Index: net/spdy/spdy_framer.cc |
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc |
index 5481b4f0dffd9d4d7e6ea76071f98bebbc83215a..2e2d340edbc22762f7e3b220a01e1c5ca5b0f1e9 100644 |
--- a/net/spdy/spdy_framer.cc |
+++ b/net/spdy/spdy_framer.cc |
@@ -688,15 +688,16 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { |
// Before we accept a DATA frame, we need to make sure we're not in the |
// middle of processing a header block. |
- if (expect_continuation_ != 0 && control_frame_type_field != CONTINUATION) { |
- DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " |
- << "frame, but instead received frame type " |
- << current_frame_type_; |
- set_error(SPDY_UNEXPECTED_FRAME); |
- return original_len - len; |
- } else if (control_frame_type_field == CONTINUATION && |
- expect_continuation_ == 0) { |
- DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; |
+ const bool is_continuation_frame = (control_frame_type_field == |
+ SpdyConstants::SerializeFrameType(protocol_version(), CONTINUATION)); |
+ if ((expect_continuation_ != 0) != is_continuation_frame) { |
+ if (expect_continuation_ != 0) { |
+ DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " |
+ << "frame, but instead received frame type " |
+ << control_frame_type_field; |
+ } else { |
+ DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; |
+ } |
set_error(SPDY_UNEXPECTED_FRAME); |
return original_len - len; |
} |
@@ -772,31 +773,38 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { |
DCHECK_EQ(SPDY_NO_ERROR, error_code_); |
DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); |
- if (control_frame_type_field < FIRST_CONTROL_TYPE || |
- control_frame_type_field > LAST_CONTROL_TYPE) { |
- set_error(SPDY_INVALID_CONTROL_FRAME); |
- return; |
- } |
- |
- current_frame_type_ = static_cast<SpdyFrameType>(control_frame_type_field); |
+ // Early detection of deprecated frames that we ignore. |
+ if (protocol_version() < SPDY4) { |
+ if (control_frame_type_field == NOOP) { |
+ current_frame_type_ = NOOP; |
+ DVLOG(1) << "NOOP control frame found. Ignoring."; |
+ CHANGE_STATE(SPDY_AUTO_RESET); |
+ return; |
+ } |
- if (current_frame_type_ == NOOP) { |
- DVLOG(1) << "NOOP control frame found. Ignoring."; |
- CHANGE_STATE(SPDY_AUTO_RESET); |
- return; |
+ if (control_frame_type_field == CREDENTIAL) { |
+ current_frame_type_ = CREDENTIAL; |
+ DCHECK_EQ(3, protocol_version()); |
+ DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; |
+ CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
+ return; |
+ } |
} |
- if (current_frame_type_ == CREDENTIAL) { |
- DCHECK_EQ(3, protocol_version()); |
- DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; |
- CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
+ if (!SpdyConstants::IsValidFrameType(protocol_version(), |
+ control_frame_type_field)) { |
+ DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field |
+ << " (protocol version: " << protocol_version() << ")"; |
+ set_error(SPDY_INVALID_CONTROL_FRAME); |
return; |
} |
+ current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), |
+ control_frame_type_field); |
+ |
// Do some sanity checking on the control frame sizes and flags. |
switch (current_frame_type_) { |
case SYN_STREAM: |
- DCHECK_GT(4, spdy_version_); |
if (current_frame_length_ < GetSynStreamMinimumSize()) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_frame_flags_ & |
@@ -919,8 +927,7 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { |
} |
break; |
case CONTINUATION: |
- if (current_frame_length_ < GetContinuationMinimumSize() || |
- protocol_version() < 4) { |
+ if (current_frame_length_ < GetContinuationMinimumSize()) { |
set_error(SPDY_INVALID_CONTROL_FRAME); |
} else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { |
set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |