|
13 | 13 | #include <stddef.h>
|
14 | 14 | #include <stdint.h>
|
15 | 15 |
|
16 |
| -extern "C" int LLVMFuzzerTestTwoInputs(const uint8_t *data1, size_t size1, |
17 |
| - const uint8_t *data2, size_t size2) { |
18 |
| - // Verify each data source contains at least one character. |
19 |
| - if (!size1 || !size2) |
20 |
| - return 0; |
21 |
| - // Verify that the final character is the null terminator. |
22 |
| - if (data1[size1 - 1] != '\0' || data2[size2 - 1] != '\0') |
| 16 | +// The general structure is to take the value of the first byte, set size1 to |
| 17 | +// that value, and add the null terminator. size2 will then contain the rest of |
| 18 | +// the bytes in data. |
| 19 | +// For example, with inputs (data={2, 6, 4, 8, 0}, size=5): |
| 20 | +// size1: data[0] = 2 |
| 21 | +// data1: {2, 6} + '\0' = {2, 6, '\0'} |
| 22 | +// size2: size - size1 = 3 |
| 23 | +// data2: {4, 8, '\0'} |
| 24 | +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
| 25 | + // Verify the size is at least 1 and the data is null terminated. |
| 26 | + if (!size || data[size - 1] != '\0') |
23 | 27 | return 0;
|
24 | 28 |
|
25 |
| - const char *s1 = reinterpret_cast<const char *>(data1); |
26 |
| - const char *s2 = reinterpret_cast<const char *>(data2); |
| 29 | + const size_t size1 = (data[0] <= size ? data[0] : size); |
| 30 | + const size_t size2 = size - size1; |
27 | 31 |
|
28 |
| - const size_t minimum_size = size1 < size2 ? size1 : size2; |
| 32 | + // The first size will always be at least 1 since |
| 33 | + // we need to append the null terminator. The second size |
| 34 | + // needs to be checked since it must also contain the null |
| 35 | + // terminator. |
| 36 | + if (!size2) |
| 37 | + return 0; |
| 38 | + |
| 39 | + // Copy the data into new containers. |
| 40 | + // Add one to data1 for null terminator. |
| 41 | + uint8_t *data1 = new uint8_t[size1 + 1]; |
| 42 | + uint8_t *data2 = new uint8_t[size2]; |
| 43 | + if (!data1 || !data2) |
| 44 | + __builtin_trap(); |
29 | 45 |
|
30 |
| - // Iterate through until either the minimum size is hit, |
31 |
| - // a character is the null terminator, or the first set |
32 |
| - // of differed bytes between s1 and s2 are found. |
33 |
| - // No bytes following a null byte should be compared. |
34 | 46 | size_t i;
|
35 |
| - for (i = 0; i < minimum_size; ++i) { |
36 |
| - if (!s1[i] || s1[i] != s2[i]) |
37 |
| - break; |
38 |
| - } |
| 47 | + for (i = 0; i < size1; ++i) |
| 48 | + data1[i] = data[i]; |
| 49 | + data1[size1] = '\0'; // Add null terminator to data1. |
| 50 | + |
| 51 | + for (size_t j = 0; j < size2; ++j) |
| 52 | + data2[j] = data[i++]; |
39 | 53 |
|
40 |
| - int expected_result = s1[i] - s2[i]; |
41 |
| - int actual_result = __llvm_libc::strcmp(s1, s2); |
| 54 | + const char *s1 = reinterpret_cast<const char *>(data1); |
| 55 | + const char *s2 = reinterpret_cast<const char *>(data2); |
| 56 | + size_t k = 0; |
| 57 | + // Iterate until a null terminator is hit or the character comparison is |
| 58 | + // different. |
| 59 | + while (s1[k] && s2[k] && s1[k] == s2[k]) |
| 60 | + ++k; |
42 | 61 |
|
| 62 | + const unsigned char ch1 = static_cast<unsigned char>(s1[k]); |
| 63 | + const unsigned char ch2 = static_cast<unsigned char>(s2[k]); |
43 | 64 | // The expected result should be the difference between the first non-equal
|
44 | 65 | // characters of s1 and s2. If all characters are equal, the expected result
|
45 | 66 | // should be '\0' - '\0' = 0.
|
46 |
| - if (expected_result != actual_result) |
| 67 | + if (__llvm_libc::strcmp(s1, s2) != ch1 - ch2) |
47 | 68 | __builtin_trap();
|
48 | 69 |
|
49 | 70 | // Verify reversed operands. This should be the negated value of the previous
|
50 | 71 | // result, except of course if the previous result was zero.
|
51 |
| - expected_result = s2[i] - s1[i]; |
52 |
| - actual_result = __llvm_libc::strcmp(s2, s1); |
53 |
| - if (expected_result != actual_result) |
| 72 | + if (__llvm_libc::strcmp(s2, s1) != ch2 - ch1) |
54 | 73 | __builtin_trap();
|
55 | 74 |
|
| 75 | + delete[] data1; |
| 76 | + delete[] data2; |
56 | 77 | return 0;
|
57 | 78 | }
|
0 commit comments