/src/zstd/tests/fuzz/fuzz_data_producer.c
Line | Count | Source |
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 | 277k | FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size) { |
20 | 277k | FUZZ_dataProducer_t *producer = FUZZ_malloc(sizeof(FUZZ_dataProducer_t)); |
21 | | |
22 | 277k | producer->data = data; |
23 | 277k | producer->size = size; |
24 | 277k | return producer; |
25 | 277k | } |
26 | | |
27 | 277k | 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 | 370M | uint32_t max) { |
31 | 370M | uint32_t range = max - min; |
32 | 370M | uint32_t rolling = range; |
33 | 370M | uint32_t result = 0; |
34 | | |
35 | 370M | FUZZ_ASSERT(min <= max); |
36 | | |
37 | 432M | while (rolling > 0 && producer->size > 0) { |
38 | 61.7M | uint8_t next = *(producer->data + producer->size - 1); |
39 | 61.7M | producer->size -= 1; |
40 | 61.7M | result = (result << 8) | next; |
41 | 61.7M | rolling >>= 8; |
42 | 61.7M | } |
43 | | |
44 | 370M | if (range == 0xffffffff) { |
45 | 6.36k | return result; |
46 | 6.36k | } |
47 | | |
48 | 370M | return min + result % (range + 1); |
49 | 370M | } |
50 | | |
51 | 6.36k | uint32_t FUZZ_dataProducer_uint32(FUZZ_dataProducer_t *producer) { |
52 | 6.36k | return FUZZ_dataProducer_uint32Range(producer, 0, 0xffffffff); |
53 | 6.36k | } |
54 | | |
55 | | int32_t FUZZ_dataProducer_int32Range(FUZZ_dataProducer_t *producer, |
56 | | int32_t min, int32_t max) |
57 | 166k | { |
58 | 166k | FUZZ_ASSERT(min <= max); |
59 | | |
60 | 166k | if (min < 0) |
61 | 74.3k | return (int)FUZZ_dataProducer_uint32Range(producer, 0, max - min) + min; |
62 | | |
63 | 91.6k | return FUZZ_dataProducer_uint32Range(producer, min, max); |
64 | 166k | } |
65 | | |
66 | 62.1k | size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer){ |
67 | 62.1k | return producer->size; |
68 | 62.1k | } |
69 | | |
70 | | void FUZZ_dataProducer_rollBack(FUZZ_dataProducer_t *producer, size_t remainingBytes) |
71 | 39.1k | { |
72 | 39.1k | FUZZ_ASSERT(remainingBytes >= producer->size); |
73 | 39.1k | producer->size = remainingBytes; |
74 | 39.1k | } |
75 | | |
76 | 5.32M | int FUZZ_dataProducer_empty(FUZZ_dataProducer_t *producer) { |
77 | 5.32M | return producer->size == 0; |
78 | 5.32M | } |
79 | | |
80 | | size_t FUZZ_dataProducer_contract(FUZZ_dataProducer_t *producer, size_t newSize) |
81 | 243k | { |
82 | 243k | const size_t effectiveNewSize = newSize > producer->size ? producer->size : newSize; |
83 | | |
84 | 243k | size_t remaining = producer->size - effectiveNewSize; |
85 | 243k | producer->data = producer->data + remaining; |
86 | 243k | producer->size = effectiveNewSize; |
87 | 243k | return remaining; |
88 | 243k | } |
89 | | |
90 | | size_t FUZZ_dataProducer_reserveDataPrefix(FUZZ_dataProducer_t *producer) |
91 | 243k | { |
92 | 243k | size_t producerSliceSize = FUZZ_dataProducer_uint32Range( |
93 | 243k | producer, 0, producer->size); |
94 | 243k | return FUZZ_dataProducer_contract(producer, producerSliceSize); |
95 | 243k | } |