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