diff --git a/libc/fuzzing/stdlib/CMakeLists.txt b/libc/fuzzing/stdlib/CMakeLists.txt --- a/libc/fuzzing/stdlib/CMakeLists.txt +++ b/libc/fuzzing/stdlib/CMakeLists.txt @@ -16,6 +16,17 @@ libc.src.stdlib.atof ) +add_libc_fuzzer( + strtofloat_fuzz + SRCS + strtofloat_fuzz.cpp + DEPENDS + libc.src.stdlib.atof + libc.src.stdlib.strtof + libc.src.stdlib.strtod + libc.src.stdlib.strtold +) + add_libc_fuzzer( strtointeger_differential_fuzz SRCS @@ -49,3 +60,17 @@ COMPILE_OPTIONS -DLLVM_LIBC_FUZZ_ATOI_CLEANER_INPUT ) + +add_libc_fuzzer( + strtointeger_fuzz + SRCS + strtointeger_fuzz.cpp + DEPENDS + libc.src.stdlib.atoi + libc.src.stdlib.atol + libc.src.stdlib.atoll + libc.src.stdlib.strtol + libc.src.stdlib.strtoll + libc.src.stdlib.strtoul + libc.src.stdlib.strtoull +) diff --git a/libc/fuzzing/stdlib/strtofloat_fuzz.cpp b/libc/fuzzing/stdlib/strtofloat_fuzz.cpp new file mode 100644 --- /dev/null +++ b/libc/fuzzing/stdlib/strtofloat_fuzz.cpp @@ -0,0 +1,49 @@ +//===-- strtofloat_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 "src/stdlib/strtod.h" +#include "src/stdlib/strtof.h" +#include "src/stdlib/strtold.h" +#include +#include + +// This takes the randomized bytes in data and interprets the first byte as the +// base for the string to integer conversion and the rest of them as a string to +// be passed to the string to integer conversion. +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. + + const char *str_ptr = reinterpret_cast(container); + + char *out_ptr = nullptr; + + auto volatile atof_output = __llvm_libc::atof(str_ptr); + auto volatile strtof_output = __llvm_libc::strtof(str_ptr, &out_ptr); + if (str_ptr + size < out_ptr) + __builtin_trap(); + auto volatile strtod_output = __llvm_libc::strtod(str_ptr, &out_ptr); + if (str_ptr + size < out_ptr) + __builtin_trap(); + auto volatile strtold_output = __llvm_libc::strtold(str_ptr, &out_ptr); + if (str_ptr + size < out_ptr) + __builtin_trap(); + + delete[] container; + return 0; +} diff --git a/libc/fuzzing/stdlib/strtointeger_fuzz.cpp b/libc/fuzzing/stdlib/strtointeger_fuzz.cpp new file mode 100644 --- /dev/null +++ b/libc/fuzzing/stdlib/strtointeger_fuzz.cpp @@ -0,0 +1,70 @@ +//===-- strtointeger_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/atoi.h" +#include "src/stdlib/atol.h" +#include "src/stdlib/atoll.h" +#include "src/stdlib/strtol.h" +#include "src/stdlib/strtoll.h" +#include "src/stdlib/strtoul.h" +#include "src/stdlib/strtoull.h" +#include +#include + +// This takes the randomized bytes in data and interprets the first byte as the +// base for the string to integer conversion and the rest of them as a string to +// be passed to the string to integer conversion. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + size_t container_size = 0; + if (size == 0) { + container_size = 1; + } else { + container_size = size; + } + uint8_t *container = new uint8_t[container_size]; + if (!container) + __builtin_trap(); + + int base = 0; + if (size > 0) { + base = data[0] % 36; + base = base + ((base == 0) ? 0 : 1); + } + for (size_t i = 1; i < size; ++i) { + container[i - 1] = data[i]; + } + + container[container_size - 1] = '\0'; // Add null terminator to container. + + const char *str_ptr = reinterpret_cast(container); + + char *out_ptr = nullptr; + + auto volatile atoi_output = __llvm_libc::atoi(str_ptr); + auto volatile atol_output = __llvm_libc::atol(str_ptr); + auto volatile atoll_output = __llvm_libc::atoll(str_ptr); + auto volatile strtol_output = __llvm_libc::strtol(str_ptr, &out_ptr, base); + if (str_ptr + container_size - 1 < out_ptr) + __builtin_trap(); + auto volatile strtoll_output = __llvm_libc::strtoll(str_ptr, &out_ptr, base); + if (str_ptr + container_size - 1 < out_ptr) + __builtin_trap(); + auto volatile strtoul_output = __llvm_libc::strtoul(str_ptr, &out_ptr, base); + if (str_ptr + container_size - 1 < out_ptr) + __builtin_trap(); + auto volatile strtoull_output = + __llvm_libc::strtoull(str_ptr, &out_ptr, base); + if (str_ptr + container_size - 1 < out_ptr) + __builtin_trap(); + + delete[] container; + return 0; +}