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