1 // 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 5 #include <fuzzer/FuzzedDataProvider.h> 6 7 #include <cstddef> 8 #include <cstdint> 9 #include <limits> 10 11 #include "absl/strings/string_view.h" 12 #include "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h" 13 #include "quiche/quic/core/quic_error_codes.h" 14 #include "quiche/quic/core/quic_stream.h" 15 16 namespace quic { 17 namespace test { 18 namespace { 19 20 // A QpackDecoderStreamReceiver::Delegate implementation that ignores all 21 // decoded instructions but keeps track of whether an error has been detected. 22 class NoOpDelegate : public QpackDecoderStreamReceiver::Delegate { 23 public: NoOpDelegate()24 NoOpDelegate() : error_detected_(false) {} 25 ~NoOpDelegate() override = default; 26 OnInsertCountIncrement(uint64_t)27 void OnInsertCountIncrement(uint64_t /*increment*/) override {} OnHeaderAcknowledgement(QuicStreamId)28 void OnHeaderAcknowledgement(QuicStreamId /*stream_id*/) override {} OnStreamCancellation(QuicStreamId)29 void OnStreamCancellation(QuicStreamId /*stream_id*/) override {} OnErrorDetected(QuicErrorCode,absl::string_view)30 void OnErrorDetected(QuicErrorCode /*error_code*/, 31 absl::string_view /*error_message*/) override { 32 error_detected_ = true; 33 } 34 error_detected() const35 bool error_detected() const { return error_detected_; } 36 37 private: 38 bool error_detected_; 39 }; 40 41 } // namespace 42 43 // This fuzzer exercises QpackDecoderStreamReceiver. LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)44extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { 45 NoOpDelegate delegate; 46 QpackDecoderStreamReceiver receiver(&delegate); 47 48 FuzzedDataProvider provider(data, size); 49 50 while (!delegate.error_detected() && provider.remaining_bytes() != 0) { 51 // Process up to 64 kB fragments at a time. Too small upper bound might not 52 // provide enough coverage, too large might make fuzzing too inefficient. 53 size_t fragment_size = provider.ConsumeIntegralInRange<uint16_t>( 54 0, std::numeric_limits<uint16_t>::max()); 55 receiver.Decode(provider.ConsumeRandomLengthString(fragment_size)); 56 } 57 58 return 0; 59 } 60 61 } // namespace test 62 } // namespace quic 63