mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 22:36:09 +03:00
82 lines
3.0 KiB
C++
82 lines
3.0 KiB
C++
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#include "net/http2/decoder/frame_decoder_state.h"
|
||
|
|
||
|
namespace net {
|
||
|
|
||
|
DecodeStatus FrameDecoderState::ReadPadLength(DecodeBuffer* db,
|
||
|
bool report_pad_length) {
|
||
|
DVLOG(2) << "ReadPadLength db->Remaining=" << db->Remaining()
|
||
|
<< "; payload_length=" << frame_header().payload_length;
|
||
|
DCHECK(IsPaddable());
|
||
|
DCHECK(frame_header().IsPadded());
|
||
|
|
||
|
// Pad Length is always at the start of the frame, so remaining_payload_
|
||
|
// should equal payload_length at this point.
|
||
|
const uint32_t total_payload = frame_header().payload_length;
|
||
|
DCHECK_EQ(total_payload, remaining_payload_);
|
||
|
DCHECK_EQ(0u, remaining_padding_);
|
||
|
|
||
|
if (db->HasData()) {
|
||
|
const uint32_t pad_length = db->DecodeUInt8();
|
||
|
const uint32_t total_padding = pad_length + 1;
|
||
|
if (total_padding <= total_payload) {
|
||
|
remaining_padding_ = pad_length;
|
||
|
remaining_payload_ = total_payload - total_padding;
|
||
|
if (report_pad_length) {
|
||
|
listener()->OnPadLength(pad_length);
|
||
|
}
|
||
|
return DecodeStatus::kDecodeDone;
|
||
|
}
|
||
|
const uint32_t missing_length = total_padding - total_payload;
|
||
|
// To allow for the possibility of recovery, record the number of
|
||
|
// remaining bytes of the frame's payload (invalid though it is)
|
||
|
// in remaining_payload_.
|
||
|
remaining_payload_ = total_payload - 1; // 1 for sizeof(Pad Length).
|
||
|
remaining_padding_ = 0;
|
||
|
listener()->OnPaddingTooLong(frame_header(), missing_length);
|
||
|
return DecodeStatus::kDecodeError;
|
||
|
}
|
||
|
|
||
|
if (total_payload == 0) {
|
||
|
remaining_payload_ = 0;
|
||
|
remaining_padding_ = 0;
|
||
|
listener()->OnPaddingTooLong(frame_header(), 1);
|
||
|
return DecodeStatus::kDecodeError;
|
||
|
}
|
||
|
// Need to wait for another buffer.
|
||
|
return DecodeStatus::kDecodeInProgress;
|
||
|
}
|
||
|
|
||
|
bool FrameDecoderState::SkipPadding(DecodeBuffer* db) {
|
||
|
DVLOG(2) << "SkipPadding remaining_padding_=" << remaining_padding_
|
||
|
<< ", db->Remaining=" << db->Remaining()
|
||
|
<< ", header: " << frame_header();
|
||
|
DCHECK_EQ(remaining_payload_, 0u);
|
||
|
DCHECK(IsPaddable()) << "header: " << frame_header();
|
||
|
DCHECK_GE(remaining_padding_, 0u);
|
||
|
DCHECK(remaining_padding_ == 0 || frame_header().IsPadded())
|
||
|
<< "remaining_padding_=" << remaining_padding_
|
||
|
<< ", header: " << frame_header();
|
||
|
const size_t avail = AvailablePadding(db);
|
||
|
if (avail > 0) {
|
||
|
listener()->OnPadding(db->cursor(), avail);
|
||
|
db->AdvanceCursor(avail);
|
||
|
remaining_padding_ -= avail;
|
||
|
}
|
||
|
return remaining_padding_ == 0;
|
||
|
}
|
||
|
|
||
|
DecodeStatus FrameDecoderState::ReportFrameSizeError() {
|
||
|
DVLOG(2) << "FrameDecoderState::ReportFrameSizeError: "
|
||
|
<< " remaining_payload_=" << remaining_payload_
|
||
|
<< "; remaining_padding_=" << remaining_padding_
|
||
|
<< ", header: " << frame_header();
|
||
|
listener()->OnFrameSizeError(frame_header());
|
||
|
return DecodeStatus::kDecodeError;
|
||
|
}
|
||
|
|
||
|
} // namespace net
|