Add fuzzer to test lib
authorAndreas Schiffler <aschiffler@ferzkopp.net>
Tue, 27 Nov 2012 21:40:46 -0800
changeset 6711e6355923901d
parent 6710 e650705e2c1d
child 6712 05f046f5886b
Add fuzzer to test lib
include/SDL_test.h
include/SDL_test_fuzzer.h
include/SDL_test_random.h
src/test/SDL_test_fuzzer.c
     1.1 --- a/include/SDL_test.h	Tue Nov 27 09:19:09 2012 -0800
     1.2 +++ b/include/SDL_test.h	Tue Nov 27 21:40:46 2012 -0800
     1.3 @@ -33,6 +33,7 @@
     1.4  #include "SDL.h"
     1.5  #include "SDL_test_font.h"
     1.6  #include "SDL_test_random.h"
     1.7 +#include "SDL_test_fuzzer.h"
     1.8  
     1.9  #include "begin_code.h"
    1.10  /* Set up for C function definitions, even when using C++ */
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/include/SDL_test_fuzzer.h	Tue Nov 27 21:40:46 2012 -0800
     2.3 @@ -0,0 +1,371 @@
     2.4 +/*
     2.5 +  Simple DirectMedia Layer
     2.6 +  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     2.7 +
     2.8 +  This software is provided 'as-is', without any express or implied
     2.9 +  warranty.  In no event will the authors be held liable for any damages
    2.10 +  arising from the use of this software.
    2.11 +
    2.12 +  Permission is granted to anyone to use this software for any purpose,
    2.13 +  including commercial applications, and to alter it and redistribute it
    2.14 +  freely, subject to the following restrictions:
    2.15 +
    2.16 +  1. The origin of this software must not be misrepresented; you must not
    2.17 +     claim that you wrote the original software. If you use this software
    2.18 +     in a product, an acknowledgment in the product documentation would be
    2.19 +     appreciated but is not required.
    2.20 +  2. Altered source versions must be plainly marked as such, and must not be
    2.21 +     misrepresented as being the original software.
    2.22 +  3. This notice may not be removed or altered from any source distribution.
    2.23 +*/
    2.24 +
    2.25 +/**
    2.26 + *  \file SDL_test_fuzzer.h
    2.27 + *  
    2.28 + *  Include file for SDL test framework.
    2.29 + *
    2.30 + *  This code is a part of the SDL2_test library, not the main SDL library.
    2.31 + */
    2.32 +
    2.33 +/* 
    2.34 +
    2.35 +  Data generators for fuzzing test data in a reproducible way.
    2.36 + 
    2.37 +*/
    2.38 +
    2.39 +#ifndef _SDL_test_fuzzer_h
    2.40 +#define _SDL_test_fuzzer_h
    2.41 +
    2.42 +#include "begin_code.h"
    2.43 +/* Set up for C function definitions, even when using C++ */
    2.44 +#ifdef __cplusplus
    2.45 +/* *INDENT-OFF* */
    2.46 +extern "C" {
    2.47 +/* *INDENT-ON* */
    2.48 +#endif
    2.49 +
    2.50 +
    2.51 +/*
    2.52 +  Based on GSOC code by Markus Kauppila <markus.kauppila@gmail.com>
    2.53 +*/
    2.54 +
    2.55 +
    2.56 +/**
    2.57 + * \file
    2.58 + * Note: The fuzzer implementation uses a static instance of random context
    2.59 + * internally which makes it thread-UNsafe.
    2.60 + */
    2.61 +
    2.62 +/**
    2.63 + * Initializes the fuzzer for a test
    2.64 + *
    2.65 + * /param execKey Execution "Key" that initializes the random number generator uniquely for the test.
    2.66 + *
    2.67 + */
    2.68 +void SDLTest_FuzzerInit(Uint64 execKey);
    2.69 +
    2.70 +
    2.71 +/**
    2.72 + * Returns a random Uint8
    2.73 + *
    2.74 + * \returns Generated integer
    2.75 + */
    2.76 +Uint8 SDLTest_RandomUint8();
    2.77 +
    2.78 +/**
    2.79 + * Returns a random Sint8
    2.80 + *
    2.81 + * \returns Generated signed integer
    2.82 + */
    2.83 +Sint8 SDLTest_RandomSint8();
    2.84 +
    2.85 +
    2.86 +/**
    2.87 + * Returns a random Uint16
    2.88 + *
    2.89 + * \returns Generated integer
    2.90 + */
    2.91 +Uint16 SDLTest_RandomUint16();
    2.92 +
    2.93 +/**
    2.94 + * Returns a random Sint16
    2.95 + *
    2.96 + * \returns Generated signed integer
    2.97 + */
    2.98 +Sint16 SDLTest_RandomSint16();
    2.99 +
   2.100 +
   2.101 +/**
   2.102 + * Returns a random integer
   2.103 + *
   2.104 + * \returns Generated integer
   2.105 + */
   2.106 +Sint32 SDLTest_RandomSint32();
   2.107 +
   2.108 +
   2.109 +/**
   2.110 + * Returns a random positive integer
   2.111 + *
   2.112 + * \returns Generated integer
   2.113 + */
   2.114 +Uint32 SDLTest_RandomUint32();
   2.115 +
   2.116 +/**
   2.117 + * Returns random Uint64.
   2.118 + *
   2.119 + * \returns Generated integer
   2.120 + */
   2.121 +Uint64 SDLTest_RandomUint64();
   2.122 +
   2.123 +
   2.124 +/**
   2.125 + * Returns random Sint64.
   2.126 + *
   2.127 + * \returns Generated signed integer
   2.128 + */
   2.129 +Sint64 SDLTest_RandomSint64();
   2.130 +
   2.131 +/**
   2.132 + * \returns random float in range [0.0 - 1.0[
   2.133 + */
   2.134 +float SDLTest_RandomUnitFloat();
   2.135 +
   2.136 +/**
   2.137 + * \returns random double in range [0.0 - 1.0[ 
   2.138 + */
   2.139 +double SDLTest_RandomUnitDouble();
   2.140 +
   2.141 +/**
   2.142 + * \returns random float.
   2.143 + *
   2.144 + */
   2.145 +float SDLTest_RandomFloat();
   2.146 +
   2.147 +/**
   2.148 + * \returns random double.
   2.149 + *
   2.150 + */
   2.151 +double SDLTest_RandomDouble();
   2.152 +
   2.153 +/**
   2.154 + * Returns a random boundary value for Uint8 within the given boundaries.
   2.155 + * Boundaries are inclusive, see the usage examples below. If validDomain
   2.156 + * is true, the function will only return valid boundaries, otherwise non-valid
   2.157 + * boundaries are also possible.
   2.158 + * If boundary1 > boundary2, the values are swapped
   2.159 + *
   2.160 + * Usage examples:
   2.161 + * RandomUint8BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20
   2.162 + * RandomUint8BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21
   2.163 + * RandomUint8BoundaryValue(0, 99, SDL_FALSE) returns 100
   2.164 + * RandomUint8BoundaryValue(0, 255, SDL_FALSE) returns -1 (== error value)
   2.165 + *
   2.166 + * \param boundary1 Lower boundary limit
   2.167 + * \param boundary2 Upper boundary limit
   2.168 + * \param validDomain Should the generated boundary be valid or not?
   2.169 + *
   2.170 + * \returns Boundary value in given range or error value (-1)
   2.171 + */
   2.172 +Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain);
   2.173 +
   2.174 +/**
   2.175 + * Returns a random boundary value for Uint16 within the given boundaries.
   2.176 + * Boundaries are inclusive, see the usage examples below. If validDomain
   2.177 + * is true, the function will only return valid boundaries, otherwise non-valid
   2.178 + * boundaries are also possible.
   2.179 + * If boundary1 > boundary2, the values are swapped
   2.180 + *
   2.181 + * Usage examples:
   2.182 + * RandomUint16BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20
   2.183 + * RandomUint16BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21
   2.184 + * RandomUint16BoundaryValue(0, 99, SDL_FALSE) returns 100
   2.185 + * RandomUint16BoundaryValue(0, 0xFFFF, SDL_FALSE) returns -1 (== error value)
   2.186 + *
   2.187 + * \param boundary1 Lower boundary limit
   2.188 + * \param boundary2 Upper boundary limit
   2.189 + * \param validDomain Should the generated boundary be valid or not?
   2.190 + *
   2.191 + * \returns Boundary value in given range or error value (-1)
   2.192 + */
   2.193 +Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain);
   2.194 +
   2.195 +/**
   2.196 + * Returns a random boundary value for Uint32 within the given boundaries.
   2.197 + * Boundaries are inclusive, see the usage examples below. If validDomain
   2.198 + * is true, the function will only return valid boundaries, otherwise non-valid
   2.199 + * boundaries are also possible.
   2.200 + * If boundary1 > boundary2, the values are swapped
   2.201 + *
   2.202 + * Usage examples:
   2.203 + * RandomUint32BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20
   2.204 + * RandomUint32BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21
   2.205 + * RandomUint32BoundaryValue(0, 99, SDL_FALSE) returns 100
   2.206 + * RandomUint32BoundaryValue(0, 0xFFFFFFFF, SDL_FALSE) returns -1 (== error value)
   2.207 + *
   2.208 + * \param boundary1 Lower boundary limit
   2.209 + * \param boundary2 Upper boundary limit
   2.210 + * \param validDomain Should the generated boundary be valid or not?
   2.211 + *
   2.212 + * \returns Boundary value in given range or error value (-1)
   2.213 + */
   2.214 +Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain);
   2.215 +
   2.216 +/**
   2.217 + * Returns a random boundary value for Uint64 within the given boundaries.
   2.218 + * Boundaries are inclusive, see the usage examples below. If validDomain
   2.219 + * is true, the function will only return valid boundaries, otherwise non-valid
   2.220 + * boundaries are also possible.
   2.221 + * If boundary1 > boundary2, the values are swapped
   2.222 + *
   2.223 + * Usage examples:
   2.224 + * RandomUint64BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20
   2.225 + * RandomUint64BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21
   2.226 + * RandomUint64BoundaryValue(0, 99, SDL_FALSE) returns 100
   2.227 + * RandomUint64BoundaryValue(0, 0xFFFFFFFFFFFFFFFF, SDL_FALSE) returns -1 (== error value)
   2.228 + *
   2.229 + * \param boundary1 Lower boundary limit
   2.230 + * \param boundary2 Upper boundary limit
   2.231 + * \param validDomain Should the generated boundary be valid or not?
   2.232 + *
   2.233 + * \returns Boundary value in given range or error value (-1)
   2.234 + */
   2.235 +Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain);
   2.236 +
   2.237 +/**
   2.238 + * Returns a random boundary value for Sint8 within the given boundaries.
   2.239 + * Boundaries are inclusive, see the usage examples below. If validDomain
   2.240 + * is true, the function will only return valid boundaries, otherwise non-valid
   2.241 + * boundaries are also possible.
   2.242 + * If boundary1 > boundary2, the values are swapped
   2.243 + *
   2.244 + * Usage examples:
   2.245 + * RandomSint8BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20
   2.246 + * RandomSint8BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9
   2.247 + * RandomSint8BoundaryValue(-128, 99, SDL_FALSE) returns 100
   2.248 + * RandomSint8BoundaryValue(-128, 127, SDL_FALSE) returns SINT8_MIN (== error value)
   2.249 + *
   2.250 + * \param boundary1 Lower boundary limit
   2.251 + * \param boundary2 Upper boundary limit
   2.252 + * \param validDomain Should the generated boundary be valid or not?
   2.253 + *
   2.254 + * \returns Boundary value in given range or error value (-1)
   2.255 + */
   2.256 +Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain);
   2.257 +
   2.258 +
   2.259 +/**
   2.260 + * Returns a random boundary value for Sint16 within the given boundaries.
   2.261 + * Boundaries are inclusive, see the usage examples below. If validDomain
   2.262 + * is true, the function will only return valid boundaries, otherwise non-valid
   2.263 + * boundaries are also possible.
   2.264 + * If boundary1 > boundary2, the values are swapped
   2.265 + *
   2.266 + * Usage examples:
   2.267 + * RandomSint16BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20
   2.268 + * RandomSint16BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9
   2.269 + * RandomSint16BoundaryValue(SINT8_MIN, 99, SDL_FALSE) returns 100
   2.270 + * RandomSint16BoundaryValue(SINT8_MIN, SINT8_MAX, SDL_FALSE) returns SINT16_MIN (== error value)
   2.271 + *
   2.272 + * \param boundary1 Lower boundary limit
   2.273 + * \param boundary2 Upper boundary limit
   2.274 + * \param validDomain Should the generated boundary be valid or not?
   2.275 + *
   2.276 + * \returns Boundary value in given range or error value (-1)
   2.277 + */
   2.278 +Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain);
   2.279 +
   2.280 +/**
   2.281 + * Returns a random boundary value for Sint32 within the given boundaries.
   2.282 + * Boundaries are inclusive, see the usage examples below. If validDomain
   2.283 + * is true, the function will only return valid boundaries, otherwise non-valid
   2.284 + * boundaries are also possible.
   2.285 + * If boundary1 > boundary2, the values are swapped
   2.286 + *
   2.287 + * Usage examples:
   2.288 + * RandomSint32BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20
   2.289 + * RandomSint32BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9
   2.290 + * RandomSint32BoundaryValue(SINT32_MIN, 99, SDL_FALSE) returns 100
   2.291 + * RandomSint32BoundaryValue(SINT32_MIN, SINT32_MAX, SDL_FALSE) returns SINT32_MIN (== error value)
   2.292 + *
   2.293 + * \param boundary1 Lower boundary limit
   2.294 + * \param boundary2 Upper boundary limit
   2.295 + * \param validDomain Should the generated boundary be valid or not?
   2.296 + *
   2.297 + * \returns Boundary value in given range or error value (-1)
   2.298 + */
   2.299 +Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain);
   2.300 +
   2.301 +/**
   2.302 + * Returns a random boundary value for Sint64 within the given boundaries.
   2.303 + * Boundaries are inclusive, see the usage examples below. If validDomain
   2.304 + * is true, the function will only return valid boundaries, otherwise non-valid
   2.305 + * boundaries are also possible.
   2.306 + * If boundary1 > boundary2, the values are swapped
   2.307 + *
   2.308 + * Usage examples:
   2.309 + * RandomSint64BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20
   2.310 + * RandomSint64BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9
   2.311 + * RandomSint64BoundaryValue(SINT64_MIN, 99, SDL_FALSE) returns 100
   2.312 + * RandomSint64BoundaryValue(SINT64_MIN, SINT32_MAX, SDL_FALSE) returns SINT64_MIN (== error value)
   2.313 + *
   2.314 + * \param boundary1 Lower boundary limit
   2.315 + * \param boundary2 Upper boundary limit
   2.316 + * \param validDomain Should the generated boundary be valid or not?
   2.317 + *
   2.318 + * \returns Boundary value in given range or error value (-1)
   2.319 + */
   2.320 +Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain);
   2.321 +
   2.322 +
   2.323 +/**
   2.324 + * Returns integer in range [min, max] (inclusive).
   2.325 + * Min and max values can be negative values.
   2.326 + * If Max in smaller tham min, then the values are swapped.
   2.327 + * Min and max are the same value, that value will be returned.
   2.328 + *
   2.329 + * \returns Generated integer
   2.330 + */
   2.331 +Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max);
   2.332 +
   2.333 +
   2.334 +/**
   2.335 + * Generates random null-terminated string. The maximum length for
   2.336 + * the string is 255 characters and it can contain ASCII characters
   2.337 + * from 1 to 127.
   2.338 + *
   2.339 + * Note: Returned string needs to be deallocated.
   2.340 + *
   2.341 + * \returns newly allocated random string
   2.342 + */
   2.343 +char * SDLTest_RandomAsciiString();
   2.344 +
   2.345 +
   2.346 +/**
   2.347 + * Generates random null-terminated string. The maximum length for
   2.348 + * the string is defined by maxLenght parameter.
   2.349 + * String can contain ASCII characters from 1 to 127.
   2.350 + *
   2.351 + * Note: Returned string needs to be deallocated.
   2.352 + *
   2.353 + * \param maxLength Maximum length of the generated string
   2.354 + *
   2.355 + * \returns newly allocated random string
   2.356 + */
   2.357 +char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength);
   2.358 +
   2.359 +/**
   2.360 + * Returns the invocation count for the fuzzer since last ...FuzzerInit.
   2.361 + */
   2.362 +int SDLTest_GetFuzzerInvocationCount();
   2.363 +
   2.364 +/* Ends C function definitions when using C++ */
   2.365 +#ifdef __cplusplus
   2.366 +/* *INDENT-OFF* */
   2.367 +}
   2.368 +/* *INDENT-ON* */
   2.369 +#endif
   2.370 +#include "close_code.h"
   2.371 +
   2.372 +#endif /* _SDL_test_fuzzer_h */
   2.373 +
   2.374 +/* vi: set ts=4 sw=4 expandtab: */
     3.1 --- a/include/SDL_test_random.h	Tue Nov 27 09:19:09 2012 -0800
     3.2 +++ b/include/SDL_test_random.h	Tue Nov 27 21:40:46 2012 -0800
     3.3 @@ -54,11 +54,9 @@
     3.4  /* ------- Definitions ------- */
     3.5  
     3.6  /*
     3.7 - * Macros that return random number in a specific format.
     3.8 - * Float values are in the range [0.0-1.0].
     3.9 + * Macros that return a random number in a specific format.
    3.10   */
    3.11 -#define SDL_TestRandomInt(c)		((int)SDL_TestRandom(c))
    3.12 -#define SDL_TestRandomFloat(c)		((double)SDL_TestRandom(c)/(unsigned long)0xffffffff)
    3.13 +#define SDLTest_RandomInt(c)		((int)SDLTest_Random(c))
    3.14  
    3.15  /*
    3.16   * Context structure for the random number generator state.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/test/SDL_test_fuzzer.c	Tue Nov 27 21:40:46 2012 -0800
     4.3 @@ -0,0 +1,637 @@
     4.4 +/*
     4.5 +  Simple DirectMedia Layer
     4.6 +  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     4.7 +
     4.8 +  This software is provided 'as-is', without any express or implied
     4.9 +  warranty.  In no event will the authors be held liable for any damages
    4.10 +  arising from the use of this software.
    4.11 +
    4.12 +  Permission is granted to anyone to use this software for any purpose,
    4.13 +  including commercial applications, and to alter it and redistribute it
    4.14 +  freely, subject to the following restrictions:
    4.15 +
    4.16 +  1. The origin of this software must not be misrepresented; you must not
    4.17 +     claim that you wrote the original software. If you use this software
    4.18 +     in a product, an acknowledgment in the product documentation would be
    4.19 +     appreciated but is not required.
    4.20 +  2. Altered source versions must be plainly marked as such, and must not be
    4.21 +     misrepresented as being the original software.
    4.22 +  3. This notice may not be removed or altered from any source distribution.
    4.23 +*/
    4.24 +
    4.25 +/* 
    4.26 +
    4.27 +  Data generators for fuzzing test data in a reproducible way.
    4.28 + 
    4.29 +*/
    4.30 +
    4.31 +#include "SDL_config.h"
    4.32 +
    4.33 +#include <stdint.h>
    4.34 +#include <stdio.h>
    4.35 +#include <stdlib.h>
    4.36 +#include <limits.h>
    4.37 +#include <float.h>
    4.38 +
    4.39 +#include "SDL_test.h"
    4.40 +
    4.41 +/** 
    4.42 + *Counter for fuzzer invocations
    4.43 + */
    4.44 +static int fuzzerInvocationCounter;
    4.45 +
    4.46 +/**
    4.47 + * Context for shared random number generator
    4.48 + */
    4.49 +static SDLTest_RandomContext rndContext;
    4.50 +
    4.51 +/*
    4.52 + * Note: doxygen documentation markup for functions is in the header file.
    4.53 + */
    4.54 +
    4.55 +void
    4.56 +SDLTest_FuzzerInit(Uint64 execKey)
    4.57 +{
    4.58 +	Uint32 a = (execKey >> 32)  & 0x00000000FFFFFFFF;
    4.59 +	Uint32 b = execKey & 0x00000000FFFFFFFF;
    4.60 +	SDLTest_RandomInit(&rndContext, a, b);
    4.61 +}
    4.62 +
    4.63 +int
    4.64 +SDLTest_GetInvocationCount()
    4.65 +{
    4.66 +	return fuzzerInvocationCounter;
    4.67 +}
    4.68 +
    4.69 +Uint8
    4.70 +SDLTest_RandomUint8()
    4.71 +{
    4.72 +	fuzzerInvocationCounter++;
    4.73 +
    4.74 +	return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
    4.75 +}
    4.76 +
    4.77 +Sint8
    4.78 +SDLTest_RandomSint8()
    4.79 +{
    4.80 +	fuzzerInvocationCounter++;
    4.81 +
    4.82 +	return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
    4.83 +}
    4.84 +
    4.85 +Uint16
    4.86 +SDLTest_RandomUint16()
    4.87 +{
    4.88 +	fuzzerInvocationCounter++;
    4.89 +
    4.90 +	return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
    4.91 +}
    4.92 +
    4.93 +Sint16
    4.94 +SDLTest_RandomSint16()
    4.95 +{
    4.96 +	fuzzerInvocationCounter++;
    4.97 +
    4.98 +	return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
    4.99 +}
   4.100 +
   4.101 +Sint32
   4.102 +SDLTest_RandomSint32()
   4.103 +{
   4.104 +	fuzzerInvocationCounter++;
   4.105 +
   4.106 +	return (Sint32) SDLTest_RandomInt(&rndContext);
   4.107 +}
   4.108 +
   4.109 +Uint32
   4.110 +SDLTest_RandomUint32()
   4.111 +{
   4.112 +	fuzzerInvocationCounter++;
   4.113 +
   4.114 +	return (Uint32) SDLTest_RandomInt(&rndContext);
   4.115 +}
   4.116 +
   4.117 +Uint64
   4.118 +SDLTest_RandomUint64()
   4.119 +{
   4.120 +	Uint64 value;
   4.121 +	Uint32 *vp = (void*)&value;
   4.122 +
   4.123 +	fuzzerInvocationCounter++;
   4.124 +
   4.125 +	vp[0] = SDLTest_RandomSint32();
   4.126 +	vp[1] = SDLTest_RandomSint32();
   4.127 +
   4.128 +	return value;
   4.129 +}
   4.130 +
   4.131 +Sint64
   4.132 +SDLTest_RandomSint64()
   4.133 +{
   4.134 +	Uint64 value;
   4.135 +	Uint32 *vp = (void*)&value;
   4.136 +
   4.137 +	fuzzerInvocationCounter++;
   4.138 +
   4.139 +	vp[0] = SDLTest_RandomSint32();
   4.140 +	vp[1] = SDLTest_RandomSint32();
   4.141 +
   4.142 +	return value;
   4.143 +}
   4.144 +
   4.145 +
   4.146 +
   4.147 +Sint32
   4.148 +SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
   4.149 +{
   4.150 +	Sint64 min = pMin;
   4.151 +	Sint64 max = pMax;
   4.152 +	Sint64 temp;
   4.153 +	Sint64 number;
   4.154 +
   4.155 +	if(pMin > pMax) {
   4.156 +		temp = min;
   4.157 +		min = max;
   4.158 +		max = temp;
   4.159 +	} else if(pMin == pMax) {
   4.160 +		return (Sint32)min;
   4.161 +	}
   4.162 +
   4.163 +	number = SDLTest_RandomUint32(); // invocation count increment in there
   4.164 +
   4.165 +	return (Sint32)((number % ((max + 1) - min)) + min);
   4.166 +}
   4.167 +
   4.168 +/*!
   4.169 + * Generates boundary values between the given boundaries.
   4.170 + * Boundary values are inclusive. See the examples below.
   4.171 + * If boundary2 < boundary1, the values are swapped.
   4.172 + * If boundary1 == boundary2, value of boundary1 will be returned
   4.173 + *
   4.174 + * Generating boundary values for Uint8:
   4.175 + * BoundaryValues(sizeof(Uint8), 10, 20, True) -> [10,11,19,20]
   4.176 + * BoundaryValues(sizeof(Uint8), 10, 20, False) -> [9,21]
   4.177 + * BoundaryValues(sizeof(Uint8), 0, 15, True) -> [0, 1, 14, 15]
   4.178 + * BoundaryValues(sizeof(Uint8), 0, 15, False) -> [16]
   4.179 + * BoundaryValues(sizeof(Uint8), 0, 255, False) -> NULL
   4.180 + *
   4.181 + * Generator works the same for other types of unsigned integers.
   4.182 + *
   4.183 + * Note: outBuffer will be allocated and needs to be freed later.
   4.184 + * If outbuffer != NULL, it'll be freed.
   4.185 + *
   4.186 + * \param maxValue The biggest value that is acceptable for this data type.
   4.187 + * 					For instance, for Uint8 -> 255, Uint16 -> 65536 etc.
   4.188 + * \param pBoundary1 defines lower boundary
   4.189 + * \param pBoundary2 defines upper boundary
   4.190 + * \param validDomain Generate only for valid domain (for the data type)
   4.191 + *
   4.192 + * \param outBuffer The generated boundary values are put here
   4.193 + *
   4.194 + * \returns Returns the number of elements in outBuffer or -1 in case of error
   4.195 + */
   4.196 +Uint32
   4.197 +SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue,
   4.198 +					Uint64 pBoundary1, Uint64 pBoundary2, SDL_bool validDomain,
   4.199 +					Uint64 *outBuffer)
   4.200 +{
   4.201 +	Uint64 boundary1 = pBoundary1, boundary2 = pBoundary2;
   4.202 +	Uint64 temp;
   4.203 +	Uint64 tempBuf[4];
   4.204 +	int index;
   4.205 +
   4.206 +	if(outBuffer != NULL) {
   4.207 +		SDL_free(outBuffer);
   4.208 +	}
   4.209 +
   4.210 +	if(boundary1 > boundary2) {
   4.211 +		temp = boundary1;
   4.212 +		boundary1 = boundary2;
   4.213 +		boundary2 = temp;
   4.214 +	}
   4.215 +
   4.216 +	index = 0;
   4.217 +	if(boundary1 == boundary2) {
   4.218 +		tempBuf[index++] = boundary1;
   4.219 +	}
   4.220 +	else if(validDomain) {
   4.221 +		tempBuf[index++] = boundary1;
   4.222 +
   4.223 +		if(boundary1 < UINT64_MAX)
   4.224 +			tempBuf[index++] = boundary1 + 1;
   4.225 +
   4.226 +		tempBuf[index++] = boundary2 - 1;
   4.227 +		tempBuf[index++] = boundary2;
   4.228 +	}
   4.229 +	else {
   4.230 +		if(boundary1 > 0) {
   4.231 +			tempBuf[index++] = boundary1 - 1;
   4.232 +		}
   4.233 +
   4.234 +		if(boundary2 < maxValue && boundary2 < UINT64_MAX) {
   4.235 +			tempBuf[index++] = boundary2 + 1;
   4.236 +		}
   4.237 +	}
   4.238 +
   4.239 +	if(index == 0) {
   4.240 +		// There are no valid boundaries
   4.241 +		return 0;
   4.242 +	}
   4.243 +
   4.244 +	// Create the return buffer
   4.245 +	outBuffer = (Uint64 *)SDL_malloc(index * sizeof(Uint64));
   4.246 +	if(outBuffer == NULL) {
   4.247 +		return 0;
   4.248 +	}
   4.249 +
   4.250 +	SDL_memcpy(outBuffer, tempBuf, index * sizeof(Uint64));
   4.251 +
   4.252 +	return index;
   4.253 +}
   4.254 +
   4.255 +Uint8
   4.256 +SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
   4.257 +{
   4.258 +	Uint64 *buffer = NULL;
   4.259 +	Uint32 size;
   4.260 +	Uint32 index;
   4.261 +	Uint8 retVal;
   4.262 +
   4.263 +	// max value for Uint8
   4.264 +	const Uint64 maxValue = UINT8_MAX;
   4.265 +
   4.266 +	size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
   4.267 +				(Uint64) boundary1, (Uint64) boundary2,
   4.268 +				validDomain, buffer);
   4.269 +	if (size == 0) {
   4.270 +		return 0;
   4.271 +	}
   4.272 +
   4.273 +	index = SDLTest_RandomSint32() % size;
   4.274 +	retVal = (Uint8)buffer[index];
   4.275 +
   4.276 +	SDL_free(buffer);
   4.277 +
   4.278 +	fuzzerInvocationCounter++;
   4.279 +
   4.280 +	return retVal;
   4.281 +}
   4.282 +
   4.283 +Uint16
   4.284 +SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
   4.285 +{
   4.286 +	Uint64 *buffer = NULL;
   4.287 +	Uint32 size;
   4.288 +	Uint32 index;
   4.289 +	Uint16 retVal;
   4.290 +
   4.291 +	// max value for Uint16
   4.292 +	const Uint64 maxValue = UINT16_MAX;
   4.293 +
   4.294 +	size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
   4.295 +				(Uint64) boundary1, (Uint64) boundary2,
   4.296 +				validDomain, buffer);
   4.297 +	if(size == 0) {
   4.298 +		return 0;
   4.299 +	}
   4.300 +
   4.301 +	index = SDLTest_RandomSint32() % size;
   4.302 +	retVal = (Uint16) buffer[index];
   4.303 +
   4.304 +	SDL_free(buffer);
   4.305 +
   4.306 +	fuzzerInvocationCounter++;
   4.307 +
   4.308 +	return retVal;
   4.309 +}
   4.310 +
   4.311 +Uint32
   4.312 +SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
   4.313 +{
   4.314 +	Uint64 *buffer = NULL;
   4.315 +	Uint32 size;
   4.316 +	Uint32 index;
   4.317 +	Uint32 retVal;
   4.318 +
   4.319 +	// max value for Uint32
   4.320 +	const Uint64 maxValue = UINT32_MAX;
   4.321 +
   4.322 +	size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
   4.323 +				(Uint64) boundary1, (Uint64) boundary2,
   4.324 +				validDomain, buffer);
   4.325 +	if(size == 0) {
   4.326 +		return 0;
   4.327 +	}
   4.328 +
   4.329 +	index = SDLTest_RandomSint32() % size;
   4.330 +	retVal = (Uint32) buffer[index];
   4.331 +
   4.332 +	SDL_free(buffer);
   4.333 +
   4.334 +	fuzzerInvocationCounter++;
   4.335 +
   4.336 +	return retVal;
   4.337 +}
   4.338 +
   4.339 +Uint64
   4.340 +SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
   4.341 +{
   4.342 +	Uint64 *buffer = NULL;
   4.343 +	Uint32 size;
   4.344 +	Uint32 index;
   4.345 +	Uint64 retVal;
   4.346 +
   4.347 +	// max value for Uint64
   4.348 +	const Uint64 maxValue = UINT64_MAX;
   4.349 +
   4.350 +	size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
   4.351 +				(Uint64) boundary1, (Uint64) boundary2,
   4.352 +				validDomain, buffer);
   4.353 +	if(size == 0) {
   4.354 +		return 0;
   4.355 +	}
   4.356 +
   4.357 +	index = SDLTest_RandomSint32() % size;
   4.358 +	retVal = (Uint64) buffer[index];
   4.359 +
   4.360 +	SDL_free(buffer);
   4.361 +
   4.362 +	fuzzerInvocationCounter++;
   4.363 +
   4.364 +	return retVal;
   4.365 +}
   4.366 +
   4.367 +/*!
   4.368 + * Generates boundary values between the given boundaries.
   4.369 + * Boundary values are inclusive. See the examples below.
   4.370 + * If boundary2 < boundary1, the values are swapped.
   4.371 + * If boundary1 == boundary2, value of boundary1 will be returned
   4.372 + *
   4.373 + * Generating boundary values for Sint8:
   4.374 + * SignedBoundaryValues(sizeof(Sint8), -10, 20, True) -> [-11,-10,19,20]
   4.375 + * SignedBoundaryValues(sizeof(Sint8), -10, 20, False) -> [-11,21]
   4.376 + * SignedBoundaryValues(sizeof(Sint8), -30, -15, True) -> [-30, -29, -16, -15]
   4.377 + * SignedBoundaryValues(sizeof(Sint8), -128, 15, False) -> [16]
   4.378 + * SignedBoundaryValues(sizeof(Sint8), -128, 127, False) -> NULL
   4.379 + *
   4.380 + * Generator works the same for other types of signed integers.
   4.381 + *
   4.382 + * Note: outBuffer will be allocated and needs to be freed later.
   4.383 + * If outbuffer != NULL, it'll be freed.
   4.384 + *
   4.385 + *
   4.386 + * \param minValue The smallest value  that is acceptable for this data type.
   4.387 + *					For instance, for Uint8 -> -128, Uint16 -> -32,768 etc.
   4.388 + * \param maxValue The biggest value that is acceptable for this data type.
   4.389 + * 					For instance, for Uint8 -> 127, Uint16 -> 32767 etc.
   4.390 + * \param pBoundary1 defines lower boundary
   4.391 + * \param pBoundary2 defines upper boundary
   4.392 + * \param validDomain Generate only for valid domain (for the data type)
   4.393 + *
   4.394 + * \param outBuffer The generated boundary values are put here
   4.395 + *
   4.396 + * \returns Returns the number of elements in outBuffer or -1 in case of error
   4.397 + */
   4.398 +Uint32
   4.399 +SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue,
   4.400 +					Sint64 pBoundary1, Sint64 pBoundary2, SDL_bool validDomain,
   4.401 +					Sint64 *outBuffer)
   4.402 +{
   4.403 +	int index;
   4.404 +	Sint64 tempBuf[4];
   4.405 +	Sint64 boundary1 = pBoundary1, boundary2 = pBoundary2;
   4.406 +
   4.407 +	if(outBuffer != NULL) {
   4.408 +		SDL_free(outBuffer);
   4.409 +	}
   4.410 +
   4.411 +	if(boundary1 > boundary2) {
   4.412 +		Sint64 temp = boundary1;
   4.413 +		boundary1 = boundary2;
   4.414 +		boundary2 = temp;
   4.415 +	}
   4.416 +
   4.417 +	index = 0;
   4.418 +	if(boundary1 == boundary2) {
   4.419 +		tempBuf[index++] = boundary1;
   4.420 +	}
   4.421 +	else if(validDomain) {
   4.422 +		tempBuf[index++] = boundary1;
   4.423 +
   4.424 +		if(boundary1 < LLONG_MAX)
   4.425 +			tempBuf[index++] = boundary1 + 1;
   4.426 +
   4.427 +		if(boundary2 > LLONG_MIN)
   4.428 +			tempBuf[index++] = boundary2 - 1;
   4.429 +
   4.430 +		tempBuf[index++] = boundary2;
   4.431 +	}
   4.432 +	else {
   4.433 +		if(boundary1 > minValue &&  boundary1 > LLONG_MIN) {
   4.434 +			tempBuf[index++] = boundary1 - 1;
   4.435 +		}
   4.436 +
   4.437 +		if(boundary2 < maxValue && boundary2 < UINT64_MAX) {
   4.438 +			tempBuf[index++] = boundary2 + 1;
   4.439 +		}
   4.440 +	}
   4.441 +
   4.442 +	if(index == 0) {
   4.443 +		// There are no valid boundaries
   4.444 +		return 0;
   4.445 +	}
   4.446 +
   4.447 +	// Create the return buffer
   4.448 +	outBuffer = (Sint64 *)SDL_malloc(index * sizeof(Sint64));
   4.449 +	if(outBuffer == NULL) {
   4.450 +		return 0;
   4.451 +	}
   4.452 +
   4.453 +	SDL_memcpy((void *)outBuffer, (void *)tempBuf, index * sizeof(Sint64));
   4.454 +
   4.455 +	return (Uint32)index;
   4.456 +}
   4.457 +
   4.458 +Sint8
   4.459 +SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
   4.460 +{
   4.461 +	// min & max values for Sint8
   4.462 +	const Sint64 maxValue = CHAR_MAX;
   4.463 +	const Sint64 minValue = CHAR_MIN;
   4.464 +
   4.465 +	Sint64 *buffer = NULL;
   4.466 +	Uint32 size;
   4.467 +	Uint32 index;
   4.468 +	Sint8 retVal;
   4.469 +
   4.470 +	size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
   4.471 +				(Sint64) boundary1, (Sint64) boundary2,
   4.472 +				validDomain, buffer);
   4.473 +	if(size == 0) {
   4.474 +		return CHAR_MIN;
   4.475 +	}
   4.476 +
   4.477 +	index = SDLTest_RandomSint32() % size;
   4.478 +	retVal = (Sint8) buffer[index];
   4.479 +
   4.480 +	SDL_free(buffer);
   4.481 +
   4.482 +	fuzzerInvocationCounter++;
   4.483 +
   4.484 +	return retVal;
   4.485 +}
   4.486 +
   4.487 +Sint16
   4.488 +SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
   4.489 +{
   4.490 +	// min & max values for Sint16
   4.491 +	const Sint64 maxValue = SHRT_MAX;
   4.492 +	const Sint64 minValue = SHRT_MIN;
   4.493 +	Sint64 *buffer = NULL;
   4.494 +	Uint32 size;
   4.495 +	Uint32 index;
   4.496 +	Sint16 retVal;
   4.497 +
   4.498 +	size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
   4.499 +					(Sint64) boundary1, (Sint64) boundary2,
   4.500 +					validDomain, buffer);
   4.501 +	if(size == 0) {
   4.502 +		return SHRT_MIN;
   4.503 +	}
   4.504 +
   4.505 +	index = SDLTest_RandomSint32() % size;
   4.506 +	retVal = (Sint16) buffer[index];
   4.507 +
   4.508 +	SDL_free(buffer);
   4.509 +
   4.510 +	fuzzerInvocationCounter++;
   4.511 +
   4.512 +	return retVal;
   4.513 +}
   4.514 +
   4.515 +Sint32
   4.516 +SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
   4.517 +{
   4.518 +	// min & max values for Sint32
   4.519 +	const Sint64 maxValue = INT_MAX;
   4.520 +	const Sint64 minValue = INT_MIN;
   4.521 +
   4.522 +	Sint64 *buffer = NULL;
   4.523 +	Uint32 size;
   4.524 +	Uint32 index;
   4.525 +	Sint32 retVal;
   4.526 +
   4.527 +	size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
   4.528 +				(Sint64) boundary1, (Sint64) boundary2,
   4.529 +				validDomain, buffer);
   4.530 +	if(size == 0) {
   4.531 +		return INT_MIN;
   4.532 +	}
   4.533 +
   4.534 +	index = SDLTest_RandomSint32() % size;
   4.535 +	retVal = (Sint32) buffer[index];
   4.536 +
   4.537 +	SDL_free(buffer);
   4.538 +
   4.539 +	fuzzerInvocationCounter++;
   4.540 +
   4.541 +	return retVal;
   4.542 +}
   4.543 +
   4.544 +Sint64
   4.545 +SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
   4.546 +{
   4.547 +	Sint64 *buffer = NULL;
   4.548 +	Uint32 size;
   4.549 +	Uint32 index;
   4.550 +	Sint64 retVal;
   4.551 +
   4.552 +	// min & max values for Sint64
   4.553 +	const Sint64 maxValue = LLONG_MAX;
   4.554 +	const Sint64 minValue = LLONG_MIN;
   4.555 +
   4.556 +	size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
   4.557 +				(Sint64) boundary1, (Sint64) boundary2,
   4.558 +				validDomain, buffer);
   4.559 +	if(size == 0) {
   4.560 +		return LLONG_MIN;
   4.561 +	}
   4.562 +
   4.563 +	index = SDLTest_RandomSint32() % size;
   4.564 +	retVal = (Sint64) buffer[index];
   4.565 +
   4.566 +	SDL_free(buffer);
   4.567 +
   4.568 +	fuzzerInvocationCounter++;
   4.569 +
   4.570 +	return retVal;
   4.571 +}
   4.572 +
   4.573 +float
   4.574 +SDLTest_RandomUnitFloat()
   4.575 +{
   4.576 +	return (float) SDLTest_RandomUint32() / UINT_MAX;
   4.577 +}
   4.578 +
   4.579 +float
   4.580 +SDLTest_RandomFloat()
   4.581 +{
   4.582 +        return (float) (FLT_MIN + SDLTest_RandomUnitDouble() * (FLT_MAX - FLT_MIN));
   4.583 +}
   4.584 +
   4.585 +double
   4.586 +SDLTest_RandomUnitDouble()
   4.587 +{
   4.588 +	return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
   4.589 +}
   4.590 +
   4.591 +double
   4.592 +SDLTest_RandomDouble()
   4.593 +{
   4.594 +	double r = 0.0;
   4.595 +	double s = 1.0;
   4.596 +	do {
   4.597 +	  s /= UINT_MAX + 1.0;
   4.598 +	  r += (double)SDLTest_RandomInt(&rndContext) * s;
   4.599 +	} while (s > DBL_EPSILON);
   4.600 +	  
   4.601 +	fuzzerInvocationCounter++;
   4.602 +	
   4.603 +	return r;
   4.604 +}
   4.605 +
   4.606 +
   4.607 +char *
   4.608 +SDLTest_RandomAsciiString()
   4.609 +{
   4.610 +	// note: fuzzerInvocationCounter is increment in the RandomAsciiStringWithMaximumLenght
   4.611 +	return SDLTest_RandomAsciiStringWithMaximumLength(255);
   4.612 +}
   4.613 +
   4.614 +char *
   4.615 +SDLTest_RandomAsciiStringWithMaximumLength(int maxSize)
   4.616 +{
   4.617 +	int size;
   4.618 +	char *string;
   4.619 +	int counter;
   4.620 +
   4.621 +	fuzzerInvocationCounter++;
   4.622 +
   4.623 +	if(maxSize < 1) {
   4.624 +		return NULL;
   4.625 +	}
   4.626 +
   4.627 +	size = (SDLTest_RandomUint32() % (maxSize + 1)) + 1;
   4.628 +	string = (char *)SDL_malloc(size * sizeof(char));
   4.629 +	if (string==NULL) {
   4.630 +	  return NULL;
   4.631 +        }
   4.632 +
   4.633 +	for(counter = 0; counter < size; ++counter) {
   4.634 +		string[counter] = (char)SDLTest_RandomIntegerInRange(1, 127);
   4.635 +	}
   4.636 +
   4.637 +	string[counter] = '\0';
   4.638 +
   4.639 +	return string;
   4.640 +}