1 //===-- atof_fuzz.cpp -----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 /// Fuzzing test for llvm-libc atof implementation.
11 //===----------------------------------------------------------------------===//
12 #include "src/stdlib/atof.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
23 constexpr double MIN_NORMAL
= 0x1p
-1022;
25 bool has_hex_prefix(const uint8_t *str
) {
28 // Skip over leading whitespace
29 while (isspace(str
[index
])) {
33 if (str
[index
] == '-' || str
[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
);
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];
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
,