| 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_basic_stream.h" | 5 #include "net/websockets/websocket_basic_stream.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 const uint64_t kMaximumTotalSize = std::numeric_limits<int>::max(); | 50 const uint64_t kMaximumTotalSize = std::numeric_limits<int>::max(); |
| 51 | 51 |
| 52 uint64_t total_size = 0; | 52 uint64_t total_size = 0; |
| 53 for (const auto& frame : *frames) { | 53 for (const auto& frame : *frames) { |
| 54 // Force the masked bit on. | 54 // Force the masked bit on. |
| 55 frame->header.masked = true; | 55 frame->header.masked = true; |
| 56 // We enforce flow control so the renderer should never be able to force us | 56 // We enforce flow control so the renderer should never be able to force us |
| 57 // to cache anywhere near 2GB of frames. | 57 // to cache anywhere near 2GB of frames. |
| 58 uint64_t frame_size = frame->header.payload_length + | 58 uint64_t frame_size = frame->header.payload_length + |
| 59 GetWebSocketFrameHeaderSize(frame->header); | 59 GetWebSocketFrameHeaderSize(frame->header); |
| 60 CHECK_LE(frame_size, kMaximumTotalSize - total_size) | 60 // Aborting to prevent overflow |
| 61 << "Aborting to prevent overflow"; | 61 CHECK_LE(frame_size, kMaximumTotalSize - total_size); |
| 62 total_size += frame_size; | 62 total_size += frame_size; |
| 63 } | 63 } |
| 64 return static_cast<int>(total_size); | 64 return static_cast<int>(total_size); |
| 65 } | 65 } |
| 66 | 66 |
| 67 } // namespace | 67 } // namespace |
| 68 | 68 |
| 69 WebSocketBasicStream::WebSocketBasicStream( | 69 WebSocketBasicStream::WebSocketBasicStream( |
| 70 std::unique_ptr<ClientSocketHandle> connection, | 70 std::unique_ptr<ClientSocketHandle> connection, |
| 71 const scoped_refptr<GrowableIOBuffer>& http_read_buffer, | 71 const scoped_refptr<GrowableIOBuffer>& http_read_buffer, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 | 146 |
| 147 char* dest = combined_buffer->data(); | 147 char* dest = combined_buffer->data(); |
| 148 int remaining_size = total_size; | 148 int remaining_size = total_size; |
| 149 for (const auto& frame : *frames) { | 149 for (const auto& frame : *frames) { |
| 150 WebSocketMaskingKey mask = generate_websocket_masking_key_(); | 150 WebSocketMaskingKey mask = generate_websocket_masking_key_(); |
| 151 int result = | 151 int result = |
| 152 WriteWebSocketFrameHeader(frame->header, &mask, dest, remaining_size); | 152 WriteWebSocketFrameHeader(frame->header, &mask, dest, remaining_size); |
| 153 DCHECK_NE(ERR_INVALID_ARGUMENT, result) | 153 DCHECK_NE(ERR_INVALID_ARGUMENT, result) |
| 154 << "WriteWebSocketFrameHeader() says that " << remaining_size | 154 << "WriteWebSocketFrameHeader() says that " << remaining_size |
| 155 << " is not enough to write the header in. This should not happen."; | 155 << " is not enough to write the header in. This should not happen."; |
| 156 CHECK_GE(result, 0) << "Potentially security-critical check failed"; | 156 // Potentially security-critical check failed |
| 157 CHECK_GE(result, 0); |
| 157 dest += result; | 158 dest += result; |
| 158 remaining_size -= result; | 159 remaining_size -= result; |
| 159 | 160 |
| 160 CHECK_LE(frame->header.payload_length, | 161 CHECK_LE(frame->header.payload_length, |
| 161 static_cast<uint64_t>(remaining_size)); | 162 static_cast<uint64_t>(remaining_size)); |
| 162 const int frame_size = static_cast<int>(frame->header.payload_length); | 163 const int frame_size = static_cast<int>(frame->header.payload_length); |
| 163 if (frame_size > 0) { | 164 if (frame_size > 0) { |
| 164 const char* const frame_data = frame->data->data(); | 165 const char* const frame_data = frame->data->data(); |
| 165 std::copy(frame_data, frame_data + frame_size, dest); | 166 std::copy(frame_data, frame_data + frame_size, dest); |
| 166 MaskWebSocketFramePayload(mask, 0, dest, frame_size); | 167 MaskWebSocketFramePayload(mask, 0, dest, frame_size); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 current_frame_header_.reset(); | 393 current_frame_header_.reset(); |
| 393 return result_frame; | 394 return result_frame; |
| 394 } | 395 } |
| 395 | 396 |
| 396 void WebSocketBasicStream::AddToIncompleteControlFrameBody( | 397 void WebSocketBasicStream::AddToIncompleteControlFrameBody( |
| 397 const scoped_refptr<IOBufferWithSize>& data_buffer) { | 398 const scoped_refptr<IOBufferWithSize>& data_buffer) { |
| 398 if (!data_buffer.get()) | 399 if (!data_buffer.get()) |
| 399 return; | 400 return; |
| 400 const int new_offset = | 401 const int new_offset = |
| 401 incomplete_control_frame_body_->offset() + data_buffer->size(); | 402 incomplete_control_frame_body_->offset() + data_buffer->size(); |
| 402 CHECK_GE(incomplete_control_frame_body_->capacity(), new_offset) | 403 // Control frame body larger than frame header indicates; frame parser bug? |
| 403 << "Control frame body larger than frame header indicates; frame parser " | 404 CHECK_GE(incomplete_control_frame_body_->capacity(), new_offset); |
| 404 "bug?"; | |
| 405 memcpy(incomplete_control_frame_body_->data(), | 405 memcpy(incomplete_control_frame_body_->data(), |
| 406 data_buffer->data(), | 406 data_buffer->data(), |
| 407 data_buffer->size()); | 407 data_buffer->size()); |
| 408 incomplete_control_frame_body_->set_offset(new_offset); | 408 incomplete_control_frame_body_->set_offset(new_offset); |
| 409 } | 409 } |
| 410 | 410 |
| 411 void WebSocketBasicStream::OnReadComplete( | 411 void WebSocketBasicStream::OnReadComplete( |
| 412 std::vector<std::unique_ptr<WebSocketFrame>>* frames, | 412 std::vector<std::unique_ptr<WebSocketFrame>>* frames, |
| 413 const CompletionCallback& callback, | 413 const CompletionCallback& callback, |
| 414 int result) { | 414 int result) { |
| 415 result = HandleReadResult(result, frames); | 415 result = HandleReadResult(result, frames); |
| 416 if (result == ERR_IO_PENDING) | 416 if (result == ERR_IO_PENDING) |
| 417 result = ReadFrames(frames, callback); | 417 result = ReadFrames(frames, callback); |
| 418 if (result != ERR_IO_PENDING) | 418 if (result != ERR_IO_PENDING) |
| 419 callback.Run(result); | 419 callback.Run(result); |
| 420 } | 420 } |
| 421 | 421 |
| 422 } // namespace net | 422 } // namespace net |
| OLD | NEW |