Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: net/http/http_chunked_decoder_unittest.cc

Issue 11191003: Fix a crash when a line with an HTTP chunk length is too long (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix signed / unsigned comparison Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_chunked_decoder.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
6
5 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
6 #include "net/base/net_errors.h" 9 #include "net/base/net_errors.h"
7 #include "net/http/http_chunked_decoder.h"
8 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
9 11
12 namespace net {
13
10 namespace { 14 namespace {
11 15
12 typedef testing::Test HttpChunkedDecoderTest; 16 typedef testing::Test HttpChunkedDecoderTest;
13 17
14 void RunTest(const char* inputs[], size_t num_inputs, 18 void RunTest(const char* inputs[], size_t num_inputs,
15 const char* expected_output, 19 const char* expected_output,
16 bool expected_eof, 20 bool expected_eof,
17 int bytes_after_eof) { 21 int bytes_after_eof) {
18 net::HttpChunkedDecoder decoder; 22 HttpChunkedDecoder decoder;
19 EXPECT_FALSE(decoder.reached_eof()); 23 EXPECT_FALSE(decoder.reached_eof());
20 24
21 std::string result; 25 std::string result;
22 26
23 for (size_t i = 0; i < num_inputs; ++i) { 27 for (size_t i = 0; i < num_inputs; ++i) {
24 std::string input = inputs[i]; 28 std::string input = inputs[i];
25 int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size())); 29 int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size()));
26 EXPECT_GE(n, 0); 30 EXPECT_GE(n, 0);
27 if (n > 0) 31 if (n > 0)
28 result.append(input.data(), n); 32 result.append(input.data(), n);
29 } 33 }
30 34
31 EXPECT_EQ(expected_output, result); 35 EXPECT_EQ(expected_output, result);
32 EXPECT_EQ(expected_eof, decoder.reached_eof()); 36 EXPECT_EQ(expected_eof, decoder.reached_eof());
33 EXPECT_EQ(bytes_after_eof, decoder.bytes_after_eof()); 37 EXPECT_EQ(bytes_after_eof, decoder.bytes_after_eof());
34 } 38 }
35 39
36 // Feed the inputs to the decoder, until it returns an error. 40 // Feed the inputs to the decoder, until it returns an error.
37 void RunTestUntilFailure(const char* inputs[], 41 void RunTestUntilFailure(const char* inputs[],
38 size_t num_inputs, 42 size_t num_inputs,
39 size_t fail_index) { 43 size_t fail_index) {
40 net::HttpChunkedDecoder decoder; 44 HttpChunkedDecoder decoder;
41 EXPECT_FALSE(decoder.reached_eof()); 45 EXPECT_FALSE(decoder.reached_eof());
42 46
43 for (size_t i = 0; i < num_inputs; ++i) { 47 for (size_t i = 0; i < num_inputs; ++i) {
44 std::string input = inputs[i]; 48 std::string input = inputs[i];
45 int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size())); 49 int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size()));
46 if (n < 0) { 50 if (n < 0) {
47 EXPECT_EQ(net::ERR_INVALID_CHUNKED_ENCODING, n); 51 EXPECT_EQ(ERR_INVALID_CHUNKED_ENCODING, n);
48 EXPECT_EQ(fail_index, i); 52 EXPECT_EQ(fail_index, i);
49 return; 53 return;
50 } 54 }
51 } 55 }
52 FAIL(); // We should have failed on the i'th iteration of the loop. 56 FAIL(); // We should have failed on the |fail_index| iteration of the loop.
53 } 57 }
54 58
55 } // namespace
56
57 TEST(HttpChunkedDecoderTest, Basic) { 59 TEST(HttpChunkedDecoderTest, Basic) {
58 const char* inputs[] = { 60 const char* inputs[] = {
59 "5\r\nhello\r\n0\r\n\r\n" 61 "B\r\nhello hello\r\n0\r\n\r\n"
mmenke 2012/10/16 16:19:34 We didn't have any test in this file validating th
60 }; 62 };
61 RunTest(inputs, arraysize(inputs), "hello", true, 0); 63 RunTest(inputs, arraysize(inputs), "hello hello", true, 0);
62 } 64 }
63 65
64 TEST(HttpChunkedDecoderTest, OneChunk) { 66 TEST(HttpChunkedDecoderTest, OneChunk) {
65 const char* inputs[] = { 67 const char* inputs[] = {
66 "5\r\nhello\r\n" 68 "5\r\nhello\r\n"
67 }; 69 };
68 RunTest(inputs, arraysize(inputs), "hello", false, 0); 70 RunTest(inputs, arraysize(inputs), "hello", false, 0);
69 } 71 }
70 72
71 TEST(HttpChunkedDecoderTest, Typical) { 73 TEST(HttpChunkedDecoderTest, Typical) {
(...skipping 16 matching lines...) Expand all
88 "\n", 90 "\n",
89 "0", 91 "0",
90 "\r", 92 "\r",
91 "\n", 93 "\n",
92 "\r", 94 "\r",
93 "\n" 95 "\n"
94 }; 96 };
95 RunTest(inputs, arraysize(inputs), "hello", true, 0); 97 RunTest(inputs, arraysize(inputs), "hello", true, 0);
96 } 98 }
97 99
100 // Same as above, but group carriage returns with previous input.
101 TEST(HttpChunkedDecoderTest, Incremental2) {
102 const char* inputs[] = {
103 "5\r",
104 "\n",
105 "hello\r",
106 "\n",
107 "0\r",
108 "\n\r",
109 "\n"
110 };
111 RunTest(inputs, arraysize(inputs), "hello", true, 0);
112 }
113
98 TEST(HttpChunkedDecoderTest, LF_InsteadOf_CRLF) { 114 TEST(HttpChunkedDecoderTest, LF_InsteadOf_CRLF) {
99 // Compatibility: [RFC 2616 - Invalid] 115 // Compatibility: [RFC 2616 - Invalid]
100 // {Firefox3} - Valid 116 // {Firefox3} - Valid
101 // {IE7, Safari3.1, Opera9.51} - Invalid 117 // {IE7, Safari3.1, Opera9.51} - Invalid
102 const char* inputs[] = { 118 const char* inputs[] = {
103 "5\nhello\n", 119 "5\nhello\n",
104 "1\n \n", 120 "1\n \n",
105 "5\nworld\n", 121 "5\nworld\n",
106 "0\n\n" 122 "0\n\n"
107 }; 123 };
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 RunTest(inputs, arraysize(inputs), "hello", true, 11); 316 RunTest(inputs, arraysize(inputs), "hello", true, 11);
301 } 317 }
302 318
303 TEST(HttpChunkedDecoderTest, MultipleExtraDataBlocks) { 319 TEST(HttpChunkedDecoderTest, MultipleExtraDataBlocks) {
304 const char* inputs[] = { 320 const char* inputs[] = {
305 "5\r\nhello\r\n0\r\n\r\nextra", 321 "5\r\nhello\r\n0\r\n\r\nextra",
306 " bytes" 322 " bytes"
307 }; 323 };
308 RunTest(inputs, arraysize(inputs), "hello", true, 11); 324 RunTest(inputs, arraysize(inputs), "hello", true, 11);
309 } 325 }
326
327 // Test when the line with the chunk length is too long.
328 TEST(HttpChunkedDecoderTest, LongChunkLengthLine) {
329 int big_chunk_length = HttpChunkedDecoder::kMaxLineBufLen;
330 scoped_array<char> big_chunk(new char[big_chunk_length + 1]);
331 memset(big_chunk.get(), '0', big_chunk_length);
332 big_chunk[big_chunk_length] = 0;
333 const char* inputs[] = {
334 big_chunk.get(),
335 "5"
336 };
337 RunTestUntilFailure(inputs, arraysize(inputs), 1);
338 }
339
340 // Test when the extension portion of the line with the chunk length is too
341 // long.
342 TEST(HttpChunkedDecoderTest, LongLengthLengthLine) {
343 int big_chunk_length = HttpChunkedDecoder::kMaxLineBufLen;
344 scoped_array<char> big_chunk(new char[big_chunk_length + 1]);
345 memset(big_chunk.get(), '0', big_chunk_length);
346 big_chunk[big_chunk_length] = 0;
347 const char* inputs[] = {
348 "5;",
349 big_chunk.get()
350 };
351 RunTestUntilFailure(inputs, arraysize(inputs), 1);
352 }
353
354 } // namespace
355
356 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_chunked_decoder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698