From 87c016078ad72c46505461e4ff8bfa04819fe7ba Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Wed, 1 Sep 2021 23:51:05 +0000 Subject: [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 --- libc/fuzzing/stdlib/CMakeLists.txt | 10 ++++++++ libc/fuzzing/stdlib/StringParserOutputDiff.h | 35 ++++++++++++++++++++++++++++ libc/fuzzing/stdlib/atof_fuzz.cpp | 32 +++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 libc/fuzzing/stdlib/StringParserOutputDiff.h create mode 100644 libc/fuzzing/stdlib/atof_fuzz.cpp (limited to 'libc/fuzzing') diff --git a/libc/fuzzing/stdlib/CMakeLists.txt b/libc/fuzzing/stdlib/CMakeLists.txt index db827f5..436125b 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 0000000..457da3b --- /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 +#include + +template using StringInputSingleOutputFunc = T (*)(const char *); + +template +void StringParserOutputDiff(StringInputSingleOutputFunc func1, + StringInputSingleOutputFunc func2, + const uint8_t *data, size_t size) { + if (size < sizeof(T)) + return; + + const char *x = reinterpret_cast(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 0000000..b368129 --- /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 +#include +#include + +#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(&__llvm_libc::atof, &::atof, container, size); + delete[] container; + return 0; +} -- cgit v1.1