blob: f30a91be163fa930f4024f10f1ed6519efb0fb8f [file] [log] [blame]
QUICHE teamfd50a402018-12-07 22:54:05 -05001// 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/third_party/quiche/src/http2/decoder/http2_structure_decoder.h"
6
7#include <algorithm>
8
9#include "net/third_party/quiche/src/http2/platform/api/http2_bug_tracker.h"
10
11namespace http2 {
12
13// Below we have some defensive coding: if we somehow run off the end, don't
14// overwrite lots of memory. Note that most of this decoder is not defensive
15// against bugs in the decoder, only against malicious encoders, but since
16// we're copying memory into a buffer here, let's make sure we don't allow a
17// small mistake to grow larger. The decoder will get stuck if we hit the
18// HTTP2_BUG conditions, but shouldn't corrupt memory.
19
20uint32_t Http2StructureDecoder::IncompleteStart(DecodeBuffer* db,
21 uint32_t target_size) {
22 if (target_size > sizeof buffer_) {
23 HTTP2_BUG << "target_size too large for buffer: " << target_size;
24 return 0;
25 }
26 const uint32_t num_to_copy = db->MinLengthRemaining(target_size);
27 memcpy(buffer_, db->cursor(), num_to_copy);
28 offset_ = num_to_copy;
29 db->AdvanceCursor(num_to_copy);
30 return num_to_copy;
31}
32
33DecodeStatus Http2StructureDecoder::IncompleteStart(DecodeBuffer* db,
34 uint32_t* remaining_payload,
35 uint32_t target_size) {
QUICHE team61940b42019-03-07 23:32:27 -050036 HTTP2_DVLOG(1) << "IncompleteStart@" << this
37 << ": *remaining_payload=" << *remaining_payload
38 << "; target_size=" << target_size
39 << "; db->Remaining=" << db->Remaining();
QUICHE teamfd50a402018-12-07 22:54:05 -050040 *remaining_payload -=
41 IncompleteStart(db, std::min(target_size, *remaining_payload));
42 if (*remaining_payload > 0 && db->Empty()) {
43 return DecodeStatus::kDecodeInProgress;
44 }
QUICHE team61940b42019-03-07 23:32:27 -050045 HTTP2_DVLOG(1) << "IncompleteStart: kDecodeError";
QUICHE teamfd50a402018-12-07 22:54:05 -050046 return DecodeStatus::kDecodeError;
47}
48
49bool Http2StructureDecoder::ResumeFillingBuffer(DecodeBuffer* db,
50 uint32_t target_size) {
QUICHE team61940b42019-03-07 23:32:27 -050051 HTTP2_DVLOG(2) << "ResumeFillingBuffer@" << this
52 << ": target_size=" << target_size << "; offset_=" << offset_
53 << "; db->Remaining=" << db->Remaining();
QUICHE teamfd50a402018-12-07 22:54:05 -050054 if (target_size < offset_) {
55 HTTP2_BUG << "Already filled buffer_! target_size=" << target_size
56 << " offset_=" << offset_;
57 return false;
58 }
59 const uint32_t needed = target_size - offset_;
60 const uint32_t num_to_copy = db->MinLengthRemaining(needed);
QUICHE team61940b42019-03-07 23:32:27 -050061 HTTP2_DVLOG(2) << "ResumeFillingBuffer num_to_copy=" << num_to_copy;
QUICHE teamfd50a402018-12-07 22:54:05 -050062 memcpy(&buffer_[offset_], db->cursor(), num_to_copy);
63 db->AdvanceCursor(num_to_copy);
64 offset_ += num_to_copy;
65 return needed == num_to_copy;
66}
67
68bool Http2StructureDecoder::ResumeFillingBuffer(DecodeBuffer* db,
69 uint32_t* remaining_payload,
70 uint32_t target_size) {
QUICHE team61940b42019-03-07 23:32:27 -050071 HTTP2_DVLOG(2) << "ResumeFillingBuffer@" << this
72 << ": target_size=" << target_size << "; offset_=" << offset_
73 << "; *remaining_payload=" << *remaining_payload
74 << "; db->Remaining=" << db->Remaining();
QUICHE teamfd50a402018-12-07 22:54:05 -050075 if (target_size < offset_) {
76 HTTP2_BUG << "Already filled buffer_! target_size=" << target_size
77 << " offset_=" << offset_;
78 return false;
79 }
80 const uint32_t needed = target_size - offset_;
81 const uint32_t num_to_copy =
82 db->MinLengthRemaining(std::min(needed, *remaining_payload));
QUICHE team61940b42019-03-07 23:32:27 -050083 HTTP2_DVLOG(2) << "ResumeFillingBuffer num_to_copy=" << num_to_copy;
QUICHE teamfd50a402018-12-07 22:54:05 -050084 memcpy(&buffer_[offset_], db->cursor(), num_to_copy);
85 db->AdvanceCursor(num_to_copy);
86 offset_ += num_to_copy;
87 *remaining_payload -= num_to_copy;
88 return needed == num_to_copy;
89}
90
91} // namespace http2