2 Simple DirectMedia Layer
3 Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
24 Data generators for fuzzing test data in a reproducible way.
28 #include "SDL_config.h"
31 /* Visual Studio 2008 doesn't have stdint.h */
32 #if defined(_MSC_VER) && _MSC_VER <= 1500
33 #define UINT8_MAX _UI8_MAX
34 #define UINT16_MAX _UI16_MAX
35 #define UINT32_MAX _UI32_MAX
36 #define INT64_MIN _I64_MIN
37 #define INT64_MAX _I64_MAX
38 #define UINT64_MAX _UI64_MAX
49 * Counter for fuzzer invocations
51 static int fuzzerInvocationCounter = 0;
54 * Context for shared random number generator
56 static SDLTest_RandomContext rndContext;
59 * Note: doxygen documentation markup for functions is in the header file.
63 SDLTest_FuzzerInit(Uint64 execKey)
65 Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF;
66 Uint32 b = execKey & 0x00000000FFFFFFFF;
67 SDL_memset((void *)&rndContext, 0, sizeof(SDLTest_RandomContext));
68 SDLTest_RandomInit(&rndContext, a, b);
69 fuzzerInvocationCounter = 0;
73 SDLTest_GetFuzzerInvocationCount()
75 return fuzzerInvocationCounter;
81 fuzzerInvocationCounter++;
83 return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
89 fuzzerInvocationCounter++;
91 return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
95 SDLTest_RandomUint16()
97 fuzzerInvocationCounter++;
99 return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
103 SDLTest_RandomSint16()
105 fuzzerInvocationCounter++;
107 return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
111 SDLTest_RandomSint32()
113 fuzzerInvocationCounter++;
115 return (Sint32) SDLTest_RandomInt(&rndContext);
119 SDLTest_RandomUint32()
121 fuzzerInvocationCounter++;
123 return (Uint32) SDLTest_RandomInt(&rndContext);
127 SDLTest_RandomUint64()
135 fuzzerInvocationCounter++;
137 value.v32[0] = SDLTest_RandomSint32();
138 value.v32[1] = SDLTest_RandomSint32();
144 SDLTest_RandomSint64()
152 fuzzerInvocationCounter++;
154 value.v32[0] = SDLTest_RandomSint32();
155 value.v32[1] = SDLTest_RandomSint32();
157 return (Sint64)value.v64;
163 SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
174 } else if(pMin == pMax) {
178 number = SDLTest_RandomUint32();
179 /* invocation count increment in preceeding call */
181 return (Sint32)((number % ((max + 1) - min)) + min);
185 * Generates a unsigned boundary value between the given boundaries.
186 * Boundary values are inclusive. See the examples below.
187 * If boundary2 < boundary1, the values are swapped.
188 * If boundary1 == boundary2, value of boundary1 will be returned
190 * Generating boundary values for Uint8:
191 * BoundaryValues(UINT8_MAX, 10, 20, True) -> [10,11,19,20]
192 * BoundaryValues(UINT8_MAX, 10, 20, False) -> [9,21]
193 * BoundaryValues(UINT8_MAX, 0, 15, True) -> [0, 1, 14, 15]
194 * BoundaryValues(UINT8_MAX, 0, 15, False) -> [16]
195 * BoundaryValues(UINT8_MAX, 0, 0xFF, False) -> [0], error set
197 * Generator works the same for other types of unsigned integers.
199 * \param maxValue The biggest value that is acceptable for this data type.
200 * For instance, for Uint8 -> 255, Uint16 -> 65536 etc.
201 * \param boundary1 defines lower boundary
202 * \param boundary2 defines upper boundary
203 * \param validDomain Generate only for valid domain (for the data type)
205 * \returns Returns a random boundary value for the domain or 0 in case of error
208 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
216 if (boundary1 > boundary2) {
225 if (validDomain == SDL_TRUE) {
230 /* Generate up to 4 values within bounds */
234 tempBuf[index] = b1 + index;
236 } while (index < delta);
240 tempBuf[index] = b1 + 1;
242 tempBuf[index] = b2 - 1;
248 /* Generate up to 2 values outside of bounds */
250 tempBuf[index] = b1 - 1;
255 tempBuf[index] = b2 + 1;
261 /* There are no valid boundaries */
266 return tempBuf[SDLTest_RandomUint8() % index];
271 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
273 /* max value for Uint8 */
274 const Uint64 maxValue = UCHAR_MAX;
275 return (Uint8)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
276 (Uint64) boundary1, (Uint64) boundary2,
281 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
283 /* max value for Uint16 */
284 const Uint64 maxValue = USHRT_MAX;
285 return (Uint16)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
286 (Uint64) boundary1, (Uint64) boundary2,
291 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
293 /* max value for Uint32 */
294 #if ((ULONG_MAX) == (UINT_MAX))
295 const Uint64 maxValue = ULONG_MAX;
297 const Uint64 maxValue = UINT_MAX;
299 return (Uint32)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
300 (Uint64) boundary1, (Uint64) boundary2,
305 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
307 /* max value for Uint64 */
308 const Uint64 maxValue = UINT64_MAX;
309 return SDLTest_GenerateUnsignedBoundaryValues(maxValue,
310 (Uint64) boundary1, (Uint64) boundary2,
315 * Generates a signed boundary value between the given boundaries.
316 * Boundary values are inclusive. See the examples below.
317 * If boundary2 < boundary1, the values are swapped.
318 * If boundary1 == boundary2, value of boundary1 will be returned
320 * Generating boundary values for Sint8:
321 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, True) -> [-10,-9,19,20]
322 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, False) -> [-11,21]
323 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -30, -15, True) -> [-30, -29, -16, -15]
324 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 15, False) -> [16]
325 * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 127, False) -> [0], error set
327 * Generator works the same for other types of signed integers.
329 * \param minValue The smallest value that is acceptable for this data type.
330 * For instance, for Uint8 -> -127, etc.
331 * \param maxValue The biggest value that is acceptable for this data type.
332 * For instance, for Uint8 -> 127, etc.
333 * \param boundary1 defines lower boundary
334 * \param boundary2 defines upper boundary
335 * \param validDomain Generate only for valid domain (for the data type)
337 * \returns Returns a random boundary value for the domain or 0 in case of error
340 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
348 if (boundary1 > boundary2) {
357 if (validDomain == SDL_TRUE) {
362 /* Generate up to 4 values within bounds */
366 tempBuf[index] = b1 + index;
368 } while (index < delta);
372 tempBuf[index] = b1 + 1;
374 tempBuf[index] = b2 - 1;
380 /* Generate up to 2 values outside of bounds */
382 tempBuf[index] = b1 - 1;
387 tempBuf[index] = b2 + 1;
393 /* There are no valid boundaries */
398 return tempBuf[SDLTest_RandomUint8() % index];
404 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
406 /* min & max values for Sint8 */
407 const Sint64 maxValue = SCHAR_MAX;
408 const Sint64 minValue = SCHAR_MIN;
409 return (Sint8)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
410 (Sint64) boundary1, (Sint64) boundary2,
415 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
417 /* min & max values for Sint16 */
418 const Sint64 maxValue = SHRT_MAX;
419 const Sint64 minValue = SHRT_MIN;
420 return (Sint16)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
421 (Sint64) boundary1, (Sint64) boundary2,
426 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
428 /* min & max values for Sint32 */
429 #if ((ULONG_MAX) == (UINT_MAX))
430 const Sint64 maxValue = LONG_MAX;
431 const Sint64 minValue = LONG_MIN;
433 const Sint64 maxValue = INT_MAX;
434 const Sint64 minValue = INT_MIN;
436 return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
437 (Sint64) boundary1, (Sint64) boundary2,
442 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
444 /* min & max values for Sint64 */
445 const Sint64 maxValue = INT64_MAX;
446 const Sint64 minValue = INT64_MIN;
447 return SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
448 boundary1, boundary2,
453 SDLTest_RandomUnitFloat()
455 return SDLTest_RandomUint32() / (float) UINT_MAX;
459 SDLTest_RandomFloat()
461 return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
465 SDLTest_RandomUnitDouble()
467 return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
471 SDLTest_RandomDouble()
477 r += (double)SDLTest_RandomInt(&rndContext) * s;
478 } while (s > DBL_EPSILON);
480 fuzzerInvocationCounter++;
487 SDLTest_RandomAsciiString()
489 return SDLTest_RandomAsciiStringWithMaximumLength(255);
493 SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
498 SDL_InvalidParamError("maxLength");
502 size = (SDLTest_RandomUint32() % (maxLength + 1));
504 return SDLTest_RandomAsciiStringOfSize(size);
508 SDLTest_RandomAsciiStringOfSize(int size)
515 SDL_InvalidParamError("size");
519 string = (char *)SDL_malloc((size + 1) * sizeof(char));
524 for(counter = 0; counter < size; ++counter) {
525 string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
528 string[counter] = '\0';
530 fuzzerInvocationCounter++;
535 /* vi: set ts=4 sw=4 expandtab: */