summaryrefslogtreecommitdiff
path: root/libc/fuzzing
diff options
context:
space:
mode:
authorMichael Jones <michaelrj@google.com>2021-09-01 23:51:05 +0000
committerMichael Jones <michaelrj@google.com>2021-10-18 16:10:03 -0700
commit87c016078ad72c46505461e4ff8bfa04819fe7ba (patch)
tree91521ff2bbe9ef913e20e0636ee8e7f0d96861f5 /libc/fuzzing
parent684b6265b31cabf422b01cd8937a3641c6df914f (diff)
downloadllvm-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.txt10
-rw-r--r--libc/fuzzing/stdlib/StringParserOutputDiff.h35
-rw-r--r--libc/fuzzing/stdlib/atof_fuzz.cpp32
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;
+}