2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 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();
171 /* invocation count increment in preceeding call */
173 return (Sint32)((number % ((max + 1) - min)) + min);
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
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
189 * Generator works the same for other types of unsigned integers.
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)
197 * \returns Returns a random boundary value for the domain or 0 in case of error
200 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
208 if (boundary1 > boundary2) {
217 if (validDomain == SDL_TRUE) {
222 /* Generate up to 4 values within bounds */
226 tempBuf[index] = b1 + index;
228 } while (index < delta);
232 tempBuf[index] = b1 + 1;
234 tempBuf[index] = b2 - 1;
240 /* Generate up to 2 values outside of bounds */
242 tempBuf[index] = b1 - 1;
247 tempBuf[index] = b2 + 1;
253 /* There are no valid boundaries */
258 return tempBuf[SDLTest_RandomUint8() % index];
263 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
265 /* max value for Uint8 */
266 const Uint64 maxValue = UCHAR_MAX;
267 return (Uint8)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
268 (Uint64) boundary1, (Uint64) boundary2,
273 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
275 /* max value for Uint16 */
276 const Uint64 maxValue = USHRT_MAX;
277 return (Uint16)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
278 (Uint64) boundary1, (Uint64) boundary2,
283 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
285 /* max value for Uint32 */
286 #if ((ULONG_MAX) == (UINT_MAX))
287 const Uint64 maxValue = ULONG_MAX;
289 const Uint64 maxValue = UINT_MAX;
291 return (Uint32)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
292 (Uint64) boundary1, (Uint64) boundary2,
297 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
299 /* max value for Uint64 */
300 const Uint64 maxValue = ULLONG_MAX;
301 return SDLTest_GenerateUnsignedBoundaryValues(maxValue,
302 (Uint64) boundary1, (Uint64) boundary2,
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
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
319 * Generator works the same for other types of signed integers.
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)
329 * \returns Returns a random boundary value for the domain or 0 in case of error
332 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
340 if (boundary1 > boundary2) {
349 if (validDomain == SDL_TRUE) {
354 /* Generate up to 4 values within bounds */
358 tempBuf[index] = b1 + index;
360 } while (index < delta);
364 tempBuf[index] = b1 + 1;
366 tempBuf[index] = b2 - 1;
372 /* Generate up to 2 values outside of bounds */
374 tempBuf[index] = b1 - 1;
379 tempBuf[index] = b2 + 1;
385 /* There are no valid boundaries */
390 return tempBuf[SDLTest_RandomUint8() % index];
395 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
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,
406 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
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,
417 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
419 /* min & max values for Sint32 */
420 #if ((ULONG_MAX) == (UINT_MAX))
421 const Sint64 maxValue = LONG_MAX;
422 const Sint64 minValue = LONG_MIN;
424 const Sint64 maxValue = INT_MAX;
425 const Sint64 minValue = INT_MIN;
427 return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
428 (Sint64) boundary1, (Sint64) boundary2,
433 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
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,
444 SDLTest_RandomUnitFloat()
446 return (float) SDLTest_RandomUint32() / UINT_MAX;
450 SDLTest_RandomFloat()
452 return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
456 SDLTest_RandomUnitDouble()
458 return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
462 SDLTest_RandomDouble()
468 r += (double)SDLTest_RandomInt(&rndContext) * s;
469 } while (s > DBL_EPSILON);
471 fuzzerInvocationCounter++;
478 SDLTest_RandomAsciiString()
480 return SDLTest_RandomAsciiStringWithMaximumLength(255);
484 SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
489 SDL_InvalidParamError("maxLength");
493 size = (SDLTest_RandomUint32() % (maxLength + 1));
495 return SDLTest_RandomAsciiStringOfSize(size);
499 SDLTest_RandomAsciiStringOfSize(int size)
506 SDL_InvalidParamError("size");
510 string = (char *)SDL_malloc((size + 1) * sizeof(char));
515 for(counter = 0; counter < size; ++counter) {
516 string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
519 string[counter] = '\0';
521 fuzzerInvocationCounter++;