Home | History | Annotate | Line # | Download | only in fuzz
      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