Chromium Code Reviews| Index: net/spdy/spdy_framer.cc |
| diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc |
| index 0b95e63000e041b1b4e572123e2bb413890896b6..ab9ccc4328ada47abd21680dcffbba44bf4465d9 100644 |
| --- a/net/spdy/spdy_framer.cc |
| +++ b/net/spdy/spdy_framer.cc |
| @@ -207,6 +207,8 @@ const char* SpdyFramer::ErrorCodeToString(int error_code) { |
| return "COMPRESS_FAILURE"; |
| case SPDY_INVALID_DATA_FRAME_FLAGS: |
| return "SPDY_INVALID_DATA_FRAME_FLAGS"; |
| + case SPDY_INVALID_CONTROL_FRAME_FLAGS: |
| + return "SPDY_INVALID_CONTROL_FRAME_FLAGS"; |
| } |
| return "UNKNOWN_ERROR"; |
| } |
| @@ -407,6 +409,9 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { |
| // if we're here, then we have the common header all received. |
| if (!current_frame.is_control_frame()) { |
| SpdyDataFrame data_frame(current_frame_buffer_.get(), false); |
| + if (data_frame.flags() & ~DATA_FLAG_FIN) { |
| + set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
| + } else { |
| visitor_->OnDataFrameHeader(&data_frame); |
| if (current_frame.length() > 0) { |
| @@ -419,6 +424,7 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { |
| } |
| CHANGE_STATE(SPDY_AUTO_RESET); |
| } |
| + } |
|
Ryan Hamilton
2013/02/07 17:07:45
fix indentation
akalin
2013/02/12 06:50:12
Done. Was due to p4diff.
|
| } else { |
| ProcessControlFrameHeader(); |
| } |
| @@ -459,18 +465,28 @@ void SpdyFramer::ProcessControlFrameHeader() { |
| switch (current_control_frame.type()) { |
| case SYN_STREAM: |
| if (current_control_frame.length() < |
| - SpdySynStreamControlFrame::size() - SpdyControlFrame::kHeaderSize) |
| + SpdySynStreamControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() & |
| + ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| + } |
| break; |
| case SYN_REPLY: |
| if (current_control_frame.length() < |
| - SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize) |
| + SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() & ~CONTROL_FLAG_FIN) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| + } |
| break; |
| case RST_STREAM: |
| if (current_control_frame.length() != |
| - SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize) |
| + SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize) { |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() != 0) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| + } |
| break; |
| case SETTINGS: |
| // Make sure that we have an integral number of 8-byte key/value pairs, |
| @@ -481,6 +497,9 @@ void SpdyFramer::ProcessControlFrameHeader() { |
| DLOG(WARNING) << "Invalid length for SETTINGS frame: " |
| << current_control_frame.length(); |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() & |
| + ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| } |
| break; |
| case GOAWAY: |
| @@ -490,30 +509,45 @@ void SpdyFramer::ProcessControlFrameHeader() { |
| // SpdyGoAwayControlFrame::size() returns the SPDY 3 size. |
| const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0; |
| if (current_control_frame.length() + goaway_offset != |
| - SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize) |
| + SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize) { |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() != 0) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| + } |
| break; |
| } |
| case HEADERS: |
| if (current_control_frame.length() < |
| - SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize) |
| + SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() & ~CONTROL_FLAG_FIN) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| + } |
| break; |
| case WINDOW_UPDATE: |
| if (current_control_frame.length() != |
| SpdyWindowUpdateControlFrame::size() - |
| - SpdyControlFrame::kHeaderSize) |
| + SpdyControlFrame::kHeaderSize) { |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() != 0) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| + } |
| break; |
| case PING: |
| if (current_control_frame.length() != |
| - SpdyPingControlFrame::size() - SpdyControlFrame::kHeaderSize) |
| + SpdyPingControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() != 0) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| + } |
| break; |
| case CREDENTIAL: |
| if (current_control_frame.length() < |
| - SpdyCredentialControlFrame::size() - SpdyControlFrame::kHeaderSize) |
| + SpdyCredentialControlFrame::size() - SpdyControlFrame::kHeaderSize) { |
| set_error(SPDY_INVALID_CONTROL_FRAME); |
| + } else if (current_control_frame.flags() != 0) { |
| + set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| + } |
| break; |
| default: |
| LOG(WARNING) << "Valid " << display_protocol_ |