| Index: net/spdy/spdy_framer.cc | 
| diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc | 
| index 1b3ef6e3fed0b29c234366a906e8eb32227383c5..c828d168bab1093812664086e5807dbd9779992a 100644 | 
| --- a/net/spdy/spdy_framer.cc | 
| +++ b/net/spdy/spdy_framer.cc | 
| @@ -166,7 +166,6 @@ void SpdyFramer::Reset() { | 
| settings_scratch_.Reset(); | 
| altsvc_scratch_.Reset(); | 
| remaining_padding_payload_length_ = 0; | 
| -  remaining_padding_length_fields_ = 0; | 
| } | 
|  | 
| size_t SpdyFramer::GetDataFrameMinimumSize() const { | 
| @@ -781,8 +780,8 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { | 
|  | 
| uint8 valid_data_flags = 0; | 
| if (protocol_version() > SPDY3) { | 
| -      valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | | 
| -          DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH; | 
| +      valid_data_flags = | 
| +          DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED; | 
| } else { | 
| valid_data_flags = DATA_FLAG_FIN; | 
| } | 
| @@ -937,7 +936,7 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { | 
| current_frame_flags_ & | 
| ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | 
| HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT | | 
| -                         HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) { | 
| +                         HEADERS_FLAG_PADDED)) { | 
| set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 
| } | 
| } | 
| @@ -966,7 +965,7 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { | 
| } else if (protocol_version() > SPDY3 && | 
| current_frame_flags_ & | 
| ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | | 
| -                       HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) { | 
| +                       HEADERS_FLAG_PADDED)) { | 
| set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 
| } | 
| break; | 
| @@ -2077,55 +2076,44 @@ size_t SpdyFramer::ProcessAltSvcFramePayload(const char* data, size_t len) { | 
| return processed_bytes; | 
| } | 
|  | 
| +// TODO(raullenchai): ProcessFramePaddingLength should be able to deal with | 
| +// HEADERS_FLAG_PADDED and PUSH_PROMISE_FLAG_PADDED as well (see b/15777051). | 
| size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { | 
| DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); | 
| +  DCHECK_EQ(remaining_padding_payload_length_, 0u); | 
|  | 
| size_t original_len = len; | 
| -  if (remaining_padding_length_fields_ == 0) { | 
| -    DCHECK_EQ(remaining_padding_payload_length_, 0u); | 
| -    bool pad_low = false; | 
| -    bool pad_high = false; | 
| -    if (current_frame_flags_ & DATA_FLAG_PAD_LOW) { | 
| -      pad_low = true; | 
| -      ++remaining_padding_length_fields_; | 
| -    } | 
| -    if (current_frame_flags_ & DATA_FLAG_PAD_HIGH) { | 
| -      pad_high = true; | 
| -      ++remaining_padding_length_fields_; | 
| -    } | 
| -    if ((pad_high && !pad_low) || | 
| -        remaining_data_length_ < remaining_padding_length_fields_) { | 
| -      set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 
| +  if (current_frame_flags_ & DATA_FLAG_PADDED) { | 
| +    if (len != 0) { | 
| +      if (remaining_data_length_ < 1) { | 
| +        set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 
| +        return 0; | 
| +      } | 
| + | 
| +      remaining_padding_payload_length_ = *reinterpret_cast<const uint8*>(data); | 
| +      ++data; | 
| +      --len; | 
| +      --remaining_data_length_; | 
| +    } else { | 
| +      // We don't have the data available for parsing the pad length field. Keep | 
| +      // waiting. | 
| return 0; | 
| } | 
| } | 
|  | 
| -  // Parse the padding length. | 
| -  while (len != 0 && remaining_padding_length_fields_ != 0) { | 
| -    remaining_padding_payload_length_ = | 
| -        (remaining_padding_payload_length_ << 8) + | 
| -        *reinterpret_cast<const uint8*>(data); | 
| -    ++data; | 
| -    --len; | 
| -    --remaining_padding_length_fields_; | 
| -    --remaining_data_length_; | 
| +  if (remaining_padding_payload_length_ > remaining_data_length_) { | 
| +    set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 
| +    return 0; | 
| } | 
| - | 
| -  if (remaining_padding_length_fields_ == 0) { | 
| -    if (remaining_padding_payload_length_ > remaining_data_length_) { | 
| -      set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 
| -      return 0; | 
| -    } | 
| -    if (current_frame_type_ == DATA) { | 
| -      CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); | 
| -    } else { | 
| -      DCHECK(current_frame_type_ == HEADERS || | 
| -             current_frame_type_ == PUSH_PROMISE || | 
| -             current_frame_type_ == SYN_STREAM || | 
| -             current_frame_type_ == SYN_REPLY) | 
| -          << current_frame_type_; | 
| -      CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 
| -    } | 
| +  if (current_frame_type_ == DATA) { | 
| +    CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); | 
| +  } else { | 
| +    DCHECK(current_frame_type_ == HEADERS || | 
| +           current_frame_type_ == PUSH_PROMISE || | 
| +           current_frame_type_ == SYN_STREAM || | 
| +           current_frame_type_ == SYN_REPLY) | 
| +        << current_frame_type_; | 
| +    CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 
| } | 
| return original_len - len; | 
| } | 
| @@ -2267,12 +2255,8 @@ SpdySerializedFrame* SpdyFramer::SerializeData( | 
|  | 
| if (protocol_version() > SPDY3) { | 
| int num_padding_fields = 0; | 
| -    if (data_ir.pad_low()) { | 
| -      flags |= DATA_FLAG_PAD_LOW; | 
| -      ++num_padding_fields; | 
| -    } | 
| -    if (data_ir.pad_high()) { | 
| -      flags |= DATA_FLAG_PAD_HIGH; | 
| +    if (data_ir.padded()) { | 
| +      flags |= DATA_FLAG_PADDED; | 
| ++num_padding_fields; | 
| } | 
|  | 
| @@ -2281,10 +2265,7 @@ SpdySerializedFrame* SpdyFramer::SerializeData( | 
| GetDataFrameMinimumSize(); | 
| SpdyFrameBuilder builder(size_with_padding, protocol_version()); | 
| builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 
| -    if (data_ir.pad_high()) { | 
| -      builder.WriteUInt8(data_ir.padding_payload_len() >> 8); | 
| -    } | 
| -    if (data_ir.pad_low()) { | 
| +    if (data_ir.padded()) { | 
| builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 
| } | 
| builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); | 
| @@ -2314,12 +2295,8 @@ SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( | 
| size_t frame_size = GetDataFrameMinimumSize(); | 
| size_t num_padding_fields = 0; | 
| if (protocol_version() > SPDY3) { | 
| -    if (data_ir.pad_low()) { | 
| -      flags |= DATA_FLAG_PAD_LOW; | 
| -      ++num_padding_fields; | 
| -    } | 
| -    if (data_ir.pad_high()) { | 
| -      flags |= DATA_FLAG_PAD_HIGH; | 
| +    if (data_ir.padded()) { | 
| +      flags |= DATA_FLAG_PADDED; | 
| ++num_padding_fields; | 
| } | 
| frame_size += num_padding_fields; | 
| @@ -2328,10 +2305,7 @@ SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( | 
| SpdyFrameBuilder builder(frame_size, protocol_version()); | 
| builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 
| if (protocol_version() > SPDY3) { | 
| -    if (data_ir.pad_high()) { | 
| -      builder.WriteUInt8(data_ir.padding_payload_len() >> 8); | 
| -    } | 
| -    if (data_ir.pad_low()) { | 
| +    if (data_ir.padded()) { | 
| builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 
| } | 
| builder.OverwriteLength(*this,  num_padding_fields + | 
|  |