SDL  2.0
SDL_test_fuzzer.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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  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 
143 Sint64
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 
162 Sint32
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  */
207 static Uint64
208 SDLTest_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 */
262  SDL_Unsupported();
263  return 0;
264  }
265 
266  return tempBuf[SDLTest_RandomUint8() % index];
267 }
268 
269 
270 Uint8
271 SDLTest_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 
280 Uint16
281 SDLTest_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 
290 Uint32
291 SDLTest_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 
304 Uint64
305 SDLTest_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  */
339 static Sint64
340 SDLTest_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 */
394  SDL_Unsupported();
395  return minValue;
396  }
397 
398  return tempBuf[SDLTest_RandomUint8() % index];
399 }
400 
401 
402 Sint8
403 SDLTest_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 
413 Sint16
414 SDLTest_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 
424 Sint32
425 SDLTest_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 
440 Sint64
441 SDLTest_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 
451 float
453 {
454  return SDLTest_RandomUint32() / (float) UINT_MAX;
455 }
456 
457 float
459 {
460  return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
461 }
462 
463 double
465 {
466  return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
467 }
468 
469 double
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 
485 char *
487 {
489 }
490 
491 char *
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 
503  return SDLTest_RandomAsciiStringOfSize(size);
504 }
505 
506 char *
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: */
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
Definition: SDL_stdinc.h:181
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
uint64_t Uint64
Definition: SDL_stdinc.h:194
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
Definition: SDL_stdinc.h:151
uint8_t Uint8
Definition: SDL_stdinc.h:157
Uint64 SDLTest_RandomUint64()
GLsizei const GLfloat * value
Sint32 SDLTest_RandomSint32()
char * SDLTest_RandomAsciiString()
float SDLTest_RandomUnitFloat()
Sint16 SDLTest_RandomSint16()
int32_t Sint32
Definition: SDL_stdinc.h:175
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
Definition: SDL_stdinc.h:169
static Uint64 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
#define SDL_malloc
Uint16 SDLTest_RandomUint16()
int64_t Sint64
Definition: SDL_stdinc.h:188
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
Definition: SDL_stdinc.h:163
Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)