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"
39 *Counter for fuzzer invocations
41 static int fuzzerInvocationCounter;
44 * Context for shared random number generator
46 static SDLTest_RandomContext rndContext;
49 * Note: doxygen documentation markup for functions is in the header file.
53 SDLTest_FuzzerInit(Uint64 execKey)
55 Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF;
56 Uint32 b = execKey & 0x00000000FFFFFFFF;
57 SDLTest_RandomInit(&rndContext, a, b);
61 SDLTest_GetInvocationCount()
63 return fuzzerInvocationCounter;
69 fuzzerInvocationCounter++;
71 return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
77 fuzzerInvocationCounter++;
79 return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
83 SDLTest_RandomUint16()
85 fuzzerInvocationCounter++;
87 return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
91 SDLTest_RandomSint16()
93 fuzzerInvocationCounter++;
95 return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
99 SDLTest_RandomSint32()
101 fuzzerInvocationCounter++;
103 return (Sint32) SDLTest_RandomInt(&rndContext);
107 SDLTest_RandomUint32()
109 fuzzerInvocationCounter++;
111 return (Uint32) SDLTest_RandomInt(&rndContext);
115 SDLTest_RandomUint64()
118 Uint32 *vp = (void*)&value;
120 fuzzerInvocationCounter++;
122 vp[0] = SDLTest_RandomSint32();
123 vp[1] = SDLTest_RandomSint32();
129 SDLTest_RandomSint64()
132 Uint32 *vp = (void*)&value;
134 fuzzerInvocationCounter++;
136 vp[0] = SDLTest_RandomSint32();
137 vp[1] = SDLTest_RandomSint32();
145 SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
156 } else if(pMin == pMax) {
160 number = SDLTest_RandomUint32(); // invocation count increment in there
162 return (Sint32)((number % ((max + 1) - min)) + min);
166 * Generates boundary values between the given boundaries.
167 * Boundary values are inclusive. See the examples below.
168 * If boundary2 < boundary1, the values are swapped.
169 * If boundary1 == boundary2, value of boundary1 will be returned
171 * Generating boundary values for Uint8:
172 * BoundaryValues(sizeof(Uint8), 10, 20, True) -> [10,11,19,20]
173 * BoundaryValues(sizeof(Uint8), 10, 20, False) -> [9,21]
174 * BoundaryValues(sizeof(Uint8), 0, 15, True) -> [0, 1, 14, 15]
175 * BoundaryValues(sizeof(Uint8), 0, 15, False) -> [16]
176 * BoundaryValues(sizeof(Uint8), 0, 255, False) -> NULL
178 * Generator works the same for other types of unsigned integers.
180 * Note: outBuffer will be allocated and needs to be freed later.
181 * If outbuffer != NULL, it'll be freed.
183 * \param maxValue The biggest value that is acceptable for this data type.
184 * For instance, for Uint8 -> 255, Uint16 -> 65536 etc.
185 * \param pBoundary1 defines lower boundary
186 * \param pBoundary2 defines upper boundary
187 * \param validDomain Generate only for valid domain (for the data type)
189 * \param outBuffer The generated boundary values are put here
191 * \returns Returns the number of elements in outBuffer or -1 in case of error
194 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue,
195 Uint64 pBoundary1, Uint64 pBoundary2, SDL_bool validDomain,
198 Uint64 boundary1 = pBoundary1, boundary2 = pBoundary2;
203 if(outBuffer != NULL) {
207 if(boundary1 > boundary2) {
209 boundary1 = boundary2;
214 if(boundary1 == boundary2) {
215 tempBuf[index++] = boundary1;
217 else if(validDomain) {
218 tempBuf[index++] = boundary1;
220 if(boundary1 < UINT64_MAX)
221 tempBuf[index++] = boundary1 + 1;
223 tempBuf[index++] = boundary2 - 1;
224 tempBuf[index++] = boundary2;
228 tempBuf[index++] = boundary1 - 1;
231 if(boundary2 < maxValue && boundary2 < UINT64_MAX) {
232 tempBuf[index++] = boundary2 + 1;
237 // There are no valid boundaries
241 // Create the return buffer
242 outBuffer = (Uint64 *)SDL_malloc(index * sizeof(Uint64));
243 if(outBuffer == NULL) {
247 SDL_memcpy(outBuffer, tempBuf, index * sizeof(Uint64));
253 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
255 Uint64 *buffer = NULL;
260 // max value for Uint8
261 const Uint64 maxValue = UINT8_MAX;
263 size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
264 (Uint64) boundary1, (Uint64) boundary2,
265 validDomain, buffer);
270 index = SDLTest_RandomSint32() % size;
271 retVal = (Uint8)buffer[index];
275 fuzzerInvocationCounter++;
281 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
283 Uint64 *buffer = NULL;
288 // max value for Uint16
289 const Uint64 maxValue = UINT16_MAX;
291 size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
292 (Uint64) boundary1, (Uint64) boundary2,
293 validDomain, buffer);
298 index = SDLTest_RandomSint32() % size;
299 retVal = (Uint16) buffer[index];
303 fuzzerInvocationCounter++;
309 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
311 Uint64 *buffer = NULL;
316 // max value for Uint32
317 const Uint64 maxValue = UINT32_MAX;
319 size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
320 (Uint64) boundary1, (Uint64) boundary2,
321 validDomain, buffer);
326 index = SDLTest_RandomSint32() % size;
327 retVal = (Uint32) buffer[index];
331 fuzzerInvocationCounter++;
337 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
339 Uint64 *buffer = NULL;
344 // max value for Uint64
345 const Uint64 maxValue = UINT64_MAX;
347 size = SDLTest_GenerateUnsignedBoundaryValues(maxValue,
348 (Uint64) boundary1, (Uint64) boundary2,
349 validDomain, buffer);
354 index = SDLTest_RandomSint32() % size;
355 retVal = (Uint64) buffer[index];
359 fuzzerInvocationCounter++;
365 * Generates boundary values between the given boundaries.
366 * Boundary values are inclusive. See the examples below.
367 * If boundary2 < boundary1, the values are swapped.
368 * If boundary1 == boundary2, value of boundary1 will be returned
370 * Generating boundary values for Sint8:
371 * SignedBoundaryValues(sizeof(Sint8), -10, 20, True) -> [-11,-10,19,20]
372 * SignedBoundaryValues(sizeof(Sint8), -10, 20, False) -> [-11,21]
373 * SignedBoundaryValues(sizeof(Sint8), -30, -15, True) -> [-30, -29, -16, -15]
374 * SignedBoundaryValues(sizeof(Sint8), -128, 15, False) -> [16]
375 * SignedBoundaryValues(sizeof(Sint8), -128, 127, False) -> NULL
377 * Generator works the same for other types of signed integers.
379 * Note: outBuffer will be allocated and needs to be freed later.
380 * If outbuffer != NULL, it'll be freed.
383 * \param minValue The smallest value that is acceptable for this data type.
384 * For instance, for Uint8 -> -128, Uint16 -> -32,768 etc.
385 * \param maxValue The biggest value that is acceptable for this data type.
386 * For instance, for Uint8 -> 127, Uint16 -> 32767 etc.
387 * \param pBoundary1 defines lower boundary
388 * \param pBoundary2 defines upper boundary
389 * \param validDomain Generate only for valid domain (for the data type)
391 * \param outBuffer The generated boundary values are put here
393 * \returns Returns the number of elements in outBuffer or -1 in case of error
396 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue,
397 Sint64 pBoundary1, Sint64 pBoundary2, SDL_bool validDomain,
402 Sint64 boundary1 = pBoundary1, boundary2 = pBoundary2;
404 if(outBuffer != NULL) {
408 if(boundary1 > boundary2) {
409 Sint64 temp = boundary1;
410 boundary1 = boundary2;
415 if(boundary1 == boundary2) {
416 tempBuf[index++] = boundary1;
418 else if(validDomain) {
419 tempBuf[index++] = boundary1;
421 if(boundary1 < LLONG_MAX)
422 tempBuf[index++] = boundary1 + 1;
424 if(boundary2 > LLONG_MIN)
425 tempBuf[index++] = boundary2 - 1;
427 tempBuf[index++] = boundary2;
430 if(boundary1 > minValue && boundary1 > LLONG_MIN) {
431 tempBuf[index++] = boundary1 - 1;
434 if(boundary2 < maxValue && boundary2 < UINT64_MAX) {
435 tempBuf[index++] = boundary2 + 1;
440 // There are no valid boundaries
444 // Create the return buffer
445 outBuffer = (Sint64 *)SDL_malloc(index * sizeof(Sint64));
446 if(outBuffer == NULL) {
450 SDL_memcpy((void *)outBuffer, (void *)tempBuf, index * sizeof(Sint64));
452 return (Uint32)index;
456 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
458 // min & max values for Sint8
459 const Sint64 maxValue = CHAR_MAX;
460 const Sint64 minValue = CHAR_MIN;
462 Sint64 *buffer = NULL;
467 size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
468 (Sint64) boundary1, (Sint64) boundary2,
469 validDomain, buffer);
474 index = SDLTest_RandomSint32() % size;
475 retVal = (Sint8) buffer[index];
479 fuzzerInvocationCounter++;
485 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
487 // min & max values for Sint16
488 const Sint64 maxValue = SHRT_MAX;
489 const Sint64 minValue = SHRT_MIN;
490 Sint64 *buffer = NULL;
495 size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
496 (Sint64) boundary1, (Sint64) boundary2,
497 validDomain, buffer);
502 index = SDLTest_RandomSint32() % size;
503 retVal = (Sint16) buffer[index];
507 fuzzerInvocationCounter++;
513 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
515 // min & max values for Sint32
516 const Sint64 maxValue = INT_MAX;
517 const Sint64 minValue = INT_MIN;
519 Sint64 *buffer = NULL;
524 size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
525 (Sint64) boundary1, (Sint64) boundary2,
526 validDomain, buffer);
531 index = SDLTest_RandomSint32() % size;
532 retVal = (Sint32) buffer[index];
536 fuzzerInvocationCounter++;
542 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
544 Sint64 *buffer = NULL;
549 // min & max values for Sint64
550 const Sint64 maxValue = LLONG_MAX;
551 const Sint64 minValue = LLONG_MIN;
553 size = SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
554 (Sint64) boundary1, (Sint64) boundary2,
555 validDomain, buffer);
560 index = SDLTest_RandomSint32() % size;
561 retVal = (Sint64) buffer[index];
565 fuzzerInvocationCounter++;
571 SDLTest_RandomUnitFloat()
573 return (float) SDLTest_RandomUint32() / UINT_MAX;
577 SDLTest_RandomFloat()
579 return (float) (FLT_MIN + SDLTest_RandomUnitDouble() * (FLT_MAX - FLT_MIN));
583 SDLTest_RandomUnitDouble()
585 return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
589 SDLTest_RandomDouble()
595 r += (double)SDLTest_RandomInt(&rndContext) * s;
596 } while (s > DBL_EPSILON);
598 fuzzerInvocationCounter++;
605 SDLTest_RandomAsciiString()
607 // note: fuzzerInvocationCounter is increment in the RandomAsciiStringWithMaximumLenght
608 return SDLTest_RandomAsciiStringWithMaximumLength(255);
612 SDLTest_RandomAsciiStringWithMaximumLength(int maxSize)
618 fuzzerInvocationCounter++;
624 size = (SDLTest_RandomUint32() % (maxSize + 1)) + 1;
625 string = (char *)SDL_malloc(size * sizeof(char));
630 for(counter = 0; counter < size; ++counter) {
631 string[counter] = (char)SDLTest_RandomIntegerInRange(1, 127);
634 string[counter] = '\0';