SDL 2.0
SDL_test_fuzzer.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
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.
8
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:
12
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.
20*/
21
22/*
23
24 Data generators for fuzzing test data in a reproducible way.
25
26*/
27
28#include "SDL_config.h"
29
30#include <limits.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
39#else
40#include <stdint.h>
41#endif
42#include <stdio.h>
43#include <stdlib.h>
44#include <float.h>
45
46#include "SDL_test.h"
47
48/**
49 * Counter for fuzzer invocations
50 */
52
53/**
54 * Context for shared random number generator
55 */
57
58/*
59 * Note: doxygen documentation markup for functions is in the header file.
60 */
61
62void
64{
65 Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF;
66 Uint32 b = execKey & 0x00000000FFFFFFFF;
67 SDL_memset((void *)&rndContext, 0, sizeof(SDLTest_RandomContext));
70}
71
72int
74{
76}
77
80{
82
83 return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
84}
85
88{
90
91 return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
92}
93
96{
98
99 return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
100}
101
102Sint16
104{
106
107 return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
108}
109
110Sint32
112{
114
116}
117
118Uint32
120{
122
124}
125
126Uint64
128{
129 union {
130 Uint64 v64;
131 Uint32 v32[2];
132 } value;
133 value.v64 = 0;
134
136
137 value.v32[0] = SDLTest_RandomSint32();
138 value.v32[1] = SDLTest_RandomSint32();
139
140 return value.v64;
141}
142
143Sint64
145{
146 union {
147 Uint64 v64;
148 Uint32 v32[2];
149 } value;
150 value.v64 = 0;
151
153
154 value.v32[0] = SDLTest_RandomSint32();
155 value.v32[1] = SDLTest_RandomSint32();
156
157 return (Sint64)value.v64;
158}
159
160
161
162Sint32
164{
165 Sint64 min = pMin;
166 Sint64 max = pMax;
167 Sint64 temp;
168 Sint64 number;
169
170 if(pMin > pMax) {
171 temp = min;
172 min = max;
173 max = temp;
174 } else if(pMin == pMax) {
175 return (Sint32)min;
176 }
177
178 number = SDLTest_RandomUint32();
179 /* invocation count increment in preceeding call */
180
181 return (Sint32)((number % ((max + 1) - min)) + min);
182}
183
184/* !
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
189 *
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
196 *
197 * Generator works the same for other types of unsigned integers.
198 *
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)
204 *
205 * \returns Returns a random boundary value for the domain or 0 in case of error
206 */
207static Uint64
208SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
209{
210 Uint64 b1, b2;
211 Uint64 delta;
212 Uint64 tempBuf[4];
213 Uint8 index;
214
215 /* Maybe swap */
216 if (boundary1 > boundary2) {
217 b1 = boundary2;
218 b2 = boundary1;
219 } else {
220 b1 = boundary1;
221 b2 = boundary2;
222 }
223
224 index = 0;
225 if (validDomain == SDL_TRUE) {
226 if (b1 == b2) {
227 return b1;
228 }
229
230 /* Generate up to 4 values within bounds */
231 delta = b2 - b1;
232 if (delta < 4) {
233 do {
234 tempBuf[index] = b1 + index;
235 index++;
236 } while (index < delta);
237 } else {
238 tempBuf[index] = b1;
239 index++;
240 tempBuf[index] = b1 + 1;
241 index++;
242 tempBuf[index] = b2 - 1;
243 index++;
244 tempBuf[index] = b2;
245 index++;
246 }
247 } else {
248 /* Generate up to 2 values outside of bounds */
249 if (b1 > 0) {
250 tempBuf[index] = b1 - 1;
251 index++;
252 }
253
254 if (b2 < maxValue) {
255 tempBuf[index] = b2 + 1;
256 index++;
257 }
258 }
259
260 if (index == 0) {
261 /* There are no valid boundaries */
263 return 0;
264 }
265
266 return tempBuf[SDLTest_RandomUint8() % index];
267}
268
269
270Uint8
271SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
272{
273 /* max value for Uint8 */
274 const Uint64 maxValue = UCHAR_MAX;
276 (Uint64) boundary1, (Uint64) boundary2,
277 validDomain);
278}
279
280Uint16
281SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
282{
283 /* max value for Uint16 */
284 const Uint64 maxValue = USHRT_MAX;
286 (Uint64) boundary1, (Uint64) boundary2,
287 validDomain);
288}
289
290Uint32
291SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
292{
293 /* max value for Uint32 */
294 #if ((ULONG_MAX) == (UINT_MAX))
295 const Uint64 maxValue = ULONG_MAX;
296 #else
297 const Uint64 maxValue = UINT_MAX;
298 #endif
300 (Uint64) boundary1, (Uint64) boundary2,
301 validDomain);
302}
303
304Uint64
305SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
306{
307 /* max value for Uint64 */
308 const Uint64 maxValue = UINT64_MAX;
310 (Uint64) boundary1, (Uint64) boundary2,
311 validDomain);
312}
313
314/* !
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
319 *
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
326 *
327 * Generator works the same for other types of signed integers.
328 *
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)
336 *
337 * \returns Returns a random boundary value for the domain or 0 in case of error
338 */
339static Sint64
340SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
341{
342 Sint64 b1, b2;
343 Sint64 delta;
344 Sint64 tempBuf[4];
345 Uint8 index;
346
347 /* Maybe swap */
348 if (boundary1 > boundary2) {
349 b1 = boundary2;
350 b2 = boundary1;
351 } else {
352 b1 = boundary1;
353 b2 = boundary2;
354 }
355
356 index = 0;
357 if (validDomain == SDL_TRUE) {
358 if (b1 == b2) {
359 return b1;
360 }
361
362 /* Generate up to 4 values within bounds */
363 delta = b2 - b1;
364 if (delta < 4) {
365 do {
366 tempBuf[index] = b1 + index;
367 index++;
368 } while (index < delta);
369 } else {
370 tempBuf[index] = b1;
371 index++;
372 tempBuf[index] = b1 + 1;
373 index++;
374 tempBuf[index] = b2 - 1;
375 index++;
376 tempBuf[index] = b2;
377 index++;
378 }
379 } else {
380 /* Generate up to 2 values outside of bounds */
381 if (b1 > minValue) {
382 tempBuf[index] = b1 - 1;
383 index++;
384 }
385
386 if (b2 < maxValue) {
387 tempBuf[index] = b2 + 1;
388 index++;
389 }
390 }
391
392 if (index == 0) {
393 /* There are no valid boundaries */
395 return minValue;
396 }
397
398 return tempBuf[SDLTest_RandomUint8() % index];
399}
400
401
402Sint8
403SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
404{
405 /* min & max values for Sint8 */
406 const Sint64 maxValue = SCHAR_MAX;
407 const Sint64 minValue = SCHAR_MIN;
408 return (Sint8)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
409 (Sint64) boundary1, (Sint64) boundary2,
410 validDomain);
411}
412
413Sint16
414SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
415{
416 /* min & max values for Sint16 */
417 const Sint64 maxValue = SHRT_MAX;
418 const Sint64 minValue = SHRT_MIN;
419 return (Sint16)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
420 (Sint64) boundary1, (Sint64) boundary2,
421 validDomain);
422}
423
424Sint32
425SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
426{
427 /* min & max values for Sint32 */
428 #if ((ULONG_MAX) == (UINT_MAX))
429 const Sint64 maxValue = LONG_MAX;
430 const Sint64 minValue = LONG_MIN;
431 #else
432 const Sint64 maxValue = INT_MAX;
433 const Sint64 minValue = INT_MIN;
434 #endif
435 return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
436 (Sint64) boundary1, (Sint64) boundary2,
437 validDomain);
438}
439
440Sint64
441SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
442{
443 /* min & max values for Sint64 */
444 const Sint64 maxValue = INT64_MAX;
445 const Sint64 minValue = INT64_MIN;
446 return SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
447 boundary1, boundary2,
448 validDomain);
449}
450
451float
453{
454 return SDLTest_RandomUint32() / (float) UINT_MAX;
455}
456
457float
459{
460 return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
461}
462
463double
465{
466 return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
467}
468
469double
471{
472 double r = 0.0;
473 double s = 1.0;
474 do {
475 s /= UINT_MAX + 1.0;
476 r += (double)SDLTest_RandomInt(&rndContext) * s;
477 } while (s > DBL_EPSILON);
478
480
481 return r;
482}
483
484
485char *
487{
489}
490
491char *
493{
494 int size;
495
496 if(maxLength < 1) {
497 SDL_InvalidParamError("maxLength");
498 return NULL;
499 }
500
501 size = (SDLTest_RandomUint32() % (maxLength + 1));
502
504}
505
506char *
508{
509 char *string;
510 int counter;
511
512
513 if(size < 1) {
514 SDL_InvalidParamError("size");
515 return NULL;
516 }
517
518 string = (char *)SDL_malloc((size + 1) * sizeof(char));
519 if (string==NULL) {
520 return NULL;
521 }
522
523 for(counter = 0; counter < size; ++counter) {
524 string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
525 }
526
527 string[counter] = '\0';
528
530
531 return string;
532}
533
534/* vi: set ts=4 sw=4 expandtab: */
#define SDL_memset
#define SDL_malloc
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLdouble s
Definition: SDL_opengl.h:2063
GLboolean GLboolean GLboolean b
GLuint index
GLsizei maxLength
GLboolean GLboolean GLboolean GLboolean a
GLsizeiptr size
GLsizei const GLfloat * value
GLsizei const GLchar *const * string
GLuint counter
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
int8_t Sint8
Definition: SDL_stdinc.h:173
uint32_t Uint32
Definition: SDL_stdinc.h:203
int32_t Sint32
Definition: SDL_stdinc.h:197
int16_t Sint16
Definition: SDL_stdinc.h:185
uint64_t Uint64
Definition: SDL_stdinc.h:216
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179
int64_t Sint64
Definition: SDL_stdinc.h:210
int SDLTest_GetFuzzerInvocationCount()
Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
float SDLTest_RandomUnitFloat()
static Sint64 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
Uint64 SDLTest_RandomUint64()
void SDLTest_FuzzerInit(Uint64 execKey)
Uint32 SDLTest_RandomUint32()
Sint32 SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
Uint16 SDLTest_RandomUint16()
Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
static Uint64 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
char * SDLTest_RandomAsciiStringOfSize(int size)
Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
static SDLTest_RandomContext rndContext
Sint32 SDLTest_RandomSint32()
float SDLTest_RandomFloat()
double SDLTest_RandomDouble()
Sint8 SDLTest_RandomSint8()
static int fuzzerInvocationCounter
Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
Sint16 SDLTest_RandomSint16()
Sint64 SDLTest_RandomSint64()
double SDLTest_RandomUnitDouble()
Uint8 SDLTest_RandomUint8()
char * SDLTest_RandomAsciiString()
#define SDLTest_RandomInt(c)
void SDLTest_RandomInit(SDLTest_RandomContext *rndContext, unsigned int xi, unsigned int ci)
Initialize random number generator with two integers.
#define INT_MAX
Definition: SDL_wave.c:31
#define NULL
Definition: begin_code.h:167
#define UINT64_MAX
Definition: testvulkan.c:39