summaryrefslogtreecommitdiffstats
path: root/net/http/http_chunked_decoder_unittest.cc
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-14 02:44:45 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-14 02:44:45 +0000
commitd89222accb371e210c434b27787fc80c30fa758d (patch)
tree19c518623c133f3a70b7549017db7e3c31b929bc /net/http/http_chunked_decoder_unittest.cc
parent293c0a7b4306a4cce26eb31b21587206c2d9a497 (diff)
downloadchromium_src-d89222accb371e210c434b27787fc80c30fa758d.zip
chromium_src-d89222accb371e210c434b27787fc80c30fa758d.tar.gz
chromium_src-d89222accb371e210c434b27787fc80c30fa758d.tar.bz2
Address some issues I found in chunked decoder:
(1) stricter parsing of chunk-size (don't allow leading/trailing whitespace, redundant "+" sign, leading "0x") (2) check for negative chunk sizes, and fail early rather than hitting weird stuff (3) don't mutate the const char* returned by std::string::data() (4) fail if CRLF terminator is missing on chunk-data. (why the spec has this in first place seems unecessary, since the chunk-size already tells the story...) (5) don't allow empty CRLFs git-svn-id: svn://svn.chromium.org/chrome/trunk/src@853 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http/http_chunked_decoder_unittest.cc')
-rw-r--r--net/http/http_chunked_decoder_unittest.cc91
1 files changed, 91 insertions, 0 deletions
diff --git a/net/http/http_chunked_decoder_unittest.cc b/net/http/http_chunked_decoder_unittest.cc
index 377f1b1..36433c0 100644
--- a/net/http/http_chunked_decoder_unittest.cc
+++ b/net/http/http_chunked_decoder_unittest.cc
@@ -55,6 +55,22 @@ void RunTest(const char* inputs[], size_t num_inputs,
EXPECT_TRUE(decoder.reached_eof() == expected_eof);
}
+// Feed the inputs to the decoder, until it returns an error.
+void RunTestUntilFailure(const char* inputs[], size_t num_inputs, size_t fail_index) {
+ net::HttpChunkedDecoder decoder;
+ EXPECT_FALSE(decoder.reached_eof());
+
+ for (size_t i = 0; i < num_inputs; ++i) {
+ std::string input = inputs[i];
+ int n = decoder.FilterBuf(&input[0], static_cast<int>(input.size()));
+ if (n < 0) {
+ EXPECT_EQ(fail_index, i);
+ return;
+ }
+ }
+ FAIL(); // We should have failed on the i'th iteration of the loop.
+}
+
} // namespace
TEST(HttpChunkedDecoderTest, Basic) {
@@ -116,3 +132,78 @@ TEST(HttpChunkedDecoderTest, Trailers) {
};
RunTest(inputs, arraysize(inputs), "hello", true);
}
+
+TEST(HttpChunkedDecoderTest, TrailersUnfinished) {
+ const char* inputs[] = {
+ "5\r\nhello\r\n",
+ "0\r\n",
+ "Foo: 1\r\n"
+ };
+ RunTest(inputs, arraysize(inputs), "hello", false);
+}
+
+TEST(HttpChunkedDecoderTest, InvalidChunkSize_0X) {
+ const char* inputs[] = {
+ "0x5\r\nhello\r\n",
+ "0\r\n\r\n"
+ };
+ RunTestUntilFailure(inputs, arraysize(inputs), 0);
+}
+
+TEST(HttpChunkedDecoderTest, InvalidChunkSize_TrailingWhitespace) {
+ const char* inputs[] = {
+ "5 \r\nhello\r\n",
+ "0\r\n\r\n"
+ };
+ RunTestUntilFailure(inputs, arraysize(inputs), 0);
+}
+
+TEST(HttpChunkedDecoderTest, InvalidChunkSize_LeadingWhitespace) {
+ const char* inputs[] = {
+ " 5\r\nhello\r\n",
+ "0\r\n\r\n"
+ };
+ RunTestUntilFailure(inputs, arraysize(inputs), 0);
+}
+
+TEST(HttpChunkedDecoderTest, InvalidLeadingSeparator) {
+ const char* inputs[] = {
+ "\r\n5\r\nhello\r\n",
+ "0\r\n\r\n"
+ };
+ RunTestUntilFailure(inputs, arraysize(inputs), 0);
+}
+
+TEST(HttpChunkedDecoderTest, InvalidChunkSize_NoSeparator) {
+ const char* inputs[] = {
+ "5\r\nhello",
+ "1\r\n \r\n",
+ "0\r\n\r\n"
+ };
+ RunTestUntilFailure(inputs, arraysize(inputs), 1);
+}
+
+TEST(HttpChunkedDecoderTest, InvalidChunkSize_Negative) {
+ const char* inputs[] = {
+ "8\r\n12345678\r\n-5\r\nhello\r\n",
+ "0\r\n\r\n"
+ };
+ RunTestUntilFailure(inputs, arraysize(inputs), 0);
+}
+
+TEST(HttpChunkedDecoderTest, InvalidChunkSize_Plus) {
+ const char* inputs[] = {
+ "+5\r\nhello\r\n",
+ "0\r\n\r\n"
+ };
+ RunTestUntilFailure(inputs, arraysize(inputs), 0);
+}
+
+TEST(HttpChunkedDecoderTest, InvalidConsecutiveCRLFs) {
+ const char* inputs[] = {
+ "5\r\nhello\r\n",
+ "\r\n\r\n\r\n\r\n",
+ "0\r\n\r\n"
+ };
+ RunTestUntilFailure(inputs, arraysize(inputs), 1);
+} \ No newline at end of file