1 | //===-- strtointeger_differential_fuzz.cpp --------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// |
9 | /// Fuzzing test for llvm-libc atof implementation. |
10 | /// |
11 | //===----------------------------------------------------------------------===// |
12 | #include "src/stdlib/atoi.h" |
13 | #include "src/stdlib/atol.h" |
14 | #include "src/stdlib/atoll.h" |
15 | #include "src/stdlib/strtol.h" |
16 | #include "src/stdlib/strtoll.h" |
17 | #include "src/stdlib/strtoul.h" |
18 | #include "src/stdlib/strtoull.h" |
19 | #include <stddef.h> |
20 | #include <stdint.h> |
21 | #include <stdlib.h> |
22 | |
23 | #include "fuzzing/stdlib/StringParserOutputDiff.h" |
24 | |
25 | // This list contains (almost) all character that can possibly be accepted by a |
26 | // string to integer conversion. Those are: space, tab, +/- signs, any digit, |
27 | // and any letter. Technically there are some space characters accepted by |
28 | // isspace that aren't in this list, but since space characters are just skipped |
29 | // over anyways I'm not really worried. |
30 | [[maybe_unused]] constexpr char VALID_CHARS[] = { |
31 | ' ', '\t', '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', |
32 | 'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'f', 'F', 'g', 'G', |
33 | 'h', 'H', 'i', 'I', 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N', |
34 | 'o', 'O', 'p', 'P', 'q', 'Q', 'r', 'R', 's', 'S', 't', 'T', 'u', 'U', |
35 | 'v', 'V', 'w', 'W', 'x', 'X', 'y', 'Y', 'z', 'Z'}; |
36 | |
37 | // This takes the randomized bytes in data and interprets the first byte as the |
38 | // base for the string to integer conversion and the rest of them as a string to |
39 | // be passed to the string to integer conversion. |
40 | // If the CLEANER_INPUT flag is set, the string is modified so that it's only |
41 | // made of characters that the string to integer functions could accept. This is |
42 | // because every other character is effectively identical, and will be treated |
43 | // as the end of the integer. For the fully randomized string this gives a |
44 | // greater than 50% chance for each character to end the string, making the odds |
45 | // of getting long numbers very low. |
46 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
47 | uint8_t *container = new uint8_t[size + 1]; |
48 | if (!container) |
49 | __builtin_trap(); |
50 | size_t i; |
51 | |
52 | for (i = 0; i < size; ++i) { |
53 | #ifdef LIBC_COPT_FUZZ_ATOI_CLEANER_INPUT |
54 | container[i] = VALID_CHARS[data[i] % sizeof(VALID_CHARS)]; |
55 | #else |
56 | container[i] = data[i]; |
57 | #endif |
58 | } |
59 | container[size] = '\0'; // Add null terminator to container. |
60 | // the first character is interpreted as the base, so it should be fully |
61 | // random even when the input is cleaned. |
62 | container[0] = data[0]; |
63 | |
64 | StringParserOutputDiff<int>(func1: &LIBC_NAMESPACE::atoi, func2: &::atoi, data: container, size); |
65 | StringParserOutputDiff<long>(func1: &LIBC_NAMESPACE::atol, func2: &::atol, data: container, size); |
66 | StringParserOutputDiff<long long>(func1: &LIBC_NAMESPACE::atoll, func2: &::atoll, data: container, |
67 | size); |
68 | |
69 | StringToNumberOutputDiff<long>(func1: &LIBC_NAMESPACE::strtol, func2: &::strtol, data: container, |
70 | size); |
71 | StringToNumberOutputDiff<long long>(func1: &LIBC_NAMESPACE::strtoll, func2: &::strtoll, |
72 | data: container, size); |
73 | |
74 | StringToNumberOutputDiff<unsigned long>(func1: &LIBC_NAMESPACE::strtoul, func2: &::strtoul, |
75 | data: container, size); |
76 | StringToNumberOutputDiff<unsigned long long>(func1: &LIBC_NAMESPACE::strtoull, |
77 | func2: &::strtoull, data: container, size); |
78 | |
79 | delete[] container; |
80 | return 0; |
81 | } |
82 | |