| Index: net/http2/decoder/http2_structure_decoder.cc
|
| diff --git a/net/http2/decoder/http2_structure_decoder.cc b/net/http2/decoder/http2_structure_decoder.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a7b1dca47a346594ff9e7776a7d3aeddc5c407be
|
| --- /dev/null
|
| +++ b/net/http2/decoder/http2_structure_decoder.cc
|
| @@ -0,0 +1,90 @@
|
| +// 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/http2_structure_decoder.h"
|
| +
|
| +#include <algorithm>
|
| +
|
| +#include "net/http2/tools/http2_bug_tracker.h"
|
| +
|
| +namespace net {
|
| +
|
| +// Below we have some defensive coding: if we somehow run off the end, don't
|
| +// overwrite lots of memory. Note that most of this decoder is not defensive
|
| +// against bugs in the decoder, only against malicious encoders, but since
|
| +// we're copying memory into a buffer here, let's make sure we don't allow a
|
| +// small mistake to grow larger. The decoder will get stuck if we hit the
|
| +// HTTP2_BUG conditions, but shouldn't corrupt memory.
|
| +
|
| +uint32_t Http2StructureDecoder::IncompleteStart(DecodeBuffer* db,
|
| + uint32_t target_size) {
|
| + if (target_size > sizeof buffer_) {
|
| + HTTP2_BUG << "target_size too large for buffer: " << target_size;
|
| + return 0;
|
| + }
|
| + const uint32_t num_to_copy = db->MinLengthRemaining(target_size);
|
| + memcpy(buffer_, db->cursor(), num_to_copy);
|
| + offset_ = num_to_copy;
|
| + db->AdvanceCursor(num_to_copy);
|
| + return num_to_copy;
|
| +}
|
| +
|
| +DecodeStatus Http2StructureDecoder::IncompleteStart(DecodeBuffer* db,
|
| + uint32_t* remaining_payload,
|
| + uint32_t target_size) {
|
| + DVLOG(1) << "IncompleteStart@" << this
|
| + << ": *remaining_payload=" << *remaining_payload
|
| + << "; target_size=" << target_size
|
| + << "; db->Remaining=" << db->Remaining();
|
| + *remaining_payload -=
|
| + IncompleteStart(db, std::min(target_size, *remaining_payload));
|
| + if (*remaining_payload > 0 && db->Empty()) {
|
| + return DecodeStatus::kDecodeInProgress;
|
| + }
|
| + DVLOG(1) << "IncompleteStart: kDecodeError";
|
| + return DecodeStatus::kDecodeError;
|
| +}
|
| +
|
| +bool Http2StructureDecoder::ResumeFillingBuffer(DecodeBuffer* db,
|
| + uint32_t target_size) {
|
| + DVLOG(2) << "ResumeFillingBuffer@" << this << ": target_size=" << target_size
|
| + << "; offset_=" << offset_ << "; db->Remaining=" << db->Remaining();
|
| + if (target_size < offset_) {
|
| + HTTP2_BUG << "Already filled buffer_! target_size=" << target_size
|
| + << " offset_=" << offset_;
|
| + return false;
|
| + }
|
| + const uint32_t needed = target_size - offset_;
|
| + const uint32_t num_to_copy = db->MinLengthRemaining(needed);
|
| + DVLOG(2) << "ResumeFillingBuffer num_to_copy=" << num_to_copy;
|
| + memcpy(&buffer_[offset_], db->cursor(), num_to_copy);
|
| + db->AdvanceCursor(num_to_copy);
|
| + offset_ += num_to_copy;
|
| + return needed == num_to_copy;
|
| +}
|
| +
|
| +bool Http2StructureDecoder::ResumeFillingBuffer(DecodeBuffer* db,
|
| + uint32_t* remaining_payload,
|
| + uint32_t target_size) {
|
| + DVLOG(2) << "ResumeFillingBuffer@" << this << ": target_size=" << target_size
|
| + << "; offset_=" << offset_
|
| + << "; *remaining_payload=" << *remaining_payload
|
| + << "; db->Remaining=" << db->Remaining();
|
| + if (target_size < offset_) {
|
| + HTTP2_BUG << "Already filled buffer_! target_size=" << target_size
|
| + << " offset_=" << offset_;
|
| + return false;
|
| + }
|
| + const uint32_t needed = target_size - offset_;
|
| + const uint32_t num_to_copy =
|
| + db->MinLengthRemaining(std::min(needed, *remaining_payload));
|
| + DVLOG(2) << "ResumeFillingBuffer num_to_copy=" << num_to_copy;
|
| + memcpy(&buffer_[offset_], db->cursor(), num_to_copy);
|
| + db->AdvanceCursor(num_to_copy);
|
| + offset_ += num_to_copy;
|
| + *remaining_payload -= num_to_copy;
|
| + return needed == num_to_copy;
|
| +}
|
| +
|
| +} // namespace net
|
|
|