SDL  2.0
SDL_test_fuzzer.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 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 /* 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
36 #else
37 #define _GNU_SOURCE
38 #include <stdint.h>
39 #endif
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <limits.h>
43 #include <float.h>
44 
45 #include "SDL_test.h"
46 
47 /**
48  * Counter for fuzzer invocations
49  */
50 static int fuzzerInvocationCounter = 0;
51 
52 /**
53  * Context for shared random number generator
54  */
56 
57 /*
58  * Note: doxygen documentation markup for functions is in the header file.
59  */
60 
61 void
63 {
64  Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF;
65  Uint32 b = execKey & 0x00000000FFFFFFFF;
66  SDL_memset((void *)&rndContext, 0, sizeof(SDLTest_RandomContext));
67  SDLTest_RandomInit(&rndContext, a, b);
69 }
70 
71 int
73 {
75 }
76 
77 Uint8
79 {
81 
82  return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
83 }
84 
85 Sint8
87 {
89 
90  return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
91 }
92 
93 Uint16
95 {
97 
98  return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
99 }
100 
101 Sint16
103 {
105 
106  return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
107 }
108 
109 Sint32
111 {
113 
114  return (Sint32) SDLTest_RandomInt(&rndContext);
115 }
116 
117 Uint32
119 {
121 
122  return (Uint32) SDLTest_RandomInt(&rndContext);
123 }
124 
125 Uint64
127 {
128  Uint64 value = 0;
129  Uint32 *vp = (void *)&value;
130 
132 
133  vp[0] = SDLTest_RandomSint32();
134  vp[1] = SDLTest_RandomSint32();
135 
136  return value;
137 }
138 
139 Sint64
141 {
142  Uint64 value = 0;
143  Uint32 *vp = (void *)&value;
144 
146 
147  vp[0] = SDLTest_RandomSint32();
148  vp[1] = SDLTest_RandomSint32();
149 
150  return value;
151 }
152 
153 
154 
155 Sint32
157 {
158  Sint64 min = pMin;
159  Sint64 max = pMax;
160  Sint64 temp;
161  Sint64 number;
162 
163  if(pMin > pMax) {
164  temp = min;
165  min = max;
166  max = temp;
167  } else if(pMin == pMax) {
168  return (Sint32)min;
169  }
170 
171  number = SDLTest_RandomUint32();
172  /* invocation count increment in preceeding call */
173 
174  return (Sint32)((number % ((max + 1) - min)) + min);
175 }
176 
177 /* !
178  * Generates a unsigned boundary value between the given boundaries.
179  * Boundary values are inclusive. See the examples below.
180  * If boundary2 < boundary1, the values are swapped.
181  * If boundary1 == boundary2, value of boundary1 will be returned
182  *
183  * Generating boundary values for Uint8:
184  * BoundaryValues(UINT8_MAX, 10, 20, True) -> [10,11,19,20]
185  * BoundaryValues(UINT8_MAX, 10, 20, False) -> [9,21]
186  * BoundaryValues(UINT8_MAX, 0, 15, True) -> [0, 1, 14, 15]
187  * BoundaryValues(UINT8_MAX, 0, 15, False) -> [16]
188  * BoundaryValues(UINT8_MAX, 0, 0xFF, False) -> [0], error set
189  *
190  * Generator works the same for other types of unsigned integers.
191  *
192  * \param maxValue The biggest value that is acceptable for this data type.
193  * For instance, for Uint8 -> 255, Uint16 -> 65536 etc.
194  * \param boundary1 defines lower boundary
195  * \param boundary2 defines upper boundary
196  * \param validDomain Generate only for valid domain (for the data type)
197  *
198  * \returns Returns a random boundary value for the domain or 0 in case of error
199  */
200 Uint64
201 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
202 {
203  Uint64 b1, b2;
204  Uint64 delta;
205  Uint64 tempBuf[4];
206  Uint8 index;
207 
208  /* Maybe swap */
209  if (boundary1 > boundary2) {
210  b1 = boundary2;
211  b2 = boundary1;
212  } else {
213  b1 = boundary1;
214  b2 = boundary2;
215  }
216 
217  index = 0;
218  if (validDomain == SDL_TRUE) {
219  if (b1 == b2) {
220  return b1;
221  }
222 
223  /* Generate up to 4 values within bounds */
224  delta = b2 - b1;
225  if (delta < 4) {
226  do {
227  tempBuf[index] = b1 + index;
228  index++;
229  } while (index < delta);
230  } else {
231  tempBuf[index] = b1;
232  index++;
233  tempBuf[index] = b1 + 1;
234  index++;
235  tempBuf[index] = b2 - 1;
236  index++;
237  tempBuf[index] = b2;
238  index++;
239  }
240  } else {
241  /* Generate up to 2 values outside of bounds */
242  if (b1 > 0) {
243  tempBuf[index] = b1 - 1;
244  index++;
245  }
246 
247  if (b2 < maxValue) {
248  tempBuf[index] = b2 + 1;
249  index++;
250  }
251  }
252 
253  if (index == 0) {
254  /* There are no valid boundaries */
255  SDL_Unsupported();
256  return 0;
257  }
258 
259  return tempBuf[SDLTest_RandomUint8() % index];
260 }
261 
262 
263 Uint8
264 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
265 {
266  /* max value for Uint8 */
267  const Uint64 maxValue = UCHAR_MAX;
269  (Uint64) boundary1, (Uint64) boundary2,
270  validDomain);
271 }
272 
273 Uint16
274 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
275 {
276  /* max value for Uint16 */
277  const Uint64 maxValue = USHRT_MAX;
279  (Uint64) boundary1, (Uint64) boundary2,
280  validDomain);
281 }
282 
283 Uint32
284 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
285 {
286  /* max value for Uint32 */
287  #if ((ULONG_MAX) == (UINT_MAX))
288  const Uint64 maxValue = ULONG_MAX;
289  #else
290  const Uint64 maxValue = UINT_MAX;
291  #endif
293  (Uint64) boundary1, (Uint64) boundary2,
294  validDomain);
295 }
296 
297 Uint64
298 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
299 {
300  /* max value for Uint64 */
301  const Uint64 maxValue = ULLONG_MAX;
303  (Uint64) boundary1, (Uint64) boundary2,
304  validDomain);
305 }
306 
307 /* !
308  * Generates a signed boundary value between the given boundaries.
309  * Boundary values are inclusive. See the examples below.
310  * If boundary2 < boundary1, the values are swapped.
311  * If boundary1 == boundary2, value of boundary1 will be returned
312  *
313  * Generating boundary values for Sint8:
314  * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, True) -> [-10,-9,19,20]
315  * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, False) -> [-11,21]
316  * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -30, -15, True) -> [-30, -29, -16, -15]
317  * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 15, False) -> [16]
318  * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 127, False) -> [0], error set
319  *
320  * Generator works the same for other types of signed integers.
321  *
322  * \param minValue The smallest value that is acceptable for this data type.
323  * For instance, for Uint8 -> -127, etc.
324  * \param maxValue The biggest value that is acceptable for this data type.
325  * For instance, for Uint8 -> 127, etc.
326  * \param boundary1 defines lower boundary
327  * \param boundary2 defines upper boundary
328  * \param validDomain Generate only for valid domain (for the data type)
329  *
330  * \returns Returns a random boundary value for the domain or 0 in case of error
331  */
332 Sint64
333 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
334 {
335  Sint64 b1, b2;
336  Sint64 delta;
337  Sint64 tempBuf[4];
338  Uint8 index;
339 
340  /* Maybe swap */
341  if (boundary1 > boundary2) {
342  b1 = boundary2;
343  b2 = boundary1;
344  } else {
345  b1 = boundary1;
346  b2 = boundary2;
347  }
348 
349  index = 0;
350  if (validDomain == SDL_TRUE) {
351  if (b1 == b2) {
352  return b1;
353  }
354 
355  /* Generate up to 4 values within bounds */
356  delta = b2 - b1;
357  if (delta < 4) {
358  do {
359  tempBuf[index] = b1 + index;
360  index++;
361  } while (index < delta);
362  } else {
363  tempBuf[index] = b1;
364  index++;
365  tempBuf[index] = b1 + 1;
366  index++;
367  tempBuf[index] = b2 - 1;
368  index++;
369  tempBuf[index] = b2;
370  index++;
371  }
372  } else {
373  /* Generate up to 2 values outside of bounds */
374  if (b1 > minValue) {
375  tempBuf[index] = b1 - 1;
376  index++;
377  }
378 
379  if (b2 < maxValue) {
380  tempBuf[index] = b2 + 1;
381  index++;
382  }
383  }
384 
385  if (index == 0) {
386  /* There are no valid boundaries */
387  SDL_Unsupported();
388  return minValue;
389  }
390 
391  return tempBuf[SDLTest_RandomUint8() % index];
392 }
393 
394 
395 Sint8
396 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
397 {
398  /* min & max values for Sint8 */
399  const Sint64 maxValue = SCHAR_MAX;
400  const Sint64 minValue = SCHAR_MIN;
401  return (Sint8)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
402  (Sint64) boundary1, (Sint64) boundary2,
403  validDomain);
404 }
405 
406 Sint16
407 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
408 {
409  /* min & max values for Sint16 */
410  const Sint64 maxValue = SHRT_MAX;
411  const Sint64 minValue = SHRT_MIN;
412  return (Sint16)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
413  (Sint64) boundary1, (Sint64) boundary2,
414  validDomain);
415 }
416 
417 Sint32
418 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
419 {
420  /* min & max values for Sint32 */
421  #if ((ULONG_MAX) == (UINT_MAX))
422  const Sint64 maxValue = LONG_MAX;
423  const Sint64 minValue = LONG_MIN;
424  #else
425  const Sint64 maxValue = INT_MAX;
426  const Sint64 minValue = INT_MIN;
427  #endif
428  return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
429  (Sint64) boundary1, (Sint64) boundary2,
430  validDomain);
431 }
432 
433 Sint64
434 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
435 {
436  /* min & max values for Sint64 */
437  const Sint64 maxValue = LLONG_MAX;
438  const Sint64 minValue = LLONG_MIN;
439  return SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
440  boundary1, boundary2,
441  validDomain);
442 }
443 
444 float
446 {
447  return (float) SDLTest_RandomUint32() / UINT_MAX;
448 }
449 
450 float
452 {
453  return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
454 }
455 
456 double
458 {
459  return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
460 }
461 
462 double
464 {
465  double r = 0.0;
466  double s = 1.0;
467  do {
468  s /= UINT_MAX + 1.0;
469  r += (double)SDLTest_RandomInt(&rndContext) * s;
470  } while (s > DBL_EPSILON);
471 
473 
474  return r;
475 }
476 
477 
478 char *
480 {
482 }
483 
484 char *
486 {
487  int size;
488 
489  if(maxLength < 1) {
490  SDL_InvalidParamError("maxLength");
491  return NULL;
492  }
493 
494  size = (SDLTest_RandomUint32() % (maxLength + 1));
495 
496  return SDLTest_RandomAsciiStringOfSize(size);
497 }
498 
499 char *
501 {
502  char *string;
503  int counter;
504 
505 
506  if(size < 1) {
507  SDL_InvalidParamError("size");
508  return NULL;
509  }
510 
511  string = (char *)SDL_malloc((size + 1) * sizeof(char));
512  if (string==NULL) {
513  return NULL;
514  }
515 
516  for(counter = 0; counter < size; ++counter) {
517  string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
518  }
519 
520  string[counter] = '\0';
521 
523 
524  return string;
525 }
Sint8 SDLTest_RandomSint8()
Uint32 SDLTest_RandomUint32()
Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2072
GLdouble s
Definition: SDL_opengl.h:2056
GLsizei const GLchar *const * string
Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
double SDLTest_RandomDouble()
Uint8 SDLTest_RandomUint8()
char * SDLTest_RandomAsciiStringOfSize(int size)
Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:161
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
GLsizeiptr size
uint64_t Uint64
An unsigned 64-bit integer type.
Definition: SDL_stdinc.h:170
Sint32 SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
void SDLTest_RandomInit(SDLTest_RandomContext *rndContext, unsigned int xi, unsigned int ci)
Initialize random number generator with two integers.
float SDLTest_RandomFloat()
GLsizei maxLength
Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
GLsizei const GLfloat * value
int8_t Sint8
A signed 8-bit integer type.
Definition: SDL_stdinc.h:139
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:143
Uint64 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
Uint64 SDLTest_RandomUint64()
Sint32 SDLTest_RandomSint32()
char * SDLTest_RandomAsciiString()
float SDLTest_RandomUnitFloat()
Sint16 SDLTest_RandomSint16()
int32_t Sint32
Definition: SDL_stdinc.h:157
void SDLTest_FuzzerInit(Uint64 execKey)
static SDLTest_RandomContext rndContext
GLuint index
double SDLTest_RandomUnitDouble()
static int fuzzerInvocationCounter
#define NULL
Definition: begin_code.h:143
SDL_bool
Definition: SDL_stdinc.h:130
Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
#define SDLTest_RandomInt(c)
GLuint counter
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:151
#define SDL_malloc
Uint16 SDLTest_RandomUint16()
int64_t Sint64
A signed 64-bit integer type.
Definition: SDL_stdinc.h:166
char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
Sint64 SDLTest_RandomSint64()
GLboolean GLboolean GLboolean GLboolean a
int SDLTest_GetFuzzerInvocationCount()
GLboolean GLboolean GLboolean b
Sint64 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define SDL_memset
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:147
Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)