diff options
author | Michael Jones <michaelrj@google.com> | 2021-09-01 23:51:05 +0000 |
---|---|---|
committer | Michael Jones <michaelrj@google.com> | 2021-10-18 16:10:03 -0700 |
commit | 87c016078ad72c46505461e4ff8bfa04819fe7ba (patch) | |
tree | 91521ff2bbe9ef913e20e0636ee8e7f0d96861f5 /libc/fuzzing | |
parent | 684b6265b31cabf422b01cd8937a3641c6df914f (diff) | |
download | llvm-87c016078ad72c46505461e4ff8bfa04819fe7ba.tar.gz |
[libc] add atof, strtof and strtod
Add the string to floating point conversion functions.
Long doubles aren't supported yet, but floats and doubles are. The
primary algorithm used is the Eisel-Lemire ParseNumberF64 algorithm,
with the Simple Decimal Conversion algorithm as backup.
Links for more information on the algorithms:
Number Parsing at a Gigabyte per Second, Software: Practice and
Experience 51 (8), 2021 (https://arxiv.org/abs/2101.11408)
https://nigeltao.github.io/blog/2020/eisel-lemire.html
https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
Differential Revision: https://reviews.llvm.org/D109261
Diffstat (limited to 'libc/fuzzing')
-rw-r--r-- | libc/fuzzing/stdlib/CMakeLists.txt | 10 | ||||
-rw-r--r-- | libc/fuzzing/stdlib/StringParserOutputDiff.h | 35 | ||||
-rw-r--r-- | libc/fuzzing/stdlib/atof_fuzz.cpp | 32 |
3 files changed, 77 insertions, 0 deletions
diff --git a/libc/fuzzing/stdlib/CMakeLists.txt b/libc/fuzzing/stdlib/CMakeLists.txt index db827f57075f..436125b6cd7a 100644 --- a/libc/fuzzing/stdlib/CMakeLists.txt +++ b/libc/fuzzing/stdlib/CMakeLists.txt @@ -6,3 +6,13 @@ add_libc_fuzzer( libc.src.stdlib.qsort ) +add_libc_fuzzer( + atof_fuzz + SRCS + atof_fuzz.cpp + HDRS + StringParserOutputDiff.h + DEPENDS + libc.src.stdlib.atof +) + diff --git a/libc/fuzzing/stdlib/StringParserOutputDiff.h b/libc/fuzzing/stdlib/StringParserOutputDiff.h new file mode 100644 index 000000000000..457da3b5674b --- /dev/null +++ b/libc/fuzzing/stdlib/StringParserOutputDiff.h @@ -0,0 +1,35 @@ +//===-- Template to diff single-input-single-output functions ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_FUZZING_STDLIB_STRING_PARSER_OUTPUT_DIFF_H +#define LLVM_LIBC_FUZZING_STDLIB_STRING_PARSER_OUTPUT_DIFF_H + +#include "fuzzing/math/Compare.h" + +#include <stddef.h> +#include <stdint.h> + +template <typename T> using StringInputSingleOutputFunc = T (*)(const char *); + +template <typename T> +void StringParserOutputDiff(StringInputSingleOutputFunc<T> func1, + StringInputSingleOutputFunc<T> func2, + const uint8_t *data, size_t size) { + if (size < sizeof(T)) + return; + + const char *x = reinterpret_cast<const char *>(data); + + T result1 = func1(x); + T result2 = func2(x); + + if (!ValuesEqual(result1, result2)) + __builtin_trap(); +} + +#endif // LLVM_LIBC_FUZZING_STDLIB_STRING_PARSER_OUTPUT_DIFF_H diff --git a/libc/fuzzing/stdlib/atof_fuzz.cpp b/libc/fuzzing/stdlib/atof_fuzz.cpp new file mode 100644 index 000000000000..b368129960d3 --- /dev/null +++ b/libc/fuzzing/stdlib/atof_fuzz.cpp @@ -0,0 +1,32 @@ +//===-- atof_fuzz.cpp -----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// Fuzzing test for llvm-libc atof implementation. +/// +//===----------------------------------------------------------------------===// +#include "src/stdlib/atof.h" +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include "fuzzing/stdlib/StringParserOutputDiff.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + uint8_t *container = new uint8_t[size + 1]; + if (!container) + __builtin_trap(); + size_t i; + + for (i = 0; i < size; ++i) + container[i] = data[i]; + container[size] = '\0'; // Add null terminator to container. + + StringParserOutputDiff<double>(&__llvm_libc::atof, &::atof, container, size); + delete[] container; + return 0; +} |