OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/http2/decoder/frame_decoder_state.h" |
| 6 |
| 7 namespace net { |
| 8 |
| 9 DecodeStatus FrameDecoderState::ReadPadLength(DecodeBuffer* db, |
| 10 bool report_pad_length) { |
| 11 DVLOG(2) << "ReadPadLength db->Remaining=" << db->Remaining() |
| 12 << "; payload_length=" << frame_header().payload_length; |
| 13 DCHECK(IsPaddable()); |
| 14 DCHECK(frame_header().IsPadded()); |
| 15 |
| 16 // Pad Length is always at the start of the frame, so remaining_payload_ |
| 17 // should equal payload_length at this point. |
| 18 const uint32_t total_payload = frame_header().payload_length; |
| 19 DCHECK_EQ(total_payload, remaining_payload_); |
| 20 DCHECK_EQ(0u, remaining_padding_); |
| 21 |
| 22 if (db->HasData()) { |
| 23 const uint32_t pad_length = db->DecodeUInt8(); |
| 24 const uint32_t total_padding = pad_length + 1; |
| 25 if (total_padding <= total_payload) { |
| 26 remaining_padding_ = pad_length; |
| 27 remaining_payload_ = total_payload - total_padding; |
| 28 if (report_pad_length) { |
| 29 listener()->OnPadLength(pad_length); |
| 30 } |
| 31 return DecodeStatus::kDecodeDone; |
| 32 } |
| 33 const uint32_t missing_length = total_padding - total_payload; |
| 34 // To allow for the possibility of recovery, record the number of |
| 35 // remaining bytes of the frame's payload (invalid though it is) |
| 36 // in remaining_payload_. |
| 37 remaining_payload_ = total_payload - 1; // 1 for sizeof(Pad Length). |
| 38 remaining_padding_ = 0; |
| 39 listener()->OnPaddingTooLong(frame_header(), missing_length); |
| 40 return DecodeStatus::kDecodeError; |
| 41 } |
| 42 |
| 43 if (total_payload == 0) { |
| 44 remaining_payload_ = 0; |
| 45 remaining_padding_ = 0; |
| 46 listener()->OnPaddingTooLong(frame_header(), 1); |
| 47 return DecodeStatus::kDecodeError; |
| 48 } |
| 49 // Need to wait for another buffer. |
| 50 return DecodeStatus::kDecodeInProgress; |
| 51 } |
| 52 |
| 53 bool FrameDecoderState::SkipPadding(DecodeBuffer* db) { |
| 54 DVLOG(2) << "SkipPadding remaining_padding_=" << remaining_padding_ |
| 55 << ", db->Remaining=" << db->Remaining() |
| 56 << ", header: " << frame_header(); |
| 57 DCHECK_EQ(remaining_payload_, 0u); |
| 58 DCHECK(IsPaddable()) << "header: " << frame_header(); |
| 59 DCHECK_GE(remaining_padding_, 0u); |
| 60 DCHECK(remaining_padding_ == 0 || frame_header().IsPadded()) |
| 61 << "remaining_padding_=" << remaining_padding_ |
| 62 << ", header: " << frame_header(); |
| 63 const size_t avail = AvailablePadding(db); |
| 64 if (avail > 0) { |
| 65 listener()->OnPadding(db->cursor(), avail); |
| 66 db->AdvanceCursor(avail); |
| 67 remaining_padding_ -= avail; |
| 68 } |
| 69 return remaining_padding_ == 0; |
| 70 } |
| 71 |
| 72 DecodeStatus FrameDecoderState::ReportFrameSizeError() { |
| 73 DVLOG(2) << "FrameDecoderState::ReportFrameSizeError: " |
| 74 << " remaining_payload_=" << remaining_payload_ |
| 75 << "; remaining_padding_=" << remaining_padding_ |
| 76 << ", header: " << frame_header(); |
| 77 listener()->OnFrameSizeError(frame_header()); |
| 78 return DecodeStatus::kDecodeError; |
| 79 } |
| 80 |
| 81 } // namespace net |
OLD | NEW |