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

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

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « net/http/http_chunked_decoder.cc ('k') | net/http/http_content_disposition.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/http/http_chunked_decoder.h"
6
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "net/base/net_errors.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace net {
13
14 namespace {
15
16 typedef testing::Test HttpChunkedDecoderTest;
17
18 void RunTest(const char* const inputs[],
19 size_t num_inputs,
20 const char* expected_output,
21 bool expected_eof,
22 int bytes_after_eof) {
23 HttpChunkedDecoder decoder;
24 EXPECT_FALSE(decoder.reached_eof());
25
26 std::string result;
27
28 for (size_t i = 0; i < num_inputs; ++i) {
29 std::string input = inputs[i];
30 int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size()));
31 EXPECT_GE(n, 0);
32 if (n > 0)
33 result.append(input.data(), n);
34 }
35
36 EXPECT_EQ(expected_output, result);
37 EXPECT_EQ(expected_eof, decoder.reached_eof());
38 EXPECT_EQ(bytes_after_eof, decoder.bytes_after_eof());
39 }
40
41 // Feed the inputs to the decoder, until it returns an error.
42 void RunTestUntilFailure(const char* const inputs[],
43 size_t num_inputs,
44 size_t fail_index) {
45 HttpChunkedDecoder decoder;
46 EXPECT_FALSE(decoder.reached_eof());
47
48 for (size_t i = 0; i < num_inputs; ++i) {
49 std::string input = inputs[i];
50 int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size()));
51 if (n < 0) {
52 EXPECT_EQ(ERR_INVALID_CHUNKED_ENCODING, n);
53 EXPECT_EQ(fail_index, i);
54 return;
55 }
56 }
57 FAIL(); // We should have failed on the |fail_index| iteration of the loop.
58 }
59
60 TEST(HttpChunkedDecoderTest, Basic) {
61 const char* const inputs[] = {
62 "B\r\nhello hello\r\n0\r\n\r\n"
63 };
64 RunTest(inputs, arraysize(inputs), "hello hello", true, 0);
65 }
66
67 TEST(HttpChunkedDecoderTest, OneChunk) {
68 const char* const inputs[] = {
69 "5\r\nhello\r\n"
70 };
71 RunTest(inputs, arraysize(inputs), "hello", false, 0);
72 }
73
74 TEST(HttpChunkedDecoderTest, Typical) {
75 const char* const inputs[] = {
76 "5\r\nhello\r\n",
77 "1\r\n \r\n",
78 "5\r\nworld\r\n",
79 "0\r\n\r\n"
80 };
81 RunTest(inputs, arraysize(inputs), "hello world", true, 0);
82 }
83
84 TEST(HttpChunkedDecoderTest, Incremental) {
85 const char* const inputs[] = {
86 "5",
87 "\r",
88 "\n",
89 "hello",
90 "\r",
91 "\n",
92 "0",
93 "\r",
94 "\n",
95 "\r",
96 "\n"
97 };
98 RunTest(inputs, arraysize(inputs), "hello", true, 0);
99 }
100
101 // Same as above, but group carriage returns with previous input.
102 TEST(HttpChunkedDecoderTest, Incremental2) {
103 const char* const inputs[] = {
104 "5\r",
105 "\n",
106 "hello\r",
107 "\n",
108 "0\r",
109 "\n\r",
110 "\n"
111 };
112 RunTest(inputs, arraysize(inputs), "hello", true, 0);
113 }
114
115 TEST(HttpChunkedDecoderTest, LF_InsteadOf_CRLF) {
116 // Compatibility: [RFC 2616 - Invalid]
117 // {Firefox3} - Valid
118 // {IE7, Safari3.1, Opera9.51} - Invalid
119 const char* const inputs[] = {
120 "5\nhello\n",
121 "1\n \n",
122 "5\nworld\n",
123 "0\n\n"
124 };
125 RunTest(inputs, arraysize(inputs), "hello world", true, 0);
126 }
127
128 TEST(HttpChunkedDecoderTest, Extensions) {
129 const char* const inputs[] = {
130 "5;x=0\r\nhello\r\n",
131 "0;y=\"2 \"\r\n\r\n"
132 };
133 RunTest(inputs, arraysize(inputs), "hello", true, 0);
134 }
135
136 TEST(HttpChunkedDecoderTest, Trailers) {
137 const char* const inputs[] = {
138 "5\r\nhello\r\n",
139 "0\r\n",
140 "Foo: 1\r\n",
141 "Bar: 2\r\n",
142 "\r\n"
143 };
144 RunTest(inputs, arraysize(inputs), "hello", true, 0);
145 }
146
147 TEST(HttpChunkedDecoderTest, TrailersUnfinished) {
148 const char* const inputs[] = {
149 "5\r\nhello\r\n",
150 "0\r\n",
151 "Foo: 1\r\n"
152 };
153 RunTest(inputs, arraysize(inputs), "hello", false, 0);
154 }
155
156 TEST(HttpChunkedDecoderTest, InvalidChunkSize_TooBig) {
157 const char* const inputs[] = {
158 // This chunked body is not terminated.
159 // However we will fail decoding because the chunk-size
160 // number is larger than we can handle.
161 "48469410265455838241\r\nhello\r\n",
162 "0\r\n\r\n"
163 };
164 RunTestUntilFailure(inputs, arraysize(inputs), 0);
165 }
166
167 TEST(HttpChunkedDecoderTest, InvalidChunkSize_0X) {
168 const char* const inputs[] = {
169 // Compatibility [RFC 2616 - Invalid]:
170 // {Safari3.1, IE7} - Invalid
171 // {Firefox3, Opera 9.51} - Valid
172 "0x5\r\nhello\r\n",
173 "0\r\n\r\n"
174 };
175 RunTestUntilFailure(inputs, arraysize(inputs), 0);
176 }
177
178 TEST(HttpChunkedDecoderTest, ChunkSize_TrailingSpace) {
179 const char* const inputs[] = {
180 // Compatibility [RFC 2616 - Invalid]:
181 // {IE7, Safari3.1, Firefox3, Opera 9.51} - Valid
182 //
183 // At least yahoo.com depends on this being valid.
184 "5 \r\nhello\r\n",
185 "0\r\n\r\n"
186 };
187 RunTest(inputs, arraysize(inputs), "hello", true, 0);
188 }
189
190 TEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingTab) {
191 const char* const inputs[] = {
192 // Compatibility [RFC 2616 - Invalid]:
193 // {IE7, Safari3.1, Firefox3, Opera 9.51} - Valid
194 "5\t\r\nhello\r\n",
195 "0\r\n\r\n"
196 };
197 RunTestUntilFailure(inputs, arraysize(inputs), 0);
198 }
199
200 TEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingFormFeed) {
201 const char* const inputs[] = {
202 // Compatibility [RFC 2616- Invalid]:
203 // {Safari3.1} - Invalid
204 // {IE7, Firefox3, Opera 9.51} - Valid
205 "5\f\r\nhello\r\n",
206 "0\r\n\r\n"
207 };
208 RunTestUntilFailure(inputs, arraysize(inputs), 0);
209 }
210
211 TEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingVerticalTab) {
212 const char* const inputs[] = {
213 // Compatibility [RFC 2616 - Invalid]:
214 // {Safari 3.1} - Invalid
215 // {IE7, Firefox3, Opera 9.51} - Valid
216 "5\v\r\nhello\r\n",
217 "0\r\n\r\n"
218 };
219 RunTestUntilFailure(inputs, arraysize(inputs), 0);
220 }
221
222 TEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingNonHexDigit) {
223 const char* const inputs[] = {
224 // Compatibility [RFC 2616 - Invalid]:
225 // {Safari 3.1} - Invalid
226 // {IE7, Firefox3, Opera 9.51} - Valid
227 "5H\r\nhello\r\n",
228 "0\r\n\r\n"
229 };
230 RunTestUntilFailure(inputs, arraysize(inputs), 0);
231 }
232
233 TEST(HttpChunkedDecoderTest, InvalidChunkSize_LeadingSpace) {
234 const char* const inputs[] = {
235 // Compatibility [RFC 2616 - Invalid]:
236 // {IE7} - Invalid
237 // {Safari 3.1, Firefox3, Opera 9.51} - Valid
238 " 5\r\nhello\r\n",
239 "0\r\n\r\n"
240 };
241 RunTestUntilFailure(inputs, arraysize(inputs), 0);
242 }
243
244 TEST(HttpChunkedDecoderTest, InvalidLeadingSeparator) {
245 const char* const inputs[] = {
246 "\r\n5\r\nhello\r\n",
247 "0\r\n\r\n"
248 };
249 RunTestUntilFailure(inputs, arraysize(inputs), 0);
250 }
251
252 TEST(HttpChunkedDecoderTest, InvalidChunkSize_NoSeparator) {
253 const char* const inputs[] = {
254 "5\r\nhello",
255 "1\r\n \r\n",
256 "0\r\n\r\n"
257 };
258 RunTestUntilFailure(inputs, arraysize(inputs), 1);
259 }
260
261 TEST(HttpChunkedDecoderTest, InvalidChunkSize_Negative) {
262 const char* const inputs[] = {
263 "8\r\n12345678\r\n-5\r\nhello\r\n",
264 "0\r\n\r\n"
265 };
266 RunTestUntilFailure(inputs, arraysize(inputs), 0);
267 }
268
269 TEST(HttpChunkedDecoderTest, InvalidChunkSize_Plus) {
270 const char* const inputs[] = {
271 // Compatibility [RFC 2616 - Invalid]:
272 // {IE7, Safari 3.1} - Invalid
273 // {Firefox3, Opera 9.51} - Valid
274 "+5\r\nhello\r\n",
275 "0\r\n\r\n"
276 };
277 RunTestUntilFailure(inputs, arraysize(inputs), 0);
278 }
279
280 TEST(HttpChunkedDecoderTest, InvalidConsecutiveCRLFs) {
281 const char* const inputs[] = {
282 "5\r\nhello\r\n",
283 "\r\n\r\n\r\n\r\n",
284 "0\r\n\r\n"
285 };
286 RunTestUntilFailure(inputs, arraysize(inputs), 1);
287 }
288
289 TEST(HttpChunkedDecoderTest, ExcessiveChunkLen) {
290 const char* const inputs[] = {
291 "c0000000\r\nhello\r\n"
292 };
293 RunTestUntilFailure(inputs, arraysize(inputs), 0);
294 }
295
296 TEST(HttpChunkedDecoderTest, BasicExtraData) {
297 const char* const inputs[] = {
298 "5\r\nhello\r\n0\r\n\r\nextra bytes"
299 };
300 RunTest(inputs, arraysize(inputs), "hello", true, 11);
301 }
302
303 TEST(HttpChunkedDecoderTest, IncrementalExtraData) {
304 const char* const inputs[] = {
305 "5",
306 "\r",
307 "\n",
308 "hello",
309 "\r",
310 "\n",
311 "0",
312 "\r",
313 "\n",
314 "\r",
315 "\nextra bytes"
316 };
317 RunTest(inputs, arraysize(inputs), "hello", true, 11);
318 }
319
320 TEST(HttpChunkedDecoderTest, MultipleExtraDataBlocks) {
321 const char* const inputs[] = {
322 "5\r\nhello\r\n0\r\n\r\nextra",
323 " bytes"
324 };
325 RunTest(inputs, arraysize(inputs), "hello", true, 11);
326 }
327
328 // Test when the line with the chunk length is too long.
329 TEST(HttpChunkedDecoderTest, LongChunkLengthLine) {
330 int big_chunk_length = HttpChunkedDecoder::kMaxLineBufLen;
331 scoped_ptr<char[]> big_chunk(new char[big_chunk_length + 1]);
332 memset(big_chunk.get(), '0', big_chunk_length);
333 big_chunk[big_chunk_length] = 0;
334 const char* const inputs[] = {
335 big_chunk.get(),
336 "5"
337 };
338 RunTestUntilFailure(inputs, arraysize(inputs), 1);
339 }
340
341 // Test when the extension portion of the line with the chunk length is too
342 // long.
343 TEST(HttpChunkedDecoderTest, LongLengthLengthLine) {
344 int big_chunk_length = HttpChunkedDecoder::kMaxLineBufLen;
345 scoped_ptr<char[]> big_chunk(new char[big_chunk_length + 1]);
346 memset(big_chunk.get(), '0', big_chunk_length);
347 big_chunk[big_chunk_length] = 0;
348 const char* const inputs[] = {
349 "5;",
350 big_chunk.get()
351 };
352 RunTestUntilFailure(inputs, arraysize(inputs), 1);
353 }
354
355 } // namespace
356
357 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_chunked_decoder.cc ('k') | net/http/http_content_disposition.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698