1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * All rights reserved. 4 * 5 * This source code is licensed under both the BSD-style license (found in the 6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7 * in the COPYING file in the root directory of this source tree). 8 * You may select, at your option, one of the above-listed licenses. 9 */ 10 11 #include "fuzz_helpers.h" 12 #include "fuzz_data_producer.h" 13 14 struct FUZZ_dataProducer_s{ 15 const uint8_t *data; 16 size_t size; 17 }; 18 19 FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size) { 20 FUZZ_dataProducer_t *producer = FUZZ_malloc(sizeof(FUZZ_dataProducer_t)); 21 22 producer->data = data; 23 producer->size = size; 24 return producer; 25 } 26 27 void FUZZ_dataProducer_free(FUZZ_dataProducer_t *producer) { free(producer); } 28 29 uint32_t FUZZ_dataProducer_uint32Range(FUZZ_dataProducer_t *producer, uint32_t min, 30 uint32_t max) { 31 uint32_t range = max - min; 32 uint32_t rolling = range; 33 uint32_t result = 0; 34 35 FUZZ_ASSERT(min <= max); 36 37 while (rolling > 0 && producer->size > 0) { 38 uint8_t next = *(producer->data + producer->size - 1); 39 producer->size -= 1; 40 result = (result << 8) | next; 41 rolling >>= 8; 42 } 43 44 if (range == 0xffffffff) { 45 return result; 46 } 47 48 return min + result % (range + 1); 49 } 50 51 uint32_t FUZZ_dataProducer_uint32(FUZZ_dataProducer_t *producer) { 52 return FUZZ_dataProducer_uint32Range(producer, 0, 0xffffffff); 53 } 54 55 int32_t FUZZ_dataProducer_int32Range(FUZZ_dataProducer_t *producer, 56 int32_t min, int32_t max) 57 { 58 FUZZ_ASSERT(min <= max); 59 60 if (min < 0) 61 return (int)FUZZ_dataProducer_uint32Range(producer, 0, max - min) + min; 62 63 return FUZZ_dataProducer_uint32Range(producer, min, max); 64 } 65 66 size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer){ 67 return producer->size; 68 } 69 70 void FUZZ_dataProducer_rollBack(FUZZ_dataProducer_t *producer, size_t remainingBytes) 71 { 72 FUZZ_ASSERT(remainingBytes >= producer->size); 73 producer->size = remainingBytes; 74 } 75 76 int FUZZ_dataProducer_empty(FUZZ_dataProducer_t *producer) { 77 return producer->size == 0; 78 } 79 80 size_t FUZZ_dataProducer_contract(FUZZ_dataProducer_t *producer, size_t newSize) 81 { 82 const size_t effectiveNewSize = newSize > producer->size ? producer->size : newSize; 83 84 size_t remaining = producer->size - effectiveNewSize; 85 producer->data = producer->data + remaining; 86 producer->size = effectiveNewSize; 87 return remaining; 88 } 89 90 size_t FUZZ_dataProducer_reserveDataPrefix(FUZZ_dataProducer_t *producer) 91 { 92 size_t producerSliceSize = FUZZ_dataProducer_uint32Range( 93 producer, 0, producer->size); 94 return FUZZ_dataProducer_contract(producer, producerSliceSize); 95 } 96