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) · 12.2 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
22
23
24
25
26
27
28
29
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.
*/
/*
Data generators for fuzzing test data in a reproducible way.
*/
#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
46
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>
#include "SDL_test.h"
/**
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
Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF;
64
Uint32 b = execKey & 0x00000000FFFFFFFF;
65
SDL_memset((void *)&rndContext, 0, sizeof(SDLTest_RandomContext));
66
SDLTest_RandomInit(&rndContext, a, b);
67
fuzzerInvocationCounter = 0;
68
69
70
}
int
71
SDLTest_GetFuzzerInvocationCount()
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
{
return fuzzerInvocationCounter;
}
Uint8
SDLTest_RandomUint8()
{
fuzzerInvocationCounter++;
return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
}
Sint8
SDLTest_RandomSint8()
{
fuzzerInvocationCounter++;
return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
}
Uint16
SDLTest_RandomUint16()
{
fuzzerInvocationCounter++;
return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
}
Sint16
SDLTest_RandomSint16()
{
fuzzerInvocationCounter++;
return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
}
Sint32
SDLTest_RandomSint32()
{
fuzzerInvocationCounter++;
return (Sint32) SDLTest_RandomInt(&rndContext);
}
Uint32
SDLTest_RandomUint32()
{
fuzzerInvocationCounter++;
return (Uint32) SDLTest_RandomInt(&rndContext);
}
Uint64
SDLTest_RandomUint64()
{
127
128
Uint64 value = 0;
Uint32 *vp = (void *)&value;
129
130
131
132
133
134
135
136
137
138
139
140
fuzzerInvocationCounter++;
vp[0] = SDLTest_RandomSint32();
vp[1] = SDLTest_RandomSint32();
return value;
}
Sint64
SDLTest_RandomSint64()
{
141
142
Uint64 value = 0;
Uint32 *vp = (void *)&value;
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
fuzzerInvocationCounter++;
vp[0] = SDLTest_RandomSint32();
vp[1] = SDLTest_RandomSint32();
return value;
}
Sint32
SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
{
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;
}
170
171
number = SDLTest_RandomUint32();
/* invocation count increment in preceeding call */
172
173
174
175
176
return (Sint32)((number % ((max + 1) - min)) + min);
}
/*!
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
192
*
* Generator works the same for other types of unsigned integers.
*
* \param maxValue The biggest value that is acceptable for this data type.
* 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
203
Uint64 b1, b2;
Uint64 delta;
204
Uint64 tempBuf[4];
205
206
207
208
209
210
211
212
213
214
Uint8 index;
/* Maybe swap */
if (boundary1 > boundary2) {
b1 = boundary2;
b2 = boundary1;
} else {
b1 = boundary1;
b2 = boundary2;
}
215
216
index = 0;
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
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++;
} while (index < delta);
} 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++;
244
245
}
246
247
248
if (b2 < maxValue) {
tempBuf[index] = b2 + 1;
index++;
249
250
251
}
}
252
253
if (index == 0) {
/* There are no valid boundaries */
254
SDL_Unsupported();
255
256
257
return 0;
}
258
return tempBuf[SDLTest_RandomUint8() % index];
259
260
}
261
262
263
264
Uint8
SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
{
265
266
267
/* max value for Uint8 */
const Uint64 maxValue = UCHAR_MAX;
return (Uint8)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
268
(Uint64) boundary1, (Uint64) boundary2,
269
validDomain);
270
271
272
273
274
}
Uint16
SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
{
275
276
277
/* max value for Uint16 */
const Uint64 maxValue = USHRT_MAX;
return (Uint16)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
278
(Uint64) boundary1, (Uint64) boundary2,
279
validDomain);
280
281
282
283
284
}
Uint32
SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
{
285
/* max value for Uint32 */
286
287
288
289
290
#if ((ULONG_MAX) == (UINT_MAX))
const Uint64 maxValue = ULONG_MAX;
#else
const Uint64 maxValue = UINT_MAX;
#endif
291
return (Uint32)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
292
(Uint64) boundary1, (Uint64) boundary2,
293
validDomain);
294
295
296
297
298
}
Uint64
SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
{
299
300
301
/* max value for Uint64 */
const Uint64 maxValue = ULLONG_MAX;
return SDLTest_GenerateUnsignedBoundaryValues(maxValue,
302
(Uint64) boundary1, (Uint64) boundary2,
303
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
322
* \param minValue The smallest value that is acceptable for this data type.
* For instance, for Uint8 -> -127, etc.
323
* \param maxValue The biggest value that is acceptable for this data type.
324
325
326
* For instance, for Uint8 -> 127, etc.
* \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
335
Sint64 b1, b2;
Sint64 delta;
336
Sint64 tempBuf[4];
337
338
339
340
341
342
343
344
345
346
Uint8 index;
/* Maybe swap */
if (boundary1 > boundary2) {
b1 = boundary2;
b2 = boundary1;
} else {
b1 = boundary1;
b2 = boundary2;
}
347
348
index = 0;
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
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++;
} while (index < delta);
} 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++;
376
377
}
378
379
380
if (b2 < maxValue) {
tempBuf[index] = b2 + 1;
index++;
381
382
383
}
}
384
385
if (index == 0) {
/* There are no valid boundaries */
386
SDL_Unsupported();
387
return minValue;
388
389
}
390
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
/* min & max values for Sint8 */
const Sint64 maxValue = SCHAR_MAX;
const Sint64 minValue = SCHAR_MIN;
return (Sint8)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
401
(Sint64) boundary1, (Sint64) boundary2,
402
validDomain);
403
404
405
406
407
}
Sint16
SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
{
408
/* min & max values for Sint16 */
409
410
const Sint64 maxValue = SHRT_MAX;
const Sint64 minValue = SHRT_MIN;
411
412
413
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
/* min & max values for Sint32 */
420
421
422
423
424
425
426
#if ((ULONG_MAX) == (UINT_MAX))
const Sint64 maxValue = LONG_MAX;
const Sint64 minValue = LONG_MIN;
#else
const Sint64 maxValue = INT_MAX;
const Sint64 minValue = INT_MIN;
#endif
427
return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
428
(Sint64) boundary1, (Sint64) boundary2,
429
validDomain);
430
431
432
433
434
}
Sint64
SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
{
435
/* min & max values for Sint64 */
436
437
const Sint64 maxValue = LLONG_MAX;
const Sint64 minValue = LLONG_MIN;
438
439
440
return SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
boundary1, boundary2,
validDomain);
441
442
443
444
445
446
447
448
449
450
451
}
float
SDLTest_RandomUnitFloat()
{
return (float) SDLTest_RandomUint32() / UINT_MAX;
}
float
SDLTest_RandomFloat()
{
452
return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
}
double
SDLTest_RandomUnitDouble()
{
return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
}
double
SDLTest_RandomDouble()
{
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;
}
char *
SDLTest_RandomAsciiString()
{
return SDLTest_RandomAsciiStringWithMaximumLength(255);
}
char *
484
SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
485
486
{
int size;
487
488
489
490
491
492
493
494
495
496
497
498
499
500
if(maxLength < 1) {
SDL_InvalidParamError("maxLength");
return NULL;
}
size = (SDLTest_RandomUint32() % (maxLength + 1));
return SDLTest_RandomAsciiStringOfSize(size);
}
char *
SDLTest_RandomAsciiStringOfSize(int size)
{
501
502
503
504
char *string;
int counter;
505
506
if(size < 1) {
SDL_InvalidParamError("size");
507
508
509
return NULL;
}
510
string = (char *)SDL_malloc((size + 1) * sizeof(char));
511
512
513
514
515
if (string==NULL) {
return NULL;
}
for(counter = 0; counter < size; ++counter) {
516
string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
517
518
519
520
}
string[counter] = '\0';
521
522
fuzzerInvocationCounter++;
523
524
return string;
}