cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_test_fuzzer.c (13441B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21
     22/*
     23
     24  Data generators for fuzzing test data in a reproducible way.
     25
     26*/
     27
     28#include "SDL_config.h"
     29
     30/* Visual Studio 2008 doesn't have stdint.h */
     31#if defined(_MSC_VER) && _MSC_VER <= 1500
     32#define UINT8_MAX   ~(Uint8)0
     33#define UINT16_MAX  ~(Uint16)0
     34#define UINT32_MAX  ~(Uint32)0
     35#define UINT64_MAX  ~(Uint64)0
     36#else
     37#include <stdint.h>
     38#endif
     39#include <stdio.h>
     40#include <stdlib.h>
     41#include <limits.h>
     42#include <float.h>
     43
     44#include "SDL_test.h"
     45
     46/**
     47 * Counter for fuzzer invocations
     48 */
     49static int fuzzerInvocationCounter = 0;
     50
     51/**
     52 * Context for shared random number generator
     53 */
     54static SDLTest_RandomContext rndContext;
     55
     56/*
     57 * Note: doxygen documentation markup for functions is in the header file.
     58 */
     59
     60void
     61SDLTest_FuzzerInit(Uint64 execKey)
     62{
     63    Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF;
     64    Uint32 b = execKey & 0x00000000FFFFFFFF;
     65    SDL_memset((void *)&rndContext, 0, sizeof(SDLTest_RandomContext));
     66    SDLTest_RandomInit(&rndContext, a, b);
     67    fuzzerInvocationCounter = 0;
     68}
     69
     70int
     71SDLTest_GetFuzzerInvocationCount()
     72{
     73    return fuzzerInvocationCounter;
     74}
     75
     76Uint8
     77SDLTest_RandomUint8()
     78{
     79    fuzzerInvocationCounter++;
     80
     81    return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
     82}
     83
     84Sint8
     85SDLTest_RandomSint8()
     86{
     87    fuzzerInvocationCounter++;
     88
     89    return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
     90}
     91
     92Uint16
     93SDLTest_RandomUint16()
     94{
     95    fuzzerInvocationCounter++;
     96
     97    return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
     98}
     99
    100Sint16
    101SDLTest_RandomSint16()
    102{
    103    fuzzerInvocationCounter++;
    104
    105    return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
    106}
    107
    108Sint32
    109SDLTest_RandomSint32()
    110{
    111    fuzzerInvocationCounter++;
    112
    113    return (Sint32) SDLTest_RandomInt(&rndContext);
    114}
    115
    116Uint32
    117SDLTest_RandomUint32()
    118{
    119    fuzzerInvocationCounter++;
    120
    121    return (Uint32) SDLTest_RandomInt(&rndContext);
    122}
    123
    124Uint64
    125SDLTest_RandomUint64()
    126{
    127    Uint64 value = 0;
    128    Uint32 *vp = (void *)&value;
    129
    130    fuzzerInvocationCounter++;
    131
    132    vp[0] = SDLTest_RandomSint32();
    133    vp[1] = SDLTest_RandomSint32();
    134
    135    return value;
    136}
    137
    138Sint64
    139SDLTest_RandomSint64()
    140{
    141    Uint64 value = 0;
    142    Uint32 *vp = (void *)&value;
    143
    144    fuzzerInvocationCounter++;
    145
    146    vp[0] = SDLTest_RandomSint32();
    147    vp[1] = SDLTest_RandomSint32();
    148
    149    return value;
    150}
    151
    152
    153
    154Sint32
    155SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
    156{
    157    Sint64 min = pMin;
    158    Sint64 max = pMax;
    159    Sint64 temp;
    160    Sint64 number;
    161
    162    if(pMin > pMax) {
    163        temp = min;
    164        min = max;
    165        max = temp;
    166    } else if(pMin == pMax) {
    167        return (Sint32)min;
    168    }
    169
    170    number = SDLTest_RandomUint32();
    171    /* invocation count increment in preceeding call */
    172
    173    return (Sint32)((number % ((max + 1) - min)) + min);
    174}
    175
    176/* !
    177 * Generates a unsigned boundary value between the given boundaries.
    178 * Boundary values are inclusive. See the examples below.
    179 * If boundary2 < boundary1, the values are swapped.
    180 * If boundary1 == boundary2, value of boundary1 will be returned
    181 *
    182 * Generating boundary values for Uint8:
    183 * BoundaryValues(UINT8_MAX, 10, 20, True) -> [10,11,19,20]
    184 * BoundaryValues(UINT8_MAX, 10, 20, False) -> [9,21]
    185 * BoundaryValues(UINT8_MAX, 0, 15, True) -> [0, 1, 14, 15]
    186 * BoundaryValues(UINT8_MAX, 0, 15, False) -> [16]
    187 * BoundaryValues(UINT8_MAX, 0, 0xFF, False) -> [0], error set
    188 *
    189 * Generator works the same for other types of unsigned integers.
    190 *
    191 * \param maxValue The biggest value that is acceptable for this data type.
    192 *                  For instance, for Uint8 -> 255, Uint16 -> 65536 etc.
    193 * \param boundary1 defines lower boundary
    194 * \param boundary2 defines upper boundary
    195 * \param validDomain Generate only for valid domain (for the data type)
    196 *
    197 * \returns Returns a random boundary value for the domain or 0 in case of error
    198 */
    199Uint64
    200SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
    201{
    202        Uint64 b1, b2;
    203    Uint64 delta;
    204    Uint64 tempBuf[4];
    205    Uint8 index;
    206
    207        /* Maybe swap */
    208    if (boundary1 > boundary2) {
    209        b1 = boundary2;
    210        b2 = boundary1;
    211    } else {
    212        b1 = boundary1;
    213        b2 = boundary2;
    214        }
    215
    216    index = 0;
    217    if (validDomain == SDL_TRUE) {
    218            if (b1 == b2) {
    219                return b1;
    220            }
    221
    222            /* Generate up to 4 values within bounds */
    223            delta = b2 - b1;
    224            if (delta < 4) {
    225                do {
    226                tempBuf[index] = b1 + index;
    227                index++;
    228                    } while (index < delta);
    229            } else {
    230          tempBuf[index] = b1;
    231          index++;
    232          tempBuf[index] = b1 + 1;
    233          index++;
    234          tempBuf[index] = b2 - 1;
    235          index++;
    236          tempBuf[index] = b2;
    237          index++;
    238            }
    239        } else {
    240            /* Generate up to 2 values outside of bounds */
    241        if (b1 > 0) {
    242            tempBuf[index] = b1 - 1;
    243            index++;
    244        }
    245
    246        if (b2 < maxValue) {
    247            tempBuf[index] = b2 + 1;
    248            index++;
    249        }
    250    }
    251
    252    if (index == 0) {
    253        /* There are no valid boundaries */
    254        SDL_Unsupported();
    255        return 0;
    256    }
    257
    258    return tempBuf[SDLTest_RandomUint8() % index];
    259}
    260
    261
    262Uint8
    263SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
    264{
    265    /* max value for Uint8 */
    266    const Uint64 maxValue = UCHAR_MAX;
    267    return (Uint8)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
    268                (Uint64) boundary1, (Uint64) boundary2,
    269                validDomain);
    270}
    271
    272Uint16
    273SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
    274{
    275    /* max value for Uint16 */
    276    const Uint64 maxValue = USHRT_MAX;
    277    return (Uint16)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
    278                (Uint64) boundary1, (Uint64) boundary2,
    279                validDomain);
    280}
    281
    282Uint32
    283SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
    284{
    285    /* max value for Uint32 */
    286    #if ((ULONG_MAX) == (UINT_MAX))
    287      const Uint64 maxValue = ULONG_MAX;
    288        #else
    289      const Uint64 maxValue = UINT_MAX;
    290        #endif
    291    return (Uint32)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
    292                (Uint64) boundary1, (Uint64) boundary2,
    293                validDomain);
    294}
    295
    296Uint64
    297SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
    298{
    299    /* max value for Uint64 */
    300    const Uint64 maxValue = ULLONG_MAX;
    301    return SDLTest_GenerateUnsignedBoundaryValues(maxValue,
    302                (Uint64) boundary1, (Uint64) boundary2,
    303                validDomain);
    304}
    305
    306/* !
    307 * Generates a signed boundary value between the given boundaries.
    308 * Boundary values are inclusive. See the examples below.
    309 * If boundary2 < boundary1, the values are swapped.
    310 * If boundary1 == boundary2, value of boundary1 will be returned
    311 *
    312 * Generating boundary values for Sint8:
    313 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, True) -> [-10,-9,19,20]
    314 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, False) -> [-11,21]
    315 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -30, -15, True) -> [-30, -29, -16, -15]
    316 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 15, False) -> [16]
    317 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 127, False) -> [0], error set
    318 *
    319 * Generator works the same for other types of signed integers.
    320 *
    321 * \param minValue The smallest value that is acceptable for this data type.
    322 *                  For instance, for Uint8 -> -127, etc.
    323 * \param maxValue The biggest value that is acceptable for this data type.
    324 *                  For instance, for Uint8 -> 127, etc.
    325 * \param boundary1 defines lower boundary
    326 * \param boundary2 defines upper boundary
    327 * \param validDomain Generate only for valid domain (for the data type)
    328 *
    329 * \returns Returns a random boundary value for the domain or 0 in case of error
    330 */
    331Sint64
    332SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
    333{
    334        Sint64 b1, b2;
    335    Sint64 delta;
    336    Sint64 tempBuf[4];
    337    Uint8 index;
    338
    339        /* Maybe swap */
    340    if (boundary1 > boundary2) {
    341        b1 = boundary2;
    342        b2 = boundary1;
    343    } else {
    344        b1 = boundary1;
    345        b2 = boundary2;
    346        }
    347
    348    index = 0;
    349    if (validDomain == SDL_TRUE) {
    350            if (b1 == b2) {
    351                return b1;
    352            }
    353
    354            /* Generate up to 4 values within bounds */
    355            delta = b2 - b1;
    356            if (delta < 4) {
    357                do {
    358                tempBuf[index] = b1 + index;
    359                index++;
    360                    } while (index < delta);
    361            } else {
    362          tempBuf[index] = b1;
    363          index++;
    364          tempBuf[index] = b1 + 1;
    365          index++;
    366          tempBuf[index] = b2 - 1;
    367          index++;
    368          tempBuf[index] = b2;
    369          index++;
    370            }
    371        } else {
    372            /* Generate up to 2 values outside of bounds */
    373        if (b1 > minValue) {
    374            tempBuf[index] = b1 - 1;
    375            index++;
    376        }
    377
    378        if (b2 < maxValue) {
    379            tempBuf[index] = b2 + 1;
    380            index++;
    381        }
    382    }
    383
    384    if (index == 0) {
    385        /* There are no valid boundaries */
    386        SDL_Unsupported();
    387        return minValue;
    388    }
    389
    390    return tempBuf[SDLTest_RandomUint8() % index];
    391}
    392
    393
    394Sint8
    395SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
    396{
    397    /* min & max values for Sint8 */
    398    const Sint64 maxValue = SCHAR_MAX;
    399    const Sint64 minValue = SCHAR_MIN;
    400    return (Sint8)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
    401                (Sint64) boundary1, (Sint64) boundary2,
    402                validDomain);
    403}
    404
    405Sint16
    406SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
    407{
    408    /* min & max values for Sint16 */
    409    const Sint64 maxValue = SHRT_MAX;
    410    const Sint64 minValue = SHRT_MIN;
    411    return (Sint16)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
    412                (Sint64) boundary1, (Sint64) boundary2,
    413                validDomain);
    414}
    415
    416Sint32
    417SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
    418{
    419    /* min & max values for Sint32 */
    420    #if ((ULONG_MAX) == (UINT_MAX))
    421      const Sint64 maxValue = LONG_MAX;
    422      const Sint64 minValue = LONG_MIN;
    423        #else
    424      const Sint64 maxValue = INT_MAX;
    425      const Sint64 minValue = INT_MIN;
    426        #endif
    427    return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
    428                (Sint64) boundary1, (Sint64) boundary2,
    429                validDomain);
    430}
    431
    432Sint64
    433SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
    434{
    435    /* min & max values for Sint64 */
    436    const Sint64 maxValue = LLONG_MAX;
    437    const Sint64 minValue = LLONG_MIN;
    438    return SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
    439                boundary1, boundary2,
    440                validDomain);
    441}
    442
    443float
    444SDLTest_RandomUnitFloat()
    445{
    446    return (float) SDLTest_RandomUint32() / UINT_MAX;
    447}
    448
    449float
    450SDLTest_RandomFloat()
    451{
    452        return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
    453}
    454
    455double
    456SDLTest_RandomUnitDouble()
    457{
    458    return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
    459}
    460
    461double
    462SDLTest_RandomDouble()
    463{
    464    double r = 0.0;
    465    double s = 1.0;
    466    do {
    467      s /= UINT_MAX + 1.0;
    468      r += (double)SDLTest_RandomInt(&rndContext) * s;
    469    } while (s > DBL_EPSILON);
    470
    471    fuzzerInvocationCounter++;
    472
    473    return r;
    474}
    475
    476
    477char *
    478SDLTest_RandomAsciiString()
    479{
    480    return SDLTest_RandomAsciiStringWithMaximumLength(255);
    481}
    482
    483char *
    484SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
    485{
    486    int size;
    487
    488    if(maxLength < 1) {
    489                SDL_InvalidParamError("maxLength");
    490        return NULL;
    491    }
    492
    493    size = (SDLTest_RandomUint32() % (maxLength + 1));
    494
    495    return SDLTest_RandomAsciiStringOfSize(size);
    496}
    497
    498char *
    499SDLTest_RandomAsciiStringOfSize(int size)
    500{
    501    char *string;
    502    int counter;
    503
    504
    505    if(size < 1) {
    506                SDL_InvalidParamError("size");
    507        return NULL;
    508    }
    509
    510    string = (char *)SDL_malloc((size + 1) * sizeof(char));
    511    if (string==NULL) {
    512      return NULL;
    513        }
    514
    515    for(counter = 0; counter < size; ++counter) {
    516        string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
    517    }
    518
    519    string[counter] = '\0';
    520
    521    fuzzerInvocationCounter++;
    522
    523    return string;
    524}