Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/brpc/details/hpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,16 @@ inline ssize_t DecodeInteger(butil::IOBufBytesIterator& iter,
if (!iter) {
return 0;
}
// A well-formed integer below MAX_HPACK_INTEGER fits in a few
// continuation octets. A run of 0x80 octets (continuation bit set,
// payload bits zero) leaves tmp unchanged, so the `tmp <
// MAX_HPACK_INTEGER` guard below never trips while m keeps growing;
// once m reaches 64 the `<< m` shift is undefined behavior. Refuse the
// over-long encoding before that happens.
if (m >= 32) {
LOG(ERROR) << "Source stream is likely malformed";
return -1;
}
cur_byte = *iter;
in_bytes++;
tmp += static_cast<uint64_t>(cur_byte & 0x7f) << m;
Expand Down
21 changes: 21 additions & 0 deletions test/brpc_hpack_unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,27 @@ TEST_F(HPackTest, dynamic_table_size_update_before_header) {
ASSERT_EQ("GET", h.value);
}

TEST_F(HPackTest, integer_with_overlong_continuation) {
brpc::HPacker p;
ASSERT_EQ(0, p.Init(4096));

// Indexed header field whose index is encoded with a 7-bit prefix of all
// ones (0xFF) followed by a long run of 0x80 continuation octets. Each
// 0x80 carries a zero payload, so the decoded value never grows past its
// MAX_HPACK_INTEGER guard, but the per-octet shift amount does. Decode must
// reject this as malformed instead of shifting by 64+ bits.
butil::IOBuf buf;
uint8_t encoded[1 + 20];
encoded[0] = 0xFF;
for (size_t i = 1; i < sizeof(encoded); ++i) {
encoded[i] = 0x80;
}
buf.append(encoded, sizeof(encoded));

brpc::HPacker::Header h;
ASSERT_LT(p.Decode(&buf, &h), 0);
}

// Copied test cases from example of rfc7541
TEST_F(HPackTest, header_with_indexing) {
brpc::HPacker p1;
Expand Down
Loading