Commit 9cb5fa1d authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

If there are extra bytes at the end of a gzip response, ignore them.

Previously, they were passed through unaltered, which was rather
unexpected. We could error out requests instead, but erroring out after
successfully decoding the response body seems likely to lead to more
compatibility issues than fix anything.

Bug: 833729
Change-Id: I7e0948aa4d3b963f27f4c954d9576b89e963fffb
Reviewed-on: https://chromium-review.googlesource.com/1015516Reviewed-by: default avatarHelen Li <xunjieli@chromium.org>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551753}
parent c380bcec
......@@ -237,15 +237,11 @@ int GzipSourceStream::FilterData(IOBuffer* output_buffer,
input_data_size -= to_read;
input_data += to_read;
if (gzip_footer_bytes_left_ == 0)
input_state_ = STATE_UNCOMPRESSED_BODY;
input_state_ = STATE_IGNORING_EXTRA_BYTES;
break;
}
case STATE_UNCOMPRESSED_BODY: {
int to_copy = std::min(input_data_size, output_buffer_size - bytes_out);
memcpy(output_buffer->data() + bytes_out, input_data, to_copy);
input_data_size -= to_copy;
input_data += to_copy;
bytes_out += to_copy;
case STATE_IGNORING_EXTRA_BYTES: {
input_data_size = 0;
break;
}
}
......
......@@ -56,8 +56,11 @@ class NET_EXPORT_PRIVATE GzipSourceStream : public FilterSourceStream {
STATE_COMPRESSED_BODY,
// Gzip footer of the input stream is being processed.
STATE_GZIP_FOOTER,
// The input stream is being passed through undecoded.
STATE_UNCOMPRESSED_BODY,
// The end of the gzipped body has been reached. If any extra bytes are
// received, just silently ignore them. Doing this, rather than failing the
// request or passing the extra bytes alone with the rest of the response
// body, matches the behavior of other browsers.
STATE_IGNORING_EXTRA_BYTES,
};
GzipSourceStream(std::unique_ptr<SourceStream> previous,
......
......@@ -220,14 +220,16 @@ TEST_P(GzipSourceStreamTest, DeflateTwoReads) {
EXPECT_EQ("DEFLATE", stream()->Description());
}
TEST_P(GzipSourceStreamTest, PassThroughAfterEOF) {
// Check that any extra bytes after the end of the gzipped data are silently
// ignored.
TEST_P(GzipSourceStreamTest, IgnoreDataAfterEof) {
Init(SourceStream::TYPE_DEFLATE);
char test_data[] = "Hello, World!";
const char kExtraData[] = "Hello, World!";
std::string encoded_data_with_trailing_data(encoded_data(),
encoded_data_len());
encoded_data_with_trailing_data.append(test_data, sizeof(test_data));
encoded_data_with_trailing_data.append(kExtraData, sizeof(kExtraData));
source()->AddReadResult(encoded_data_with_trailing_data.c_str(),
encoded_data_len() + sizeof(test_data), OK,
encoded_data_with_trailing_data.length(), OK,
GetParam().mode);
source()->AddReadResult(nullptr, 0, OK, GetParam().mode);
// Compressed and uncompressed data get returned as separate Read() results,
......@@ -235,7 +237,6 @@ TEST_P(GzipSourceStreamTest, PassThroughAfterEOF) {
std::string actual_output;
int rv = ReadStream(&actual_output);
std::string expected_output(source_data(), source_data_len());
expected_output.append(test_data, sizeof(test_data));
EXPECT_EQ(static_cast<int>(expected_output.size()), rv);
EXPECT_EQ(expected_output, actual_output);
EXPECT_EQ("DEFLATE", stream()->Description());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment