2 Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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"
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
47 *Counter for fuzzer invocations
49 static int fuzzerInvocationCounter = 0;
52 * Context for shared random number generator
54 static SDLTest_RandomContext rndContext;
57 * Note: doxygen documentation markup for functions is in the header file.
61 SDLTest_FuzzerInit(Uint64 execKey)
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;
71 SDLTest_GetFuzzerInvocationCount()
73 return fuzzerInvocationCounter;
79 fuzzerInvocationCounter++;
81 return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
87 fuzzerInvocationCounter++;
89 return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
93 SDLTest_RandomUint16()
95 fuzzerInvocationCounter++;
97 return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
101 SDLTest_RandomSint16()
103 fuzzerInvocationCounter++;
105 return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
109 SDLTest_RandomSint32()
111 fuzzerInvocationCounter++;
113 return (Sint32) SDLTest_RandomInt(&rndContext);
117 SDLTest_RandomUint32()
119 fuzzerInvocationCounter++;
121 return (Uint32) SDLTest_RandomInt(&rndContext);
125 SDLTest_RandomUint64()
128 Uint32 *vp = (void *)&value;
130 fuzzerInvocationCounter++;
132 vp[0] = SDLTest_RandomSint32();
133 vp[1] = SDLTest_RandomSint32();
139 SDLTest_RandomSint64()
142 Uint32 *vp = (void *)&value;
144 fuzzerInvocationCounter++;
146 vp[0] = SDLTest_RandomSint32();
147 vp[1] = SDLTest_RandomSint32();
155 SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
166 } else if(pMin == pMax) {
170 number = SDLTest_RandomUint32(); // invocation count increment in there
172 return (Sint32)((number % ((max + 1) - min)) + min);
176 * Generates boundary values between the given boundaries.
177 * Boundary values are inclusive. See the examples below.
178 * If boundary2 < boundary1, the values are swapped.
179 * If boundary1 == boundary2, value of boundary1 will be returned
181 * Generating boundary values for Uint8:
182 * BoundaryValues(sizeof(Uint8), 10, 20, True) -> [10,11,19,20]
183 * BoundaryValues(sizeof(Uint8), 10, 20, False) -> [9,21]
184 * BoundaryValues(sizeof(Uint8), 0, 15, True) -> [0, 1, 14, 15]
185 * BoundaryValues(sizeof(Uint8), 0, 15, False) -> [16]
186 * BoundaryValues(sizeof(Uint8), 0, 255, False) -> NULL
188 * Generator works the same for other types of unsigned integers.
190 * Note: outBuffer will be allocated and needs to be freed later.
191 * If outbuffer != NULL, it'll be freed.
193 * \param maxValue The biggest value that is acceptable for this data type.
194 * For instance, for Uint8 -> 255, Uint16 -> 65536 etc.
195 * \param pBoundary1 defines lower boundary
196 * \param pBoundary2 defines upper boundary
197 * \param validDomain Generate only for valid domain (for the data type)
199 * \param outBuffer The generated boundary values are put here
201 * \returns Returns the number of elements in outBuffer or -1 in case of error
204 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue,
205 Uint64 pBoundary1, Uint64 pBoundary2, SDL_bool validDomain,
208 Uint64 boundary1 = pBoundary1, boundary2 = pBoundary2;
213 if(outBuffer != NULL) {
217 if(boundary1 > boundary2) {
219 boundary1 = boundary2;
224 if(boundary1 == boundary2) {
225 tempBuf[index++] = boundary1;
227 else if(validDomain) {
228 tempBuf[index++] = boundary1;
230 if(boundary1 < UINT64_MAX)
231 tempBuf[index++] = boundary1 + 1;
233 tempBuf[index++] = boundary2 - 1;
234 tempBuf[index++] = boundary2;
238 tempBuf[index++] = boundary1 - 1;
241 if(boundary2 < maxValue && boundary2 < UINT64_MAX) {
242 tempBuf[index++] = boundary2 + 1;
247 // There are no valid boundaries
251 // Create the return buffer
252 outBuffer = (Uint64 *)SDL_malloc(index * sizeof(Uint64));
253 if(outBuffer == NULL) {
257 SDL_memcpy(outBuffer, tempBuf, index * sizeof(Uint64));
263 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
265 Uint64 *buffer = NULL;
270 // max value for Uint8
271 const Uint64 maxValue = UINT8_MAX;
273 size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
274 (Uint64) boundary1, (Uint64) boundary2,
275 validDomain, buffer);
276 if (buffer == NULL || size == 0) {
280 index = SDLTest_RandomSint32() % size;
281 retVal = (Uint8)buffer[index];
285 fuzzerInvocationCounter++;
291 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
293 Uint64 *buffer = NULL;
298 // max value for Uint16
299 const Uint64 maxValue = UINT16_MAX;
301 size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
302 (Uint64) boundary1, (Uint64) boundary2,
303 validDomain, buffer);
304 if (buffer == NULL || size == 0) {
308 index = SDLTest_RandomSint32() % size;
309 retVal = (Uint16) buffer[index];
313 fuzzerInvocationCounter++;
319 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
321 Uint64 *buffer = NULL;
326 // max value for Uint32
327 const Uint64 maxValue = UINT32_MAX;
329 size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
330 (Uint64) boundary1, (Uint64) boundary2,
331 validDomain, buffer);
332 if (buffer == NULL || size == 0) {
336 index = SDLTest_RandomSint32() % size;
337 retVal = (Uint32) buffer[index];
341 fuzzerInvocationCounter++;
347 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
349 Uint64 *buffer = NULL;
354 // max value for Uint64
355 const Uint64 maxValue = UINT64_MAX;
357 size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
358 (Uint64) boundary1, (Uint64) boundary2,
359 validDomain, buffer);
360 if (buffer == NULL || size == 0) {
364 index = SDLTest_RandomSint32() % size;
365 retVal = (Uint64) buffer[index];
369 fuzzerInvocationCounter++;
375 * Generates boundary values between the given boundaries.
376 * Boundary values are inclusive. See the examples below.
377 * If boundary2 < boundary1, the values are swapped.
378 * If boundary1 == boundary2, value of boundary1 will be returned
380 * Generating boundary values for Sint8:
381 * SignedBoundaryValues(sizeof(Sint8), -10, 20, True) -> [-11,-10,19,20]
382 * SignedBoundaryValues(sizeof(Sint8), -10, 20, False) -> [-11,21]
383 * SignedBoundaryValues(sizeof(Sint8), -30, -15, True) -> [-30, -29, -16, -15]
384 * SignedBoundaryValues(sizeof(Sint8), -128, 15, False) -> [16]
385 * SignedBoundaryValues(sizeof(Sint8), -128, 127, False) -> NULL
387 * Generator works the same for other types of signed integers.
389 * Note: outBuffer will be allocated and needs to be freed later.
390 * If outbuffer != NULL, it'll be freed.
393 * \param minValue The smallest value that is acceptable for this data type.
394 * For instance, for Uint8 -> -128, Uint16 -> -32,768 etc.
395 * \param maxValue The biggest value that is acceptable for this data type.
396 * For instance, for Uint8 -> 127, Uint16 -> 32767 etc.
397 * \param pBoundary1 defines lower boundary
398 * \param pBoundary2 defines upper boundary
399 * \param validDomain Generate only for valid domain (for the data type)
401 * \param outBuffer The generated boundary values are put here
403 * \returns Returns the number of elements in outBuffer or -1 in case of error
406 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue,
407 Sint64 pBoundary1, Sint64 pBoundary2, SDL_bool validDomain,
412 Sint64 boundary1 = pBoundary1, boundary2 = pBoundary2;
414 if(outBuffer != NULL) {
418 if(boundary1 > boundary2) {
419 Sint64 temp = boundary1;
420 boundary1 = boundary2;
425 if(boundary1 == boundary2) {
426 tempBuf[index++] = boundary1;
428 else if(validDomain) {
429 tempBuf[index++] = boundary1;
431 if(boundary1 < LLONG_MAX)
432 tempBuf[index++] = boundary1 + 1;
434 if(boundary2 > LLONG_MIN)
435 tempBuf[index++] = boundary2 - 1;
437 tempBuf[index++] = boundary2;
440 if(boundary1 > minValue && boundary1 > LLONG_MIN) {
441 tempBuf[index++] = boundary1 - 1;
444 if(boundary2 < maxValue && boundary2 < UINT64_MAX) {
445 tempBuf[index++] = boundary2 + 1;
450 // There are no valid boundaries
454 // Create the return buffer
455 outBuffer = (Sint64 *)SDL_malloc(index * sizeof(Sint64));
456 if(outBuffer == NULL) {
460 SDL_memcpy((void *)outBuffer, (void *)tempBuf, index * sizeof(Sint64));
462 return (Uint32)index;
466 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
468 // min & max values for Sint8
469 const Sint64 maxValue = CHAR_MAX;
470 const Sint64 minValue = CHAR_MIN;
472 Sint64 *buffer = NULL;
477 size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
478 (Sint64) boundary1, (Sint64) boundary2,
479 validDomain, buffer);
480 if (buffer == NULL || size == 0) {
484 index = SDLTest_RandomSint32() % size;
485 retVal = (Sint8) buffer[index];
489 fuzzerInvocationCounter++;
495 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
497 // min & max values for Sint16
498 const Sint64 maxValue = SHRT_MAX;
499 const Sint64 minValue = SHRT_MIN;
500 Sint64 *buffer = NULL;
505 size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
506 (Sint64) boundary1, (Sint64) boundary2,
507 validDomain, buffer);
508 if (buffer == NULL || size == 0) {
512 index = SDLTest_RandomSint32() % size;
513 retVal = (Sint16) buffer[index];
517 fuzzerInvocationCounter++;
523 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
525 // min & max values for Sint32
526 const Sint64 maxValue = INT_MAX;
527 const Sint64 minValue = INT_MIN;
529 Sint64 *buffer = NULL;
534 size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
535 (Sint64) boundary1, (Sint64) boundary2,
536 validDomain, buffer);
537 if (buffer == NULL || size == 0) {
541 index = SDLTest_RandomSint32() % size;
542 retVal = (Sint32) buffer[index];
546 fuzzerInvocationCounter++;
552 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
554 Sint64 *buffer = NULL;
559 // min & max values for Sint64
560 const Sint64 maxValue = LLONG_MAX;
561 const Sint64 minValue = LLONG_MIN;
563 size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
564 (Sint64) boundary1, (Sint64) boundary2,
565 validDomain, buffer);
566 if (buffer == NULL || size == 0) {
570 index = SDLTest_RandomSint32() % size;
571 retVal = (Sint64) buffer[index];
575 fuzzerInvocationCounter++;
581 SDLTest_RandomUnitFloat()
583 return (float) SDLTest_RandomUint32() / UINT_MAX;
587 SDLTest_RandomFloat()
589 return (float) (FLT_MIN + SDLTest_RandomUnitDouble() * (FLT_MAX - FLT_MIN));
593 SDLTest_RandomUnitDouble()
595 return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
599 SDLTest_RandomDouble()
605 r += (double)SDLTest_RandomInt(&rndContext) * s;
606 } while (s > DBL_EPSILON);
608 fuzzerInvocationCounter++;
615 SDLTest_RandomAsciiString()
617 // note: fuzzerInvocationCounter is increment in the RandomAsciiStringWithMaximumLenght
618 return SDLTest_RandomAsciiStringWithMaximumLength(255);
622 SDLTest_RandomAsciiStringWithMaximumLength(int maxSize)
628 fuzzerInvocationCounter++;
634 size = (SDLTest_RandomUint32() % (maxSize + 1)) + 1;
635 string = (char *)SDL_malloc(size * sizeof(char));
640 for(counter = 0; counter < size; ++counter) {
641 string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
644 string[counter] = '\0';