blob: 495a58ffdfd4c60d9f1bf2f88987428c300d7d2f [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright 2018 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
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/core/qpack/qpack_instruction_decoder.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
7#include <algorithm>
8#include <utility>
9
vasilvv7cac7b02020-10-08 12:32:10 -070010#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050011#include "quic/platform/api/quic_bug_tracker.h"
12#include "quic/platform/api/quic_logging.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013
14namespace quic {
15
16namespace {
17
18// Maximum length of header name and header value. This limits the amount of
19// memory the peer can make the decoder allocate when sending string literals.
20const size_t kStringLiteralLengthLimit = 1024 * 1024;
21
22} // namespace
23
24QpackInstructionDecoder::QpackInstructionDecoder(const QpackLanguage* language,
25 Delegate* delegate)
26 : language_(language),
27 delegate_(delegate),
28 s_bit_(false),
29 varint_(0),
30 varint2_(0),
31 is_huffman_encoded_(false),
32 string_length_(0),
33 error_detected_(false),
34 state_(State::kStartInstruction) {}
35
vasilvv7cac7b02020-10-08 12:32:10 -070036bool QpackInstructionDecoder::Decode(absl::string_view data) {
vasilvvf8035162021-02-01 14:49:14 -080037 QUICHE_DCHECK(!data.empty());
38 QUICHE_DCHECK(!error_detected_);
QUICHE teama6ef0a62019-03-07 20:34:33 -050039
40 while (true) {
bncfb4f4fc2019-11-18 17:14:56 -080041 bool success = true;
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 size_t bytes_consumed = 0;
43
44 switch (state_) {
45 case State::kStartInstruction:
bncfb4f4fc2019-11-18 17:14:56 -080046 success = DoStartInstruction(data);
QUICHE teama6ef0a62019-03-07 20:34:33 -050047 break;
48 case State::kStartField:
bncfb4f4fc2019-11-18 17:14:56 -080049 success = DoStartField();
QUICHE teama6ef0a62019-03-07 20:34:33 -050050 break;
51 case State::kReadBit:
bncfb4f4fc2019-11-18 17:14:56 -080052 success = DoReadBit(data);
QUICHE teama6ef0a62019-03-07 20:34:33 -050053 break;
54 case State::kVarintStart:
bncfb4f4fc2019-11-18 17:14:56 -080055 success = DoVarintStart(data, &bytes_consumed);
QUICHE teama6ef0a62019-03-07 20:34:33 -050056 break;
57 case State::kVarintResume:
bncfb4f4fc2019-11-18 17:14:56 -080058 success = DoVarintResume(data, &bytes_consumed);
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 break;
60 case State::kVarintDone:
bncfb4f4fc2019-11-18 17:14:56 -080061 success = DoVarintDone();
QUICHE teama6ef0a62019-03-07 20:34:33 -050062 break;
63 case State::kReadString:
bncfb4f4fc2019-11-18 17:14:56 -080064 success = DoReadString(data, &bytes_consumed);
QUICHE teama6ef0a62019-03-07 20:34:33 -050065 break;
66 case State::kReadStringDone:
bncfb4f4fc2019-11-18 17:14:56 -080067 success = DoReadStringDone();
QUICHE teama6ef0a62019-03-07 20:34:33 -050068 break;
69 }
70
bncfb4f4fc2019-11-18 17:14:56 -080071 if (!success) {
72 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -050073 }
74
bncfb4f4fc2019-11-18 17:14:56 -080075 // |success| must be false if an error is detected.
vasilvvf8035162021-02-01 14:49:14 -080076 QUICHE_DCHECK(!error_detected_);
bncfb4f4fc2019-11-18 17:14:56 -080077
vasilvvf8035162021-02-01 14:49:14 -080078 QUICHE_DCHECK_LE(bytes_consumed, data.size());
QUICHE teama6ef0a62019-03-07 20:34:33 -050079
vasilvv7cac7b02020-10-08 12:32:10 -070080 data = absl::string_view(data.data() + bytes_consumed,
81 data.size() - bytes_consumed);
QUICHE teama6ef0a62019-03-07 20:34:33 -050082
83 // Stop processing if no more data but next state would require it.
84 if (data.empty() && (state_ != State::kStartField) &&
85 (state_ != State::kVarintDone) && (state_ != State::kReadStringDone)) {
bncfb4f4fc2019-11-18 17:14:56 -080086 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -050087 }
88 }
bncfb4f4fc2019-11-18 17:14:56 -080089
90 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -050091}
92
93bool QpackInstructionDecoder::AtInstructionBoundary() const {
94 return state_ == State::kStartInstruction;
95}
96
vasilvv7cac7b02020-10-08 12:32:10 -070097bool QpackInstructionDecoder::DoStartInstruction(absl::string_view data) {
vasilvvf8035162021-02-01 14:49:14 -080098 QUICHE_DCHECK(!data.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -050099
100 instruction_ = LookupOpcode(data[0]);
101 field_ = instruction_->fields.begin();
102
103 state_ = State::kStartField;
bncfb4f4fc2019-11-18 17:14:56 -0800104 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105}
106
bncfb4f4fc2019-11-18 17:14:56 -0800107bool QpackInstructionDecoder::DoStartField() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500108 if (field_ == instruction_->fields.end()) {
109 // Completed decoding this instruction.
110
111 if (!delegate_->OnInstructionDecoded(instruction_)) {
bncfb4f4fc2019-11-18 17:14:56 -0800112 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500113 }
114
115 state_ = State::kStartInstruction;
bncfb4f4fc2019-11-18 17:14:56 -0800116 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500117 }
118
119 switch (field_->type) {
120 case QpackInstructionFieldType::kSbit:
121 case QpackInstructionFieldType::kName:
122 case QpackInstructionFieldType::kValue:
123 state_ = State::kReadBit;
bncfb4f4fc2019-11-18 17:14:56 -0800124 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 case QpackInstructionFieldType::kVarint:
126 case QpackInstructionFieldType::kVarint2:
127 state_ = State::kVarintStart;
bncfb4f4fc2019-11-18 17:14:56 -0800128 return true;
129 default:
QUICHE team407e1c72021-03-16 14:46:23 -0700130 QUIC_BUG(quic_bug_10767_1) << "Invalid field type.";
bncfb4f4fc2019-11-18 17:14:56 -0800131 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500132 }
133}
134
vasilvv7cac7b02020-10-08 12:32:10 -0700135bool QpackInstructionDecoder::DoReadBit(absl::string_view data) {
vasilvvf8035162021-02-01 14:49:14 -0800136 QUICHE_DCHECK(!data.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137
138 switch (field_->type) {
139 case QpackInstructionFieldType::kSbit: {
140 const uint8_t bitmask = field_->param;
141 s_bit_ = (data[0] & bitmask) == bitmask;
142
143 ++field_;
144 state_ = State::kStartField;
145
bncfb4f4fc2019-11-18 17:14:56 -0800146 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147 }
148 case QpackInstructionFieldType::kName:
149 case QpackInstructionFieldType::kValue: {
150 const uint8_t prefix_length = field_->param;
vasilvvf8035162021-02-01 14:49:14 -0800151 QUICHE_DCHECK_GE(7, prefix_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152 const uint8_t bitmask = 1 << prefix_length;
153 is_huffman_encoded_ = (data[0] & bitmask) == bitmask;
154
155 state_ = State::kVarintStart;
156
bncfb4f4fc2019-11-18 17:14:56 -0800157 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500158 }
159 default:
QUICHE team407e1c72021-03-16 14:46:23 -0700160 QUIC_BUG(quic_bug_10767_2) << "Invalid field type.";
bncfb4f4fc2019-11-18 17:14:56 -0800161 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500162 }
163}
164
vasilvv7cac7b02020-10-08 12:32:10 -0700165bool QpackInstructionDecoder::DoVarintStart(absl::string_view data,
bncfb4f4fc2019-11-18 17:14:56 -0800166 size_t* bytes_consumed) {
vasilvvf8035162021-02-01 14:49:14 -0800167 QUICHE_DCHECK(!data.empty());
168 QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
169 field_->type == QpackInstructionFieldType::kVarint2 ||
170 field_->type == QpackInstructionFieldType::kName ||
171 field_->type == QpackInstructionFieldType::kValue);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500172
173 http2::DecodeBuffer buffer(data.data() + 1, data.size() - 1);
174 http2::DecodeStatus status =
175 varint_decoder_.Start(data[0], field_->param, &buffer);
176
bncfb4f4fc2019-11-18 17:14:56 -0800177 *bytes_consumed = 1 + buffer.Offset();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500178 switch (status) {
179 case http2::DecodeStatus::kDecodeDone:
180 state_ = State::kVarintDone;
bncfb4f4fc2019-11-18 17:14:56 -0800181 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500182 case http2::DecodeStatus::kDecodeInProgress:
183 state_ = State::kVarintResume;
bncfb4f4fc2019-11-18 17:14:56 -0800184 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500185 case http2::DecodeStatus::kDecodeError:
bnc4e440102020-10-20 17:32:29 -0700186 OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
bncfb4f4fc2019-11-18 17:14:56 -0800187 return false;
danzh9693b992019-07-12 11:05:45 -0700188 default:
QUICHE team407e1c72021-03-16 14:46:23 -0700189 QUIC_BUG(quic_bug_10767_3) << "Unknown decode status " << status;
bncfb4f4fc2019-11-18 17:14:56 -0800190 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500191 }
192}
193
vasilvv7cac7b02020-10-08 12:32:10 -0700194bool QpackInstructionDecoder::DoVarintResume(absl::string_view data,
bncfb4f4fc2019-11-18 17:14:56 -0800195 size_t* bytes_consumed) {
vasilvvf8035162021-02-01 14:49:14 -0800196 QUICHE_DCHECK(!data.empty());
197 QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
198 field_->type == QpackInstructionFieldType::kVarint2 ||
199 field_->type == QpackInstructionFieldType::kName ||
200 field_->type == QpackInstructionFieldType::kValue);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500201
202 http2::DecodeBuffer buffer(data);
203 http2::DecodeStatus status = varint_decoder_.Resume(&buffer);
204
bncfb4f4fc2019-11-18 17:14:56 -0800205 *bytes_consumed = buffer.Offset();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500206 switch (status) {
207 case http2::DecodeStatus::kDecodeDone:
208 state_ = State::kVarintDone;
bncfb4f4fc2019-11-18 17:14:56 -0800209 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500210 case http2::DecodeStatus::kDecodeInProgress:
vasilvvf8035162021-02-01 14:49:14 -0800211 QUICHE_DCHECK_EQ(*bytes_consumed, data.size());
212 QUICHE_DCHECK(buffer.Empty());
bncfb4f4fc2019-11-18 17:14:56 -0800213 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500214 case http2::DecodeStatus::kDecodeError:
bnc4e440102020-10-20 17:32:29 -0700215 OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
bncfb4f4fc2019-11-18 17:14:56 -0800216 return false;
danzh9693b992019-07-12 11:05:45 -0700217 default:
QUICHE team407e1c72021-03-16 14:46:23 -0700218 QUIC_BUG(quic_bug_10767_4) << "Unknown decode status " << status;
bncfb4f4fc2019-11-18 17:14:56 -0800219 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220 }
221}
222
bncfb4f4fc2019-11-18 17:14:56 -0800223bool QpackInstructionDecoder::DoVarintDone() {
vasilvvf8035162021-02-01 14:49:14 -0800224 QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
225 field_->type == QpackInstructionFieldType::kVarint2 ||
226 field_->type == QpackInstructionFieldType::kName ||
227 field_->type == QpackInstructionFieldType::kValue);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228
229 if (field_->type == QpackInstructionFieldType::kVarint) {
230 varint_ = varint_decoder_.value();
231
232 ++field_;
233 state_ = State::kStartField;
bncfb4f4fc2019-11-18 17:14:56 -0800234 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500235 }
236
237 if (field_->type == QpackInstructionFieldType::kVarint2) {
238 varint2_ = varint_decoder_.value();
239
240 ++field_;
241 state_ = State::kStartField;
bncfb4f4fc2019-11-18 17:14:56 -0800242 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500243 }
244
245 string_length_ = varint_decoder_.value();
246 if (string_length_ > kStringLiteralLengthLimit) {
bnc4e440102020-10-20 17:32:29 -0700247 OnError(ErrorCode::STRING_LITERAL_TOO_LONG, "String literal too long.");
bncfb4f4fc2019-11-18 17:14:56 -0800248 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500249 }
250
vasilvvc48c8712019-03-11 13:38:16 -0700251 std::string* const string =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500252 (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
253 string->clear();
254
255 if (string_length_ == 0) {
256 ++field_;
257 state_ = State::kStartField;
bncfb4f4fc2019-11-18 17:14:56 -0800258 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500259 }
260
261 string->reserve(string_length_);
262
263 state_ = State::kReadString;
bncfb4f4fc2019-11-18 17:14:56 -0800264 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500265}
266
vasilvv7cac7b02020-10-08 12:32:10 -0700267bool QpackInstructionDecoder::DoReadString(absl::string_view data,
bncfb4f4fc2019-11-18 17:14:56 -0800268 size_t* bytes_consumed) {
vasilvvf8035162021-02-01 14:49:14 -0800269 QUICHE_DCHECK(!data.empty());
270 QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
271 field_->type == QpackInstructionFieldType::kValue);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500272
vasilvvc48c8712019-03-11 13:38:16 -0700273 std::string* const string =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500274 (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
vasilvvf8035162021-02-01 14:49:14 -0800275 QUICHE_DCHECK_LT(string->size(), string_length_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500276
bncfb4f4fc2019-11-18 17:14:56 -0800277 *bytes_consumed = std::min(string_length_ - string->size(), data.size());
278 string->append(data.data(), *bytes_consumed);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500279
vasilvvf8035162021-02-01 14:49:14 -0800280 QUICHE_DCHECK_LE(string->size(), string_length_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500281 if (string->size() == string_length_) {
282 state_ = State::kReadStringDone;
283 }
bncfb4f4fc2019-11-18 17:14:56 -0800284 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500285}
286
bncfb4f4fc2019-11-18 17:14:56 -0800287bool QpackInstructionDecoder::DoReadStringDone() {
vasilvvf8035162021-02-01 14:49:14 -0800288 QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
289 field_->type == QpackInstructionFieldType::kValue);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500290
vasilvvc48c8712019-03-11 13:38:16 -0700291 std::string* const string =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500292 (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
vasilvvf8035162021-02-01 14:49:14 -0800293 QUICHE_DCHECK_EQ(string->size(), string_length_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500294
295 if (is_huffman_encoded_) {
296 huffman_decoder_.Reset();
297 // HpackHuffmanDecoder::Decode() cannot perform in-place decoding.
vasilvvc48c8712019-03-11 13:38:16 -0700298 std::string decoded_value;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500299 huffman_decoder_.Decode(*string, &decoded_value);
300 if (!huffman_decoder_.InputProperlyTerminated()) {
bnc4e440102020-10-20 17:32:29 -0700301 OnError(ErrorCode::HUFFMAN_ENCODING_ERROR,
302 "Error in Huffman-encoded string.");
bncfb4f4fc2019-11-18 17:14:56 -0800303 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500304 }
305 *string = std::move(decoded_value);
306 }
307
308 ++field_;
309 state_ = State::kStartField;
bncfb4f4fc2019-11-18 17:14:56 -0800310 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500311}
312
313const QpackInstruction* QpackInstructionDecoder::LookupOpcode(
314 uint8_t byte) const {
315 for (const auto* instruction : *language_) {
316 if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
317 return instruction;
318 }
319 }
320 // |language_| should be defined such that instruction opcodes cover every
321 // possible input.
vasilvvf8035162021-02-01 14:49:14 -0800322 QUICHE_DCHECK(false);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500323 return nullptr;
324}
325
bnc4e440102020-10-20 17:32:29 -0700326void QpackInstructionDecoder::OnError(ErrorCode error_code,
327 absl::string_view error_message) {
vasilvvf8035162021-02-01 14:49:14 -0800328 QUICHE_DCHECK(!error_detected_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500329
330 error_detected_ = true;
bnc4e440102020-10-20 17:32:29 -0700331 delegate_->OnInstructionDecodingError(error_code, error_message);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500332}
333
334} // namespace quic