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