OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/websockets/websocket_inflater.h" | 5 #include "net/websockets/websocket_inflater.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <deque> | 8 #include <deque> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 29 matching lines...) Expand all Loading... |
40 size_t output_buffer_capacity) | 40 size_t output_buffer_capacity) |
41 : input_queue_(input_queue_capacity), | 41 : input_queue_(input_queue_capacity), |
42 output_buffer_(output_buffer_capacity) { | 42 output_buffer_(output_buffer_capacity) { |
43 DCHECK_GT(input_queue_capacity, 0u); | 43 DCHECK_GT(input_queue_capacity, 0u); |
44 DCHECK_GT(output_buffer_capacity, 0u); | 44 DCHECK_GT(output_buffer_capacity, 0u); |
45 } | 45 } |
46 | 46 |
47 bool WebSocketInflater::Initialize(int window_bits) { | 47 bool WebSocketInflater::Initialize(int window_bits) { |
48 DCHECK_LE(8, window_bits); | 48 DCHECK_LE(8, window_bits); |
49 DCHECK_GE(15, window_bits); | 49 DCHECK_GE(15, window_bits); |
| 50 |
| 51 // Use a negative value to decompress a raw deflate stream. Upgrade |
| 52 // window_bits = 8 (a 256-byte window) to 9 (a 512-byte window) because zlib |
| 53 // is unable to compress using a 256-byte window. Historically, zlib has |
| 54 // silently increased the window size during compression in this case. This |
| 55 // must also be done during decompression to avoid inadvertently attempting |
| 56 // decompression with a window smaller than what zlib actually would have used |
| 57 // during compression. See https://crbug.com/691074. |
| 58 window_bits = -std::max(window_bits, 9); |
| 59 |
50 stream_.reset(new z_stream); | 60 stream_.reset(new z_stream); |
51 memset(stream_.get(), 0, sizeof(*stream_)); | 61 memset(stream_.get(), 0, sizeof(*stream_)); |
52 int result = inflateInit2(stream_.get(), -window_bits); | 62 int result = inflateInit2(stream_.get(), window_bits); |
53 if (result != Z_OK) { | 63 if (result != Z_OK) { |
54 inflateEnd(stream_.get()); | 64 inflateEnd(stream_.get()); |
55 stream_.reset(); | 65 stream_.reset(); |
56 return false; | 66 return false; |
57 } | 67 } |
58 return true; | 68 return true; |
59 } | 69 } |
60 | 70 |
61 WebSocketInflater::~WebSocketInflater() { | 71 WebSocketInflater::~WebSocketInflater() { |
62 if (stream_) { | 72 if (stream_) { |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 size_t num_bytes_to_copy = std::min(size, capacity_ - tail_of_last_buffer_); | 284 size_t num_bytes_to_copy = std::min(size, capacity_ - tail_of_last_buffer_); |
275 if (!num_bytes_to_copy) | 285 if (!num_bytes_to_copy) |
276 return 0; | 286 return 0; |
277 IOBufferWithSize* buffer = buffers_.back().get(); | 287 IOBufferWithSize* buffer = buffers_.back().get(); |
278 memcpy(&buffer->data()[tail_of_last_buffer_], data, num_bytes_to_copy); | 288 memcpy(&buffer->data()[tail_of_last_buffer_], data, num_bytes_to_copy); |
279 tail_of_last_buffer_ += num_bytes_to_copy; | 289 tail_of_last_buffer_ += num_bytes_to_copy; |
280 return num_bytes_to_copy; | 290 return num_bytes_to_copy; |
281 } | 291 } |
282 | 292 |
283 } // namespace net | 293 } // namespace net |
OLD | NEW |