| 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 "net/http/http_chunked_decoder.h" | 5 #include "net/http/http_chunked_decoder.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | 8 |
| 11 #include "base/format_macros.h" | |
| 12 #include "base/strings/stringprintf.h" | |
| 13 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 14 #include "net/test/gtest_util.h" | 10 #include "net/test/gtest_util.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 11 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 13 |
| 18 using net::test::IsError; | 14 using net::test::IsError; |
| 19 using net::test::IsOk; | 15 using net::test::IsOk; |
| 20 | 16 |
| 21 namespace net { | 17 namespace net { |
| 22 | 18 |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 | 284 |
| 289 TEST(HttpChunkedDecoderTest, InvalidConsecutiveCRLFs) { | 285 TEST(HttpChunkedDecoderTest, InvalidConsecutiveCRLFs) { |
| 290 const char* const inputs[] = { | 286 const char* const inputs[] = { |
| 291 "5\r\nhello\r\n", | 287 "5\r\nhello\r\n", |
| 292 "\r\n\r\n\r\n\r\n", | 288 "\r\n\r\n\r\n\r\n", |
| 293 "0\r\n\r\n" | 289 "0\r\n\r\n" |
| 294 }; | 290 }; |
| 295 RunTestUntilFailure(inputs, arraysize(inputs), 1); | 291 RunTestUntilFailure(inputs, arraysize(inputs), 1); |
| 296 } | 292 } |
| 297 | 293 |
| 298 TEST(HttpChunkedDecoderTest, ReallyBigChunks) { | 294 TEST(HttpChunkedDecoderTest, ExcessiveChunkLen) { |
| 299 // Number of bytes sent through the chunked decoder per loop iteration. To | 295 const char* const inputs[] = { |
| 300 // minimize runtime, should be the square root of the chunk lengths, below. | 296 "c0000000\r\nhello\r\n" |
| 301 const int64_t kWrittenBytesPerIteration = 0x10000; | |
| 302 | |
| 303 // Length of chunks to test. Must be multiples of kWrittenBytesPerIteration. | |
| 304 int64_t kChunkLengths[] = { | |
| 305 // Overflows when cast to a signed int32. | |
| 306 0x0c0000000, | |
| 307 // Overflows when cast to an unsigned int32. | |
| 308 0x100000000, | |
| 309 }; | 297 }; |
| 310 | |
| 311 for (int64_t chunk_length : kChunkLengths) { | |
| 312 HttpChunkedDecoder decoder; | |
| 313 EXPECT_FALSE(decoder.reached_eof()); | |
| 314 | |
| 315 // Feed just the header to the decode. | |
| 316 std::string chunk_header = | |
| 317 base::StringPrintf("%" PRIx64 "\r\n", chunk_length); | |
| 318 std::vector<char> data(chunk_header.begin(), chunk_header.end()); | |
| 319 EXPECT_EQ(OK, decoder.FilterBuf(data.data(), data.size())); | |
| 320 EXPECT_FALSE(decoder.reached_eof()); | |
| 321 | |
| 322 // Set |data| to be kWrittenBytesPerIteration long, and have a repeating | |
| 323 // pattern. | |
| 324 data.clear(); | |
| 325 data.reserve(kWrittenBytesPerIteration); | |
| 326 for (size_t i = 0; i < kWrittenBytesPerIteration; i++) { | |
| 327 data.push_back(static_cast<char>(i)); | |
| 328 } | |
| 329 | |
| 330 // Repeatedly feed the data to the chunked decoder. Since the data doesn't | |
| 331 // include any chunk lengths, the decode will never have to move the data, | |
| 332 // and should run fairly quickly. | |
| 333 for (int64_t total_written = 0; total_written < chunk_length; | |
| 334 total_written += kWrittenBytesPerIteration) { | |
| 335 EXPECT_EQ(kWrittenBytesPerIteration, | |
| 336 decoder.FilterBuf(data.data(), kWrittenBytesPerIteration)); | |
| 337 EXPECT_FALSE(decoder.reached_eof()); | |
| 338 } | |
| 339 | |
| 340 // Chunk terminator and the final chunk. | |
| 341 char final_chunk[] = "\r\n0\r\n\r\n"; | |
| 342 EXPECT_EQ(OK, decoder.FilterBuf(final_chunk, arraysize(final_chunk))); | |
| 343 EXPECT_TRUE(decoder.reached_eof()); | |
| 344 | |
| 345 // Since |data| never included any chunk headers, it should not have been | |
| 346 // modified. | |
| 347 for (size_t i = 0; i < kWrittenBytesPerIteration; i++) { | |
| 348 EXPECT_EQ(static_cast<char>(i), data[i]); | |
| 349 } | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 TEST(HttpChunkedDecoderTest, ExcessiveChunkLen) { | |
| 354 // Smallest number that can't be represented as a signed int64. | |
| 355 const char* const inputs[] = {"8000000000000000\r\nhello\r\n"}; | |
| 356 RunTestUntilFailure(inputs, arraysize(inputs), 0); | 298 RunTestUntilFailure(inputs, arraysize(inputs), 0); |
| 357 } | 299 } |
| 358 | 300 |
| 359 TEST(HttpChunkedDecoderTest, ExcessiveChunkLen2) { | |
| 360 // Smallest number that can't be represented as an unsigned int64. | |
| 361 const char* const inputs[] = {"10000000000000000\r\nhello\r\n"}; | |
| 362 RunTestUntilFailure(inputs, arraysize(inputs), 0); | |
| 363 } | |
| 364 | |
| 365 TEST(HttpChunkedDecoderTest, BasicExtraData) { | 301 TEST(HttpChunkedDecoderTest, BasicExtraData) { |
| 366 const char* const inputs[] = { | 302 const char* const inputs[] = { |
| 367 "5\r\nhello\r\n0\r\n\r\nextra bytes" | 303 "5\r\nhello\r\n0\r\n\r\nextra bytes" |
| 368 }; | 304 }; |
| 369 RunTest(inputs, arraysize(inputs), "hello", true, 11); | 305 RunTest(inputs, arraysize(inputs), "hello", true, 11); |
| 370 } | 306 } |
| 371 | 307 |
| 372 TEST(HttpChunkedDecoderTest, IncrementalExtraData) { | 308 TEST(HttpChunkedDecoderTest, IncrementalExtraData) { |
| 373 const char* const inputs[] = { | 309 const char* const inputs[] = { |
| 374 "5", | 310 "5", |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 const char* const inputs[] = { | 353 const char* const inputs[] = { |
| 418 "5;", | 354 "5;", |
| 419 big_chunk.get() | 355 big_chunk.get() |
| 420 }; | 356 }; |
| 421 RunTestUntilFailure(inputs, arraysize(inputs), 1); | 357 RunTestUntilFailure(inputs, arraysize(inputs), 1); |
| 422 } | 358 } |
| 423 | 359 |
| 424 } // namespace | 360 } // namespace |
| 425 | 361 |
| 426 } // namespace net | 362 } // namespace net |
| OLD | NEW |