1 // Copyright 2015 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifdef UNSAFE_BUFFERS_BUILD 6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors. 7 #pragma allow_unsafe_buffers 8 #endif 9 10 #include "net/http/http_chunked_decoder.h" 11 12 #include <stddef.h> 13 #include <stdint.h> 14 15 #include <algorithm> 16 #include <vector> 17 18 #include "base/containers/to_vector.h" 19 20 // Entry point for LibFuzzer. LLVMFuzzerTestOneInput(const uint8_t * data_ptr,size_t size)21extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data_ptr, size_t size) { 22 // SAFETY: libfuzzer provides a valid pointer and size pair. 23 auto data = UNSAFE_BUFFERS(base::span(data_ptr, size)); 24 net::HttpChunkedDecoder decoder; 25 26 // Feed data to decoder.FilterBuf() by blocks of "random" size. 27 size_t block_size = 0; 28 for (size_t offset = 0; offset < size; offset += block_size) { 29 // Since there is no input for block_size values, but it should be strictly 30 // determined, let's calculate these values using a couple of data bytes. 31 uint8_t temp_block_size = data[offset] ^ data[size - offset - 1]; 32 33 // Let temp_block_size be in range from 0 to 0x3F (0b00111111). 34 temp_block_size &= 0x3F; 35 36 // XOR with previous block size to get different values for different data. 37 block_size ^= temp_block_size; 38 39 // Prevent infinite loop if block_size == 0. 40 block_size = std::max(block_size, static_cast<size_t>(1)); 41 42 // Prevent out-of-bounds access. 43 block_size = std::min(block_size, size - offset); 44 45 // Create new buffer with current block of data and feed it to the decoder. 46 std::vector<uint8_t> buffer = 47 base::ToVector(data.subspan(offset, block_size)); 48 int result = decoder.FilterBuf(buffer); 49 if (result < 0) 50 return 0; 51 } 52 53 return 0; 54 } 55