This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_test_fuzzer.c
524 lines (440 loc) · 13.1 KB
1
2
/*
Simple DirectMedia Layer
3
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
22
/*
23
24
Data generators for fuzzing test data in a reproducible way.
25
26
27
28
29
*/
#include "SDL_config.h"
30
31
32
33
34
35
36
/* Visual Studio 2008 doesn't have stdint.h */
#if defined(_MSC_VER) && _MSC_VER <= 1500
#define UINT8_MAX ~(Uint8)0
#define UINT16_MAX ~(Uint16)0
#define UINT32_MAX ~(Uint32)0
#define UINT64_MAX ~(Uint64)0
#else
37
#include <stdint.h>
38
#endif
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>
#include "SDL_test.h"
46
/**
47
* Counter for fuzzer invocations
48
*/
49
static int fuzzerInvocationCounter = 0;
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
* Context for shared random number generator
*/
static SDLTest_RandomContext rndContext;
/*
* Note: doxygen documentation markup for functions is in the header file.
*/
void
SDLTest_FuzzerInit(Uint64 execKey)
{
63
64
65
66
67
Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF;
Uint32 b = execKey & 0x00000000FFFFFFFF;
SDL_memset((void *)&rndContext, 0, sizeof(SDLTest_RandomContext));
SDLTest_RandomInit(&rndContext, a, b);
fuzzerInvocationCounter = 0;
68
69
70
}
int
71
SDLTest_GetFuzzerInvocationCount()
72
{
73
return fuzzerInvocationCounter;
74
75
76
77
78
}
Uint8
SDLTest_RandomUint8()
{
79
fuzzerInvocationCounter++;
80
81
return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
82
83
84
85
86
}
Sint8
SDLTest_RandomSint8()
{
87
fuzzerInvocationCounter++;
88
89
return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
90
91
92
93
94
}
Uint16
SDLTest_RandomUint16()
{
95
fuzzerInvocationCounter++;
96
97
return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
98
99
100
101
102
}
Sint16
SDLTest_RandomSint16()
{
103
fuzzerInvocationCounter++;
104
105
return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
106
107
108
109
110
}
Sint32
SDLTest_RandomSint32()
{
111
fuzzerInvocationCounter++;
112
113
return (Sint32) SDLTest_RandomInt(&rndContext);
114
115
116
117
118
}
Uint32
SDLTest_RandomUint32()
{
119
fuzzerInvocationCounter++;
120
121
return (Uint32) SDLTest_RandomInt(&rndContext);
122
123
124
125
126
}
Uint64
SDLTest_RandomUint64()
{
127
128
Uint64 value = 0;
Uint32 *vp = (void *)&value;
129
130
fuzzerInvocationCounter++;
131
132
133
vp[0] = SDLTest_RandomSint32();
vp[1] = SDLTest_RandomSint32();
134
135
return value;
136
137
138
139
140
}
Sint64
SDLTest_RandomSint64()
{
141
142
Uint64 value = 0;
Uint32 *vp = (void *)&value;
143
144
fuzzerInvocationCounter++;
145
146
147
vp[0] = SDLTest_RandomSint32();
vp[1] = SDLTest_RandomSint32();
148
149
return value;
150
151
152
153
154
155
156
}
Sint32
SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
{
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
Sint64 min = pMin;
Sint64 max = pMax;
Sint64 temp;
Sint64 number;
if(pMin > pMax) {
temp = min;
min = max;
max = temp;
} else if(pMin == pMax) {
return (Sint32)min;
}
number = SDLTest_RandomUint32();
/* invocation count increment in preceeding call */
return (Sint32)((number % ((max + 1) - min)) + min);
174
175
176
}
/*!
177
* Generates a unsigned boundary value between the given boundaries.
178
179
180
181
182
* Boundary values are inclusive. See the examples below.
* If boundary2 < boundary1, the values are swapped.
* If boundary1 == boundary2, value of boundary1 will be returned
*
* Generating boundary values for Uint8:
183
184
185
186
187
* BoundaryValues(UINT8_MAX, 10, 20, True) -> [10,11,19,20]
* BoundaryValues(UINT8_MAX, 10, 20, False) -> [9,21]
* BoundaryValues(UINT8_MAX, 0, 15, True) -> [0, 1, 14, 15]
* BoundaryValues(UINT8_MAX, 0, 15, False) -> [16]
* BoundaryValues(UINT8_MAX, 0, 0xFF, False) -> [0], error set
188
189
190
191
*
* Generator works the same for other types of unsigned integers.
*
* \param maxValue The biggest value that is acceptable for this data type.
192
* For instance, for Uint8 -> 255, Uint16 -> 65536 etc.
193
194
* \param boundary1 defines lower boundary
* \param boundary2 defines upper boundary
195
196
* \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
198
*/
199
200
Uint64
SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
201
{
202
Uint64 b1, b2;
203
204
205
206
Uint64 delta;
Uint64 tempBuf[4];
Uint8 index;
207
/* Maybe swap */
208
209
210
211
212
213
if (boundary1 > boundary2) {
b1 = boundary2;
b2 = boundary1;
} else {
b1 = boundary1;
b2 = boundary2;
214
}
215
216
217
218
219
220
221
222
223
224
225
226
227
index = 0;
if (validDomain == SDL_TRUE) {
if (b1 == b2) {
return b1;
}
/* Generate up to 4 values within bounds */
delta = b2 - b1;
if (delta < 4) {
do {
tempBuf[index] = b1 + index;
index++;
228
} while (index < delta);
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
} else {
tempBuf[index] = b1;
index++;
tempBuf[index] = b1 + 1;
index++;
tempBuf[index] = b2 - 1;
index++;
tempBuf[index] = b2;
index++;
}
} else {
/* Generate up to 2 values outside of bounds */
if (b1 > 0) {
tempBuf[index] = b1 - 1;
index++;
}
if (b2 < maxValue) {
tempBuf[index] = b2 + 1;
index++;
}
}
if (index == 0) {
/* There are no valid boundaries */
SDL_Unsupported();
return 0;
}
return tempBuf[SDLTest_RandomUint8() % index];
259
260
}
261
262
263
264
Uint8
SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
{
265
266
267
268
269
/* max value for Uint8 */
const Uint64 maxValue = UCHAR_MAX;
return (Uint8)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
(Uint64) boundary1, (Uint64) boundary2,
validDomain);
270
271
272
273
274
}
Uint16
SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
{
275
276
277
278
279
/* max value for Uint16 */
const Uint64 maxValue = USHRT_MAX;
return (Uint16)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
(Uint64) boundary1, (Uint64) boundary2,
validDomain);
280
281
282
283
284
}
Uint32
SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
{
285
286
287
/* max value for Uint32 */
#if ((ULONG_MAX) == (UINT_MAX))
const Uint64 maxValue = ULONG_MAX;
288
#else
289
const Uint64 maxValue = UINT_MAX;
290
#endif
291
292
293
return (Uint32)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
(Uint64) boundary1, (Uint64) boundary2,
validDomain);
294
295
296
297
298
}
Uint64
SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
{
299
300
301
302
303
/* max value for Uint64 */
const Uint64 maxValue = ULLONG_MAX;
return SDLTest_GenerateUnsignedBoundaryValues(maxValue,
(Uint64) boundary1, (Uint64) boundary2,
validDomain);
304
305
306
}
/*!
307
* Generates a signed boundary value between the given boundaries.
308
309
310
311
312
* Boundary values are inclusive. See the examples below.
* If boundary2 < boundary1, the values are swapped.
* If boundary1 == boundary2, value of boundary1 will be returned
*
* Generating boundary values for Sint8:
313
314
315
316
317
* SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, True) -> [-10,-9,19,20]
* SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, False) -> [-11,21]
* SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -30, -15, True) -> [-30, -29, -16, -15]
* SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 15, False) -> [16]
* SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 127, False) -> [0], error set
318
319
320
*
* 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
326
* \param boundary1 defines lower boundary
* \param boundary2 defines upper boundary
327
328
* \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
330
*/
331
332
Sint64
SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
333
{
334
Sint64 b1, b2;
335
336
337
338
Sint64 delta;
Sint64 tempBuf[4];
Uint8 index;
339
/* Maybe swap */
340
341
342
343
344
345
if (boundary1 > boundary2) {
b1 = boundary2;
b2 = boundary1;
} else {
b1 = boundary1;
b2 = boundary2;
346
}
347
348
349
350
351
352
353
354
355
356
357
358
359
index = 0;
if (validDomain == SDL_TRUE) {
if (b1 == b2) {
return b1;
}
/* Generate up to 4 values within bounds */
delta = b2 - b1;
if (delta < 4) {
do {
tempBuf[index] = b1 + index;
index++;
360
} while (index < delta);
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
} else {
tempBuf[index] = b1;
index++;
tempBuf[index] = b1 + 1;
index++;
tempBuf[index] = b2 - 1;
index++;
tempBuf[index] = b2;
index++;
}
} else {
/* Generate up to 2 values outside of bounds */
if (b1 > minValue) {
tempBuf[index] = b1 - 1;
index++;
}
if (b2 < maxValue) {
tempBuf[index] = b2 + 1;
index++;
}
}
if (index == 0) {
/* There are no valid boundaries */
SDL_Unsupported();
return minValue;
}
return tempBuf[SDLTest_RandomUint8() % index];
391
392
}
393
394
395
396
Sint8
SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
{
397
398
399
400
401
402
/* min & max values for Sint8 */
const Sint64 maxValue = SCHAR_MAX;
const Sint64 minValue = SCHAR_MIN;
return (Sint8)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
(Sint64) boundary1, (Sint64) boundary2,
validDomain);
403
404
405
406
407
}
Sint16
SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
{
408
409
410
411
412
413
/* min & max values for Sint16 */
const Sint64 maxValue = SHRT_MAX;
const Sint64 minValue = SHRT_MIN;
return (Sint16)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
(Sint64) boundary1, (Sint64) boundary2,
validDomain);
414
415
416
417
418
}
Sint32
SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
{
419
420
421
422
/* min & max values for Sint32 */
#if ((ULONG_MAX) == (UINT_MAX))
const Sint64 maxValue = LONG_MAX;
const Sint64 minValue = LONG_MIN;
423
#else
424
425
const Sint64 maxValue = INT_MAX;
const Sint64 minValue = INT_MIN;
426
#endif
427
428
429
return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
(Sint64) boundary1, (Sint64) boundary2,
validDomain);
430
431
432
433
434
}
Sint64
SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
{
435
436
437
438
439
440
/* min & max values for Sint64 */
const Sint64 maxValue = LLONG_MAX;
const Sint64 minValue = LLONG_MIN;
return SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
boundary1, boundary2,
validDomain);
441
442
443
444
445
}
float
SDLTest_RandomUnitFloat()
{
446
return (float) SDLTest_RandomUint32() / UINT_MAX;
447
448
449
450
451
}
float
SDLTest_RandomFloat()
{
452
return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
453
454
455
456
457
}
double
SDLTest_RandomUnitDouble()
{
458
return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
459
460
461
462
463
}
double
SDLTest_RandomDouble()
{
464
465
466
467
468
469
470
471
472
473
double r = 0.0;
double s = 1.0;
do {
s /= UINT_MAX + 1.0;
r += (double)SDLTest_RandomInt(&rndContext) * s;
} while (s > DBL_EPSILON);
fuzzerInvocationCounter++;
return r;
474
475
476
477
478
479
}
char *
SDLTest_RandomAsciiString()
{
480
return SDLTest_RandomAsciiStringWithMaximumLength(255);
481
482
483
}
char *
484
SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
485
{
486
int size;
487
488
if(maxLength < 1) {
489
SDL_InvalidParamError("maxLength");
490
491
492
493
return NULL;
}
size = (SDLTest_RandomUint32() % (maxLength + 1));
494
495
return SDLTest_RandomAsciiStringOfSize(size);
496
497
498
499
500
}
char *
SDLTest_RandomAsciiStringOfSize(int size)
{
501
502
char *string;
int counter;
503
504
505
if(size < 1) {
506
SDL_InvalidParamError("size");
507
508
return NULL;
}
509
510
511
512
string = (char *)SDL_malloc((size + 1) * sizeof(char));
if (string==NULL) {
return NULL;
513
514
}
515
516
517
for(counter = 0; counter < size; ++counter) {
string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
}
518
519
string[counter] = '\0';
520
521
fuzzerInvocationCounter++;
522
523
return string;
524
}