OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/base/io_buffer.h" | |
6 #include "net/filter/filter.h" | |
7 #include "net/filter/mock_filter_context.h" | |
8 #include "testing/gtest/include/gtest/gtest.h" | |
9 | |
10 namespace net { | |
11 | |
12 namespace { | |
13 | |
14 class PassThroughFilter : public Filter { | |
15 public: | |
16 PassThroughFilter() : Filter(FILTER_TYPE_UNSUPPORTED) {} | |
17 | |
18 FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override { | |
19 return CopyOut(dest_buffer, dest_len); | |
20 } | |
21 | |
22 DISALLOW_COPY_AND_ASSIGN(PassThroughFilter); | |
23 }; | |
24 | |
25 } // namespace | |
26 | |
27 TEST(FilterTest, ContentTypeId) { | |
28 // Check for basic translation of Content-Encoding, including case variations. | |
29 EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE, | |
30 Filter::ConvertEncodingToType("deflate")); | |
31 EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE, | |
32 Filter::ConvertEncodingToType("deflAte")); | |
33 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, | |
34 Filter::ConvertEncodingToType("gzip")); | |
35 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, | |
36 Filter::ConvertEncodingToType("GzIp")); | |
37 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, | |
38 Filter::ConvertEncodingToType("x-gzip")); | |
39 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, | |
40 Filter::ConvertEncodingToType("X-GzIp")); | |
41 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, | |
42 Filter::ConvertEncodingToType("sdch")); | |
43 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, | |
44 Filter::ConvertEncodingToType("sDcH")); | |
45 EXPECT_EQ(Filter::FILTER_TYPE_UNSUPPORTED, | |
46 Filter::ConvertEncodingToType("weird")); | |
47 EXPECT_EQ(Filter::FILTER_TYPE_UNSUPPORTED, | |
48 Filter::ConvertEncodingToType("strange")); | |
49 } | |
50 | |
51 // Check various fixups that modify content encoding lists. | |
52 TEST(FilterTest, ApacheGzip) { | |
53 MockFilterContext filter_context; | |
54 filter_context.SetSdchResponse(NULL); | |
55 | |
56 // Check that redundant gzip mime type removes only solo gzip encoding. | |
57 const std::string kGzipMime1("application/x-gzip"); | |
58 const std::string kGzipMime2("application/gzip"); | |
59 const std::string kGzipMime3("application/x-gunzip"); | |
60 std::vector<Filter::FilterType> encoding_types; | |
61 | |
62 // First show it removes the gzip, given any gzip style mime type. | |
63 encoding_types.clear(); | |
64 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
65 filter_context.SetMimeType(kGzipMime1); | |
66 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
67 EXPECT_TRUE(encoding_types.empty()); | |
68 | |
69 encoding_types.clear(); | |
70 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
71 filter_context.SetMimeType(kGzipMime2); | |
72 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
73 EXPECT_TRUE(encoding_types.empty()); | |
74 | |
75 encoding_types.clear(); | |
76 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
77 filter_context.SetMimeType(kGzipMime3); | |
78 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
79 EXPECT_TRUE(encoding_types.empty()); | |
80 | |
81 // Check to be sure it doesn't remove everything when it has such a type. | |
82 encoding_types.clear(); | |
83 encoding_types.push_back(Filter::FILTER_TYPE_SDCH); | |
84 filter_context.SetMimeType(kGzipMime1); | |
85 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
86 ASSERT_EQ(1U, encoding_types.size()); | |
87 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types.front()); | |
88 | |
89 // Check to be sure that gzip can survive with other mime types. | |
90 encoding_types.clear(); | |
91 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
92 filter_context.SetMimeType("other/mime"); | |
93 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
94 ASSERT_EQ(1U, encoding_types.size()); | |
95 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
96 } | |
97 | |
98 TEST(FilterTest, GzipContentDispositionFilename) { | |
99 MockFilterContext filter_context; | |
100 filter_context.SetSdchResponse(NULL); | |
101 | |
102 const std::string kGzipMime("application/x-tar"); | |
103 const std::string kContentDisposition("attachment; filename=\"foo.tgz\""); | |
104 const std::string kURL("http://foo.com/getfoo.php"); | |
105 std::vector<Filter::FilterType> encoding_types; | |
106 | |
107 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
108 filter_context.SetMimeType(kGzipMime); | |
109 filter_context.SetURL(GURL(kURL)); | |
110 filter_context.SetContentDisposition(kContentDisposition); | |
111 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
112 ASSERT_EQ(0U, encoding_types.size()); | |
113 } | |
114 | |
115 TEST(FilterTest, SdchEncoding) { | |
116 // Handle content encodings including SDCH. | |
117 const std::string kTextHtmlMime("text/html"); | |
118 MockFilterContext filter_context; | |
119 // Empty handle indicates to filter that SDCH is active. | |
120 filter_context.SetSdchResponse( | |
121 SdchManager::CreateEmptyDictionarySetForTesting().Pass()); | |
122 | |
123 std::vector<Filter::FilterType> encoding_types; | |
124 | |
125 // Check for most common encoding, and verify it survives unchanged. | |
126 encoding_types.clear(); | |
127 encoding_types.push_back(Filter::FILTER_TYPE_SDCH); | |
128 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
129 filter_context.SetMimeType(kTextHtmlMime); | |
130 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
131 ASSERT_EQ(2U, encoding_types.size()); | |
132 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]); | |
133 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]); | |
134 | |
135 // Unchanged even with other mime types. | |
136 encoding_types.clear(); | |
137 encoding_types.push_back(Filter::FILTER_TYPE_SDCH); | |
138 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
139 filter_context.SetMimeType("other/type"); | |
140 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
141 ASSERT_EQ(2U, encoding_types.size()); | |
142 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]); | |
143 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]); | |
144 | |
145 // Solo SDCH is extended to include optional gunzip. | |
146 encoding_types.clear(); | |
147 encoding_types.push_back(Filter::FILTER_TYPE_SDCH); | |
148 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
149 ASSERT_EQ(2U, encoding_types.size()); | |
150 EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]); | |
151 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]); | |
152 } | |
153 | |
154 TEST(FilterTest, MissingSdchEncoding) { | |
155 // Handle interesting case where entire SDCH encoding assertion "got lost." | |
156 const std::string kTextHtmlMime("text/html"); | |
157 MockFilterContext filter_context; | |
158 filter_context.SetSdchResponse( | |
159 SdchManager::CreateEmptyDictionarySetForTesting().Pass()); | |
160 | |
161 std::vector<Filter::FilterType> encoding_types; | |
162 | |
163 // Loss of encoding, but it was an SDCH response with html type. | |
164 encoding_types.clear(); | |
165 filter_context.SetMimeType(kTextHtmlMime); | |
166 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
167 ASSERT_EQ(2U, encoding_types.size()); | |
168 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]); | |
169 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]); | |
170 | |
171 // Loss of encoding, but it was an SDCH response with a prefix that says it | |
172 // was an html type. Note that it *should* be the case that a precise match | |
173 // with "text/html" we be collected by GetMimeType() and passed in, but we | |
174 // coded the fixup defensively (scanning for a prefix of "text/html", so this | |
175 // is an example which could survive such confusion in the caller). | |
176 encoding_types.clear(); | |
177 filter_context.SetMimeType("text/html; charset=UTF-8"); | |
178 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
179 ASSERT_EQ(2U, encoding_types.size()); | |
180 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]); | |
181 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]); | |
182 | |
183 // No encoding, but it was an SDCH response with non-html type. | |
184 encoding_types.clear(); | |
185 filter_context.SetMimeType("other/mime"); | |
186 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
187 ASSERT_EQ(2U, encoding_types.size()); | |
188 EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]); | |
189 EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]); | |
190 } | |
191 | |
192 TEST(FilterTest, Svgz) { | |
193 MockFilterContext filter_context; | |
194 | |
195 // Check that svgz files are only decompressed when not downloading. | |
196 const std::string kSvgzMime("image/svg+xml"); | |
197 const std::string kSvgzUrl("http://ignore.com/foo.svgz"); | |
198 const std::string kSvgUrl("http://ignore.com/foo.svg"); | |
199 std::vector<Filter::FilterType> encoding_types; | |
200 | |
201 // Test svgz extension | |
202 encoding_types.clear(); | |
203 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
204 filter_context.SetDownload(false); | |
205 filter_context.SetMimeType(kSvgzMime); | |
206 filter_context.SetURL(GURL(kSvgzUrl)); | |
207 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
208 ASSERT_EQ(1U, encoding_types.size()); | |
209 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
210 | |
211 encoding_types.clear(); | |
212 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
213 filter_context.SetDownload(true); | |
214 filter_context.SetMimeType(kSvgzMime); | |
215 filter_context.SetURL(GURL(kSvgzUrl)); | |
216 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
217 EXPECT_TRUE(encoding_types.empty()); | |
218 | |
219 // Test svg extension | |
220 encoding_types.clear(); | |
221 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
222 filter_context.SetDownload(false); | |
223 filter_context.SetMimeType(kSvgzMime); | |
224 filter_context.SetURL(GURL(kSvgUrl)); | |
225 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
226 ASSERT_EQ(1U, encoding_types.size()); | |
227 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
228 | |
229 encoding_types.clear(); | |
230 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
231 filter_context.SetDownload(true); | |
232 filter_context.SetMimeType(kSvgzMime); | |
233 filter_context.SetURL(GURL(kSvgUrl)); | |
234 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
235 ASSERT_EQ(1U, encoding_types.size()); | |
236 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
237 } | |
238 | |
239 TEST(FilterTest, UnsupportedMimeGzip) { | |
240 // From issue 8170 - handling files with Content-Encoding: x-gzip | |
241 MockFilterContext filter_context; | |
242 std::vector<Filter::FilterType> encoding_types; | |
243 const std::string kTarMime("application/x-tar"); | |
244 const std::string kCpioMime("application/x-cpio"); | |
245 const std::string kTarUrl("http://ignore.com/foo.tar"); | |
246 const std::string kTargzUrl("http://ignore.com/foo.tar.gz"); | |
247 const std::string kTgzUrl("http://ignore.com/foo.tgz"); | |
248 const std::string kBadTgzUrl("http://ignore.com/foo.targz"); | |
249 const std::string kUrl("http://ignore.com/foo"); | |
250 | |
251 // Firefox 3 does not decompress when we have unsupported mime types for | |
252 // certain filenames. | |
253 encoding_types.clear(); | |
254 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
255 filter_context.SetDownload(false); | |
256 filter_context.SetMimeType(kTarMime); | |
257 filter_context.SetURL(GURL(kTargzUrl)); | |
258 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
259 EXPECT_TRUE(encoding_types.empty()); | |
260 | |
261 encoding_types.clear(); | |
262 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
263 filter_context.SetDownload(false); | |
264 filter_context.SetMimeType(kTarMime); | |
265 filter_context.SetURL(GURL(kTgzUrl)); | |
266 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
267 EXPECT_TRUE(encoding_types.empty()); | |
268 | |
269 encoding_types.clear(); | |
270 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
271 filter_context.SetDownload(false); | |
272 filter_context.SetMimeType(kCpioMime); | |
273 filter_context.SetURL(GURL(kTgzUrl)); | |
274 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
275 EXPECT_TRUE(encoding_types.empty()); | |
276 | |
277 // Same behavior for downloads. | |
278 encoding_types.clear(); | |
279 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
280 filter_context.SetDownload(true); | |
281 filter_context.SetMimeType(kCpioMime); | |
282 filter_context.SetURL(GURL(kTgzUrl)); | |
283 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
284 EXPECT_TRUE(encoding_types.empty()); | |
285 | |
286 // Unsupported mime type with wrong file name, decompressed. | |
287 encoding_types.clear(); | |
288 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
289 filter_context.SetDownload(false); | |
290 filter_context.SetMimeType(kTarMime); | |
291 filter_context.SetURL(GURL(kUrl)); | |
292 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
293 ASSERT_EQ(1U, encoding_types.size()); | |
294 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
295 | |
296 encoding_types.clear(); | |
297 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
298 filter_context.SetDownload(false); | |
299 filter_context.SetMimeType(kTarMime); | |
300 filter_context.SetURL(GURL(kTarUrl)); | |
301 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
302 ASSERT_EQ(1U, encoding_types.size()); | |
303 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
304 | |
305 encoding_types.clear(); | |
306 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
307 filter_context.SetDownload(false); | |
308 filter_context.SetMimeType(kTarMime); | |
309 filter_context.SetURL(GURL(kBadTgzUrl)); | |
310 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
311 ASSERT_EQ(1U, encoding_types.size()); | |
312 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
313 | |
314 // Same behavior for downloads. | |
315 encoding_types.clear(); | |
316 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
317 filter_context.SetDownload(true); | |
318 filter_context.SetMimeType(kTarMime); | |
319 filter_context.SetURL(GURL(kBadTgzUrl)); | |
320 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
321 ASSERT_EQ(1U, encoding_types.size()); | |
322 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
323 } | |
324 | |
325 TEST(FilterTest, SupportedMimeGzip) { | |
326 // From issue 16430 - Files with supported mime types should be decompressed, | |
327 // even though these files end in .gz/.tgz. | |
328 MockFilterContext filter_context; | |
329 std::vector<Filter::FilterType> encoding_types; | |
330 const std::string kGzUrl("http://ignore.com/foo.gz"); | |
331 const std::string kUrl("http://ignore.com/foo"); | |
332 const std::string kHtmlMime("text/html"); | |
333 const std::string kJavascriptMime("text/javascript"); | |
334 | |
335 // For files that does not end in .gz/.tgz, we always decompress. | |
336 encoding_types.clear(); | |
337 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
338 filter_context.SetDownload(false); | |
339 filter_context.SetMimeType(kHtmlMime); | |
340 filter_context.SetURL(GURL(kUrl)); | |
341 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
342 ASSERT_EQ(1U, encoding_types.size()); | |
343 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
344 | |
345 encoding_types.clear(); | |
346 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
347 filter_context.SetDownload(true); | |
348 filter_context.SetMimeType(kHtmlMime); | |
349 filter_context.SetURL(GURL(kUrl)); | |
350 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
351 ASSERT_EQ(1U, encoding_types.size()); | |
352 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
353 | |
354 // And also decompress files that end in .gz/.tgz. | |
355 encoding_types.clear(); | |
356 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
357 filter_context.SetDownload(false); | |
358 filter_context.SetMimeType(kHtmlMime); | |
359 filter_context.SetURL(GURL(kGzUrl)); | |
360 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
361 ASSERT_EQ(1U, encoding_types.size()); | |
362 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
363 | |
364 encoding_types.clear(); | |
365 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
366 filter_context.SetDownload(false); | |
367 filter_context.SetMimeType(kJavascriptMime); | |
368 filter_context.SetURL(GURL(kGzUrl)); | |
369 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
370 ASSERT_EQ(1U, encoding_types.size()); | |
371 EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front()); | |
372 | |
373 // Except on downloads, where they just get saved. | |
374 encoding_types.clear(); | |
375 encoding_types.push_back(Filter::FILTER_TYPE_GZIP); | |
376 filter_context.SetDownload(true); | |
377 filter_context.SetMimeType(kHtmlMime); | |
378 filter_context.SetURL(GURL(kGzUrl)); | |
379 Filter::FixupEncodingTypes(filter_context, &encoding_types); | |
380 EXPECT_TRUE(encoding_types.empty()); | |
381 } | |
382 | |
383 // Make sure a series of three pass-through filters copies the data cleanly. | |
384 // Regression test for http://crbug.com/418975. | |
385 TEST(FilterTest, ThreeFilterChain) { | |
386 scoped_ptr<PassThroughFilter> filter1(new PassThroughFilter); | |
387 scoped_ptr<PassThroughFilter> filter2(new PassThroughFilter); | |
388 scoped_ptr<PassThroughFilter> filter3(new PassThroughFilter); | |
389 | |
390 filter1->InitBuffer(32 * 1024); | |
391 filter2->InitBuffer(32 * 1024); | |
392 filter3->InitBuffer(32 * 1024); | |
393 | |
394 filter2->next_filter_ = filter3.Pass(); | |
395 filter1->next_filter_ = filter2.Pass(); | |
396 | |
397 // Initialize the input array with a varying byte sequence. | |
398 const size_t input_array_size = 64 * 1024; | |
399 char input_array[input_array_size]; | |
400 size_t read_array_index = 0; | |
401 for (size_t i = 0; i < input_array_size; i++) { | |
402 input_array[i] = i % 113; | |
403 } | |
404 | |
405 const size_t output_array_size = 4 * 1024; | |
406 char output_array[output_array_size]; | |
407 | |
408 size_t compare_array_index = 0; | |
409 | |
410 do { | |
411 // Read data from the filter chain. | |
412 int amount_read = output_array_size; | |
413 Filter::FilterStatus status = filter1->ReadData(output_array, &amount_read); | |
414 EXPECT_NE(Filter::FILTER_ERROR, status); | |
415 EXPECT_EQ(0, memcmp(output_array, input_array + compare_array_index, | |
416 amount_read)); | |
417 compare_array_index += amount_read; | |
418 | |
419 // Detect the various indications that data transfer along the chain is | |
420 // complete. | |
421 if (Filter::FILTER_DONE == status || Filter::FILTER_ERROR == status || | |
422 (Filter::FILTER_OK == status && amount_read == 0) || | |
423 (Filter::FILTER_NEED_MORE_DATA == status && | |
424 read_array_index == input_array_size)) | |
425 break; | |
426 | |
427 if (Filter::FILTER_OK == status) | |
428 continue; | |
429 | |
430 // Write needed data into the filter chain. | |
431 ASSERT_EQ(Filter::FILTER_NEED_MORE_DATA, status); | |
432 ASSERT_NE(0, filter1->stream_buffer_size()); | |
433 size_t amount_to_copy = std::min( | |
434 static_cast<size_t>(filter1->stream_buffer_size()), | |
435 input_array_size - read_array_index); | |
436 memcpy(filter1->stream_buffer()->data(), | |
437 input_array + read_array_index, | |
438 amount_to_copy); | |
439 filter1->FlushStreamBuffer(amount_to_copy); | |
440 read_array_index += amount_to_copy; | |
441 } while (true); | |
442 | |
443 EXPECT_EQ(read_array_index, input_array_size); | |
444 EXPECT_EQ(compare_array_index, input_array_size); | |
445 } | |
446 | |
447 } // Namespace net | |
OLD | NEW |