1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h"
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_chunked_decoder.h"
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef testing::Test HttpChunkedDecoderTest;
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest(const char* inputs[], size_t num_inputs,
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott             const char* expected_output,
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott             bool expected_eof,
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott             int bytes_after_eof) {
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpChunkedDecoder decoder;
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(decoder.reached_eof());
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string result;
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t i = 0; i < num_inputs; ++i) {
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string input = inputs[i];
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size()));
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_GE(n, 0);
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (n > 0)
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      result.append(input.data(), n);
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected_output, result);
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(expected_eof, decoder.reached_eof());
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(bytes_after_eof, decoder.bytes_after_eof());
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Feed the inputs to the decoder, until it returns an error.
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTestUntilFailure(const char* inputs[],
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         size_t num_inputs,
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         size_t fail_index) {
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  net::HttpChunkedDecoder decoder;
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(decoder.reached_eof());
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t i = 0; i < num_inputs; ++i) {
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string input = inputs[i];
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size()));
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (n < 0) {
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      EXPECT_EQ(net::ERR_INVALID_CHUNKED_ENCODING, n);
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      EXPECT_EQ(fail_index, i);
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return;
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  FAIL(); // We should have failed on the i'th iteration of the loop.
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, Basic) {
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello\r\n0\r\n\r\n"
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", true, 0);
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, OneChunk) {
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello\r\n"
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", false, 0);
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, Typical) {
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello\r\n",
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "1\r\n \r\n",
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nworld\r\n",
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello world", true, 0);
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, Incremental) {
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5",
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r",
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\n",
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "hello",
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r",
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\n",
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0",
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r",
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\n",
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r",
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\n"
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", true, 0);
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, LF_InsteadOf_CRLF) {
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Compatibility: [RFC 2616 - Invalid]
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // {Firefox3} - Valid
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // {IE7, Safari3.1, Opera9.51} - Invalid
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\nhello\n",
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "1\n \n",
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\nworld\n",
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\n\n"
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello world", true, 0);
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, Extensions) {
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5;x=0\r\nhello\r\n",
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0;y=\"2 \"\r\n\r\n"
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", true, 0);
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, Trailers) {
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello\r\n",
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n",
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Foo: 1\r\n",
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Bar: 2\r\n",
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r\n"
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", true, 0);
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, TrailersUnfinished) {
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello\r\n",
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n",
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "Foo: 1\r\n"
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", false, 0);
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_TooBig) {
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // This chunked body is not terminated.
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // However we will fail decoding because the chunk-size
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // number is larger than we can handle.
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "48469410265455838241\r\nhello\r\n",
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_0X) {
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Compatibility [RFC 2616 - Invalid]:
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {Safari3.1, IE7} - Invalid
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {Firefox3, Opera 9.51} - Valid
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0x5\r\nhello\r\n",
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, ChunkSize_TrailingSpace) {
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Compatibility [RFC 2616 - Invalid]:
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {IE7, Safari3.1, Firefox3, Opera 9.51} - Valid
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    //
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // At least yahoo.com depends on this being valid.
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5      \r\nhello\r\n",
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", true, 0);
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingTab) {
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Compatibility [RFC 2616 - Invalid]:
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {IE7, Safari3.1, Firefox3, Opera 9.51} - Valid
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\t\r\nhello\r\n",
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingFormFeed) {
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Compatibility [RFC 2616- Invalid]:
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {Safari3.1} - Invalid
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {IE7, Firefox3, Opera 9.51} - Valid
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\f\r\nhello\r\n",
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingVerticalTab) {
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Compatibility [RFC 2616 - Invalid]:
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {Safari 3.1} - Invalid
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {IE7, Firefox3, Opera 9.51} - Valid
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\v\r\nhello\r\n",
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingNonHexDigit) {
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Compatibility [RFC 2616 - Invalid]:
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {Safari 3.1} - Invalid
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {IE7, Firefox3, Opera 9.51} - Valid
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5H\r\nhello\r\n",
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_LeadingSpace) {
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Compatibility [RFC 2616 - Invalid]:
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {IE7} - Invalid
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {Safari 3.1, Firefox3, Opera 9.51} - Valid
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    " 5\r\nhello\r\n",
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidLeadingSeparator) {
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r\n5\r\nhello\r\n",
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_NoSeparator) {
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello",
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "1\r\n \r\n",
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 1);
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_Negative) {
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "8\r\n12345678\r\n-5\r\nhello\r\n",
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidChunkSize_Plus) {
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Compatibility [RFC 2616 - Invalid]:
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {IE7, Safari 3.1} - Invalid
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // {Firefox3, Opera 9.51} - Valid
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "+5\r\nhello\r\n",
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, InvalidConsecutiveCRLFs) {
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello\r\n",
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r\n\r\n\r\n\r\n",
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0\r\n\r\n"
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 1);
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, ExcessiveChunkLen) {
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "c0000000\r\nhello\r\n"
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTestUntilFailure(inputs, arraysize(inputs), 0);
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, BasicExtraData) {
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello\r\n0\r\n\r\nextra bytes"
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", true, 11);
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, IncrementalExtraData) {
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5",
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r",
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\n",
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "hello",
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r",
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\n",
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "0",
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r",
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\n",
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\r",
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "\nextra bytes"
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", true, 11);
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(HttpChunkedDecoderTest, MultipleExtraDataBlocks) {
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* inputs[] = {
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "5\r\nhello\r\n0\r\n\r\nextra",
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    " bytes"
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest(inputs, arraysize(inputs), "hello", true, 11);
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
310