[NFC][Py Reformat] Reformat python files in llvm
[llvm-project.git] / libc / fuzzing / stdlib / atof_differential_fuzz.cpp
blob2f330e1af2e32d2e0e8d0831e88a2e94f329631e
1 //===-- atof_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/atof.h"
13 #include <stddef.h>
14 #include <stdint.h>
15 #include <stdlib.h>
17 #include "fuzzing/stdlib/StringParserOutputDiff.h"
19 // TODO: Remove this once glibc fixes hex subnormal rounding. See
20 // https://sourceware.org/bugzilla/show_bug.cgi?id=30220
21 #ifdef LLVM_LIBC_ATOF_DIF_FUZZ_SKIP_GLIBC_HEX_SUBNORMAL_ERR
22 #include <ctype.h>
23 constexpr double MIN_NORMAL = 0x1p-1022;
25 bool has_hex_prefix(const uint8_t *str) {
26 size_t index = 0;
28 // Skip over leading whitespace
29 while (isspace(str[index])) {
30 ++index;
32 // Skip over sign
33 if (str[index] == '-' || str[index] == '+') {
34 ++index;
36 return str[index] == '0' && (tolower(str[index + 1])) == 'x';
39 bool should_be_skipped(const uint8_t *str) {
40 double init_result = ::atof(reinterpret_cast<const char *>(str));
41 if (init_result < 0) {
42 init_result = -init_result;
44 if (init_result < MIN_NORMAL && init_result != 0) {
45 return has_hex_prefix(str);
47 return false;
49 #else
50 bool should_be_skipped(const uint8_t *) { return false; }
51 #endif // LLVM_LIBC_ATOF_DIF_FUZZ_SKIP_GLIBC_HEX_SUBNORMAL_ERR
53 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
54 uint8_t *container = new uint8_t[size + 1];
55 if (!container)
56 __builtin_trap();
57 size_t i;
59 for (i = 0; i < size; ++i)
60 container[i] = data[i];
61 container[size] = '\0'; // Add null terminator to container.
63 if (!should_be_skipped(container)) {
64 StringParserOutputDiff<double>(&__llvm_libc::atof, &::atof, container,
65 size);
67 delete[] container;
68 return 0;