OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <fstream> | 5 #include <fstream> |
6 #include <iostream> | 6 #include <iostream> |
7 | 7 |
8 #if defined(USE_SYSTEM_ZLIB) | 8 #if defined(USE_SYSTEM_ZLIB) |
9 // The code below uses the MOZ_Z_ forms of these functions in order that things | 9 // The code below uses the MOZ_Z_ forms of these functions in order that things |
10 // should work on Windows. In order to make this code cross platform, we map | 10 // should work on Windows. In order to make this code cross platform, we map |
11 // back to the normal functions here in the case that we are using the system | 11 // back to the normal functions here in the case that we are using the system |
12 // zlib. | 12 // zlib. |
13 #define MOZ_Z_deflate deflate | 13 #define MOZ_Z_deflate deflate |
14 #define MOZ_Z_deflateEnd deflateEnd | 14 #define MOZ_Z_deflateEnd deflateEnd |
15 #include <zlib.h> | 15 #include <zlib.h> |
16 #else | 16 #else |
17 #include "third_party/zlib/zlib.h" | 17 #include "third_party/zlib/zlib.h" |
18 #endif | 18 #endif |
19 | 19 |
20 #include "base/file_util.h" | 20 #include "base/file_util.h" |
21 #include "base/path_service.h" | 21 #include "base/path_service.h" |
22 #include "base/scoped_ptr.h" | 22 #include "base/scoped_ptr.h" |
23 #include "net/base/filter_unittest.h" | |
24 #include "net/base/gzip_filter.h" | 23 #include "net/base/gzip_filter.h" |
| 24 #include "net/base/mock_filter_context.h" |
25 #include "net/base/io_buffer.h" | 25 #include "net/base/io_buffer.h" |
26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
27 #include "testing/platform_test.h" | 27 #include "testing/platform_test.h" |
28 | 28 |
29 namespace { | 29 namespace { |
30 | 30 |
31 const int kDefaultBufferSize = 4096; | 31 const int kDefaultBufferSize = 4096; |
32 const int kSmallBufferSize = 128; | 32 const int kSmallBufferSize = 128; |
33 const int kMaxBufferSize = 1048576; // 1048576 == 2^20 == 1 MB | 33 const int kMaxBufferSize = 1048576; // 1048576 == 2^20 == 1 MB |
34 | 34 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 | 236 |
237 char* gzip_encode_buffer_; | 237 char* gzip_encode_buffer_; |
238 int gzip_encode_len_; | 238 int gzip_encode_len_; |
239 }; | 239 }; |
240 | 240 |
241 // Basic scenario: decoding deflate data with big enough buffer. | 241 // Basic scenario: decoding deflate data with big enough buffer. |
242 TEST_F(GZipUnitTest, DecodeDeflate) { | 242 TEST_F(GZipUnitTest, DecodeDeflate) { |
243 // Decode the compressed data with filter | 243 // Decode the compressed data with filter |
244 std::vector<Filter::FilterType> filter_types; | 244 std::vector<Filter::FilterType> filter_types; |
245 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); | 245 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); |
246 MockFilterContext filter_context(kDefaultBufferSize); | 246 net::MockFilterContext filter_context(kDefaultBufferSize); |
247 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 247 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
248 ASSERT_TRUE(filter.get()); | 248 ASSERT_TRUE(filter.get()); |
249 memcpy(filter->stream_buffer()->data(), deflate_encode_buffer_, | 249 memcpy(filter->stream_buffer()->data(), deflate_encode_buffer_, |
250 deflate_encode_len_); | 250 deflate_encode_len_); |
251 filter->FlushStreamBuffer(deflate_encode_len_); | 251 filter->FlushStreamBuffer(deflate_encode_len_); |
252 | 252 |
253 char deflate_decode_buffer[kDefaultBufferSize]; | 253 char deflate_decode_buffer[kDefaultBufferSize]; |
254 int deflate_decode_size = kDefaultBufferSize; | 254 int deflate_decode_size = kDefaultBufferSize; |
255 filter->ReadData(deflate_decode_buffer, &deflate_decode_size); | 255 filter->ReadData(deflate_decode_buffer, &deflate_decode_size); |
256 | 256 |
257 // Compare the decoding result with source data | 257 // Compare the decoding result with source data |
258 EXPECT_TRUE(deflate_decode_size == source_len()); | 258 EXPECT_TRUE(deflate_decode_size == source_len()); |
259 EXPECT_EQ(memcmp(source_buffer(), deflate_decode_buffer, source_len()), 0); | 259 EXPECT_EQ(memcmp(source_buffer(), deflate_decode_buffer, source_len()), 0); |
260 } | 260 } |
261 | 261 |
262 // Basic scenario: decoding gzip data with big enough buffer. | 262 // Basic scenario: decoding gzip data with big enough buffer. |
263 TEST_F(GZipUnitTest, DecodeGZip) { | 263 TEST_F(GZipUnitTest, DecodeGZip) { |
264 // Decode the compressed data with filter | 264 // Decode the compressed data with filter |
265 std::vector<Filter::FilterType> filter_types; | 265 std::vector<Filter::FilterType> filter_types; |
266 filter_types.push_back(Filter::FILTER_TYPE_GZIP); | 266 filter_types.push_back(Filter::FILTER_TYPE_GZIP); |
267 MockFilterContext filter_context(kDefaultBufferSize); | 267 net::MockFilterContext filter_context(kDefaultBufferSize); |
268 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 268 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
269 ASSERT_TRUE(filter.get()); | 269 ASSERT_TRUE(filter.get()); |
270 memcpy(filter->stream_buffer()->data(), gzip_encode_buffer_, | 270 memcpy(filter->stream_buffer()->data(), gzip_encode_buffer_, |
271 gzip_encode_len_); | 271 gzip_encode_len_); |
272 filter->FlushStreamBuffer(gzip_encode_len_); | 272 filter->FlushStreamBuffer(gzip_encode_len_); |
273 | 273 |
274 char gzip_decode_buffer[kDefaultBufferSize]; | 274 char gzip_decode_buffer[kDefaultBufferSize]; |
275 int gzip_decode_size = kDefaultBufferSize; | 275 int gzip_decode_size = kDefaultBufferSize; |
276 filter->ReadData(gzip_decode_buffer, &gzip_decode_size); | 276 filter->ReadData(gzip_decode_buffer, &gzip_decode_size); |
277 | 277 |
278 // Compare the decoding result with source data | 278 // Compare the decoding result with source data |
279 EXPECT_TRUE(gzip_decode_size == source_len()); | 279 EXPECT_TRUE(gzip_decode_size == source_len()); |
280 EXPECT_EQ(memcmp(source_buffer(), gzip_decode_buffer, source_len()), 0); | 280 EXPECT_EQ(memcmp(source_buffer(), gzip_decode_buffer, source_len()), 0); |
281 } | 281 } |
282 | 282 |
283 // Tests we can call filter repeatedly to get all the data decoded. | 283 // Tests we can call filter repeatedly to get all the data decoded. |
284 // To do that, we create a filter with a small buffer that can not hold all | 284 // To do that, we create a filter with a small buffer that can not hold all |
285 // the input data. | 285 // the input data. |
286 TEST_F(GZipUnitTest, DecodeWithSmallBuffer) { | 286 TEST_F(GZipUnitTest, DecodeWithSmallBuffer) { |
287 std::vector<Filter::FilterType> filter_types; | 287 std::vector<Filter::FilterType> filter_types; |
288 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); | 288 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); |
289 MockFilterContext filter_context(kSmallBufferSize); | 289 net::MockFilterContext filter_context(kSmallBufferSize); |
290 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 290 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
291 ASSERT_TRUE(filter.get()); | 291 ASSERT_TRUE(filter.get()); |
292 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(), | 292 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(), |
293 deflate_encode_buffer_, deflate_encode_len_, | 293 deflate_encode_buffer_, deflate_encode_len_, |
294 kDefaultBufferSize); | 294 kDefaultBufferSize); |
295 } | 295 } |
296 | 296 |
297 // Tests we can still decode with just 1 byte buffer in the filter. | 297 // Tests we can still decode with just 1 byte buffer in the filter. |
298 // The purpose of this tests are two: (1) Verify filter can parse partial GZip | 298 // The purpose of this tests are two: (1) Verify filter can parse partial GZip |
299 // header correctly. (2) Sometimes the filter will consume input without | 299 // header correctly. (2) Sometimes the filter will consume input without |
300 // generating output. Verify filter can handle it correctly. | 300 // generating output. Verify filter can handle it correctly. |
301 TEST_F(GZipUnitTest, DecodeWithOneByteBuffer) { | 301 TEST_F(GZipUnitTest, DecodeWithOneByteBuffer) { |
302 std::vector<Filter::FilterType> filter_types; | 302 std::vector<Filter::FilterType> filter_types; |
303 filter_types.push_back(Filter::FILTER_TYPE_GZIP); | 303 filter_types.push_back(Filter::FILTER_TYPE_GZIP); |
304 MockFilterContext filter_context(1); | 304 net::MockFilterContext filter_context(1); |
305 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 305 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
306 ASSERT_TRUE(filter.get()); | 306 ASSERT_TRUE(filter.get()); |
307 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(), | 307 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(), |
308 gzip_encode_buffer_, gzip_encode_len_, | 308 gzip_encode_buffer_, gzip_encode_len_, |
309 kDefaultBufferSize); | 309 kDefaultBufferSize); |
310 } | 310 } |
311 | 311 |
312 // Tests we can decode when caller has small buffer to read out from filter. | 312 // Tests we can decode when caller has small buffer to read out from filter. |
313 TEST_F(GZipUnitTest, DecodeWithSmallOutputBuffer) { | 313 TEST_F(GZipUnitTest, DecodeWithSmallOutputBuffer) { |
314 std::vector<Filter::FilterType> filter_types; | 314 std::vector<Filter::FilterType> filter_types; |
315 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); | 315 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); |
316 MockFilterContext filter_context(kDefaultBufferSize); | 316 net::MockFilterContext filter_context(kDefaultBufferSize); |
317 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 317 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
318 ASSERT_TRUE(filter.get()); | 318 ASSERT_TRUE(filter.get()); |
319 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(), | 319 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(), |
320 deflate_encode_buffer_, deflate_encode_len_, | 320 deflate_encode_buffer_, deflate_encode_len_, |
321 kSmallBufferSize); | 321 kSmallBufferSize); |
322 } | 322 } |
323 | 323 |
324 // Tests we can still decode with just 1 byte buffer in the filter and just 1 | 324 // Tests we can still decode with just 1 byte buffer in the filter and just 1 |
325 // byte buffer in the caller. | 325 // byte buffer in the caller. |
326 TEST_F(GZipUnitTest, DecodeWithOneByteInputAndOutputBuffer) { | 326 TEST_F(GZipUnitTest, DecodeWithOneByteInputAndOutputBuffer) { |
327 std::vector<Filter::FilterType> filter_types; | 327 std::vector<Filter::FilterType> filter_types; |
328 filter_types.push_back(Filter::FILTER_TYPE_GZIP); | 328 filter_types.push_back(Filter::FILTER_TYPE_GZIP); |
329 MockFilterContext filter_context(1); | 329 net::MockFilterContext filter_context(1); |
330 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 330 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
331 ASSERT_TRUE(filter.get()); | 331 ASSERT_TRUE(filter.get()); |
332 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(), | 332 DecodeAndCompareWithFilter(filter.get(), source_buffer(), source_len(), |
333 gzip_encode_buffer_, gzip_encode_len_, 1); | 333 gzip_encode_buffer_, gzip_encode_len_, 1); |
334 } | 334 } |
335 | 335 |
336 // Decoding deflate stream with corrupted data. | 336 // Decoding deflate stream with corrupted data. |
337 TEST_F(GZipUnitTest, DecodeCorruptedData) { | 337 TEST_F(GZipUnitTest, DecodeCorruptedData) { |
338 char corrupt_data[kDefaultBufferSize]; | 338 char corrupt_data[kDefaultBufferSize]; |
339 int corrupt_data_len = deflate_encode_len_; | 339 int corrupt_data_len = deflate_encode_len_; |
340 memcpy(corrupt_data, deflate_encode_buffer_, deflate_encode_len_); | 340 memcpy(corrupt_data, deflate_encode_buffer_, deflate_encode_len_); |
341 | 341 |
342 int pos = corrupt_data_len / 2; | 342 int pos = corrupt_data_len / 2; |
343 corrupt_data[pos] = !corrupt_data[pos]; | 343 corrupt_data[pos] = !corrupt_data[pos]; |
344 | 344 |
345 // Decode the corrupted data with filter | 345 // Decode the corrupted data with filter |
346 std::vector<Filter::FilterType> filter_types; | 346 std::vector<Filter::FilterType> filter_types; |
347 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); | 347 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); |
348 MockFilterContext filter_context(kDefaultBufferSize); | 348 net::MockFilterContext filter_context(kDefaultBufferSize); |
349 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 349 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
350 ASSERT_TRUE(filter.get()); | 350 ASSERT_TRUE(filter.get()); |
351 char corrupt_decode_buffer[kDefaultBufferSize]; | 351 char corrupt_decode_buffer[kDefaultBufferSize]; |
352 int corrupt_decode_size = kDefaultBufferSize; | 352 int corrupt_decode_size = kDefaultBufferSize; |
353 | 353 |
354 int code = DecodeAllWithFilter(filter.get(), corrupt_data, corrupt_data_len, | 354 int code = DecodeAllWithFilter(filter.get(), corrupt_data, corrupt_data_len, |
355 corrupt_decode_buffer, &corrupt_decode_size); | 355 corrupt_decode_buffer, &corrupt_decode_size); |
356 | 356 |
357 // Expect failures | 357 // Expect failures |
358 EXPECT_TRUE(code == Filter::FILTER_ERROR); | 358 EXPECT_TRUE(code == Filter::FILTER_ERROR); |
359 } | 359 } |
360 | 360 |
361 // Decoding deflate stream with missing data. | 361 // Decoding deflate stream with missing data. |
362 TEST_F(GZipUnitTest, DecodeMissingData) { | 362 TEST_F(GZipUnitTest, DecodeMissingData) { |
363 char corrupt_data[kDefaultBufferSize]; | 363 char corrupt_data[kDefaultBufferSize]; |
364 int corrupt_data_len = deflate_encode_len_; | 364 int corrupt_data_len = deflate_encode_len_; |
365 memcpy(corrupt_data, deflate_encode_buffer_, deflate_encode_len_); | 365 memcpy(corrupt_data, deflate_encode_buffer_, deflate_encode_len_); |
366 | 366 |
367 int pos = corrupt_data_len / 2; | 367 int pos = corrupt_data_len / 2; |
368 int len = corrupt_data_len - pos - 1; | 368 int len = corrupt_data_len - pos - 1; |
369 memmove(&corrupt_data[pos], &corrupt_data[pos+1], len); | 369 memmove(&corrupt_data[pos], &corrupt_data[pos+1], len); |
370 --corrupt_data_len; | 370 --corrupt_data_len; |
371 | 371 |
372 // Decode the corrupted data with filter | 372 // Decode the corrupted data with filter |
373 std::vector<Filter::FilterType> filter_types; | 373 std::vector<Filter::FilterType> filter_types; |
374 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); | 374 filter_types.push_back(Filter::FILTER_TYPE_DEFLATE); |
375 MockFilterContext filter_context(kDefaultBufferSize); | 375 net::MockFilterContext filter_context(kDefaultBufferSize); |
376 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 376 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
377 ASSERT_TRUE(filter.get()); | 377 ASSERT_TRUE(filter.get()); |
378 char corrupt_decode_buffer[kDefaultBufferSize]; | 378 char corrupt_decode_buffer[kDefaultBufferSize]; |
379 int corrupt_decode_size = kDefaultBufferSize; | 379 int corrupt_decode_size = kDefaultBufferSize; |
380 | 380 |
381 int code = DecodeAllWithFilter(filter.get(), corrupt_data, corrupt_data_len, | 381 int code = DecodeAllWithFilter(filter.get(), corrupt_data, corrupt_data_len, |
382 corrupt_decode_buffer, &corrupt_decode_size); | 382 corrupt_decode_buffer, &corrupt_decode_size); |
383 | 383 |
384 // Expect failures | 384 // Expect failures |
385 EXPECT_EQ(Filter::FILTER_ERROR, code); | 385 EXPECT_EQ(Filter::FILTER_ERROR, code); |
386 } | 386 } |
387 | 387 |
388 // Decoding gzip stream with corrupted header. | 388 // Decoding gzip stream with corrupted header. |
389 TEST_F(GZipUnitTest, DecodeCorruptedHeader) { | 389 TEST_F(GZipUnitTest, DecodeCorruptedHeader) { |
390 char corrupt_data[kDefaultBufferSize]; | 390 char corrupt_data[kDefaultBufferSize]; |
391 int corrupt_data_len = gzip_encode_len_; | 391 int corrupt_data_len = gzip_encode_len_; |
392 memcpy(corrupt_data, gzip_encode_buffer_, gzip_encode_len_); | 392 memcpy(corrupt_data, gzip_encode_buffer_, gzip_encode_len_); |
393 | 393 |
394 corrupt_data[2] = !corrupt_data[2]; | 394 corrupt_data[2] = !corrupt_data[2]; |
395 | 395 |
396 // Decode the corrupted data with filter | 396 // Decode the corrupted data with filter |
397 std::vector<Filter::FilterType> filter_types; | 397 std::vector<Filter::FilterType> filter_types; |
398 filter_types.push_back(Filter::FILTER_TYPE_GZIP); | 398 filter_types.push_back(Filter::FILTER_TYPE_GZIP); |
399 MockFilterContext filter_context(kDefaultBufferSize); | 399 net::MockFilterContext filter_context(kDefaultBufferSize); |
400 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); | 400 scoped_ptr<Filter> filter(Filter::Factory(filter_types, filter_context)); |
401 ASSERT_TRUE(filter.get()); | 401 ASSERT_TRUE(filter.get()); |
402 char corrupt_decode_buffer[kDefaultBufferSize]; | 402 char corrupt_decode_buffer[kDefaultBufferSize]; |
403 int corrupt_decode_size = kDefaultBufferSize; | 403 int corrupt_decode_size = kDefaultBufferSize; |
404 | 404 |
405 int code = DecodeAllWithFilter(filter.get(), corrupt_data, corrupt_data_len, | 405 int code = DecodeAllWithFilter(filter.get(), corrupt_data, corrupt_data_len, |
406 corrupt_decode_buffer, &corrupt_decode_size); | 406 corrupt_decode_buffer, &corrupt_decode_size); |
407 | 407 |
408 // Expect failures | 408 // Expect failures |
409 EXPECT_TRUE(code == Filter::FILTER_ERROR); | 409 EXPECT_TRUE(code == Filter::FILTER_ERROR); |
410 } | 410 } |
411 | 411 |
412 } // namespace | 412 } // namespace |
OLD | NEW |