[chttp2] Fix fuzzer found bug (#32507)

<!--

If you know who should review your pull request, please assign it to
that
person, otherwise the pull request would get assigned randomly.

If your pull request is for a specific language, please add the
appropriate
lang label.

-->
reviewable/pr31942/r2^2
Craig Tiller 2 years ago committed by GitHub
parent 740932c899
commit 2485fa94bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/core/ext/transport/chttp2/transport/hpack_parser.cc
  2. 11
      src/core/lib/transport/metadata_batch.cc
  3. 21
      src/core/lib/transport/metadata_batch.h
  4. 4
      test/core/transport/chttp2/hpack_parser_corpus/clusterfuzz-testcase-minimized-hpack_parser_fuzzer-4859070937169920

@ -803,7 +803,7 @@ class HPackParser::Parser {
template <typename Key, typename Value>
void Encode(Key, const Value& value) {
AddToSummary(Key::key(), Key::Encode(value).size());
AddToSummary(Key::key(), EncodedSizeOfKey(Key(), value));
}
private:

@ -168,6 +168,17 @@ StaticSlice HttpSchemeMetadata::Encode(ValueType x) {
}
}
size_t EncodedSizeOfKey(HttpSchemeMetadata, HttpSchemeMetadata::ValueType x) {
switch (x) {
case HttpSchemeMetadata::kHttp:
return 4;
case HttpSchemeMetadata::kHttps:
return 5;
default:
return 0;
}
}
const char* HttpSchemeMetadata::DisplayValue(ValueType content_type) {
switch (content_type) {
case kHttp:

@ -49,6 +49,16 @@
namespace grpc_core {
// Given a metadata key and a value, return the encoded size.
// Defaults to calling the key's Encode() method and then calculating the size
// of that, but can be overridden for specific keys if there's a better way of
// doing this.
// May return 0 if the size is unknown/unknowable.
template <typename Key>
size_t EncodedSizeOfKey(Key, const typename Key::ValueType& value) {
return Key::Encode(value).size();
}
// grpc-timeout metadata trait.
// ValueType is defined as Timestamp - an absolute timestamp (i.e. a
// deadline!), that is converted to a duration by transports before being
@ -90,6 +100,10 @@ struct TeMetadata {
static const char* DisplayMemento(MementoType te) { return DisplayValue(te); }
};
inline size_t EncodedSizeOfKey(TeMetadata, TeMetadata::ValueType x) {
return x == TeMetadata::kTrailers ? 8 : 0;
}
// content-type metadata trait.
struct ContentTypeMetadata {
static constexpr bool kRepeatable = false;
@ -140,6 +154,8 @@ struct HttpSchemeMetadata {
}
};
size_t EncodedSizeOfKey(HttpSchemeMetadata, HttpSchemeMetadata::ValueType x);
// method metadata trait.
struct HttpMethodMetadata {
static constexpr bool kRepeatable = false;
@ -362,6 +378,11 @@ struct GrpcLbClientStatsMetadata {
}
};
inline size_t EncodedSizeOfKey(GrpcLbClientStatsMetadata,
GrpcLbClientStatsMetadata::ValueType) {
return 0;
}
// lb-token metadata
struct LbTokenMetadata : public SimpleSliceBasedMetadata {
static constexpr bool kRepeatable = false;

@ -0,0 +1,4 @@
frames {
max_metadata_length: 58
parse: "@\002te\000@\002te\002@\000et\000;e"
}
Loading…
Cancel
Save