diff --git a/libc/fuzzing/string/CMakeLists.txt b/libc/fuzzing/string/CMakeLists.txt --- a/libc/fuzzing/string/CMakeLists.txt +++ b/libc/fuzzing/string/CMakeLists.txt @@ -1,3 +1,11 @@ +add_libc_fuzzer( + memchr_fuzz + SRCS + memchr_fuzz.cpp + DEPENDS + libc.src.string.memchr +) + add_libc_fuzzer( strcmp_fuzz SRCS @@ -16,6 +24,14 @@ libc.src.string.strlen ) +add_libc_fuzzer( + strlen_fuzz + SRCS + strlen_fuzz.cpp + DEPENDS + libc.src.string.strlen +) + add_libc_fuzzer( strstr_fuzz SRCS diff --git a/libc/fuzzing/string/memchr_fuzz.cpp b/libc/fuzzing/string/memchr_fuzz.cpp new file mode 100644 --- /dev/null +++ b/libc/fuzzing/string/memchr_fuzz.cpp @@ -0,0 +1,40 @@ +//===-- memchr_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 memchr implementation. +/// +//===----------------------------------------------------------------------===// +#include "src/string/memchr.h" +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + // Verify the size is at least 1, since we're using the final index as the + // value to search for. + if (!size) + return 0; + + const unsigned char *src = reinterpret_cast(data); + const unsigned char c = data[size - 1]; // final index. + + // Searches all indices except the last one. This ensures + // the value being searched for isn't always found. + const size_t new_size = size - 1; + + size_t i; + for (i = 0; i < new_size; ++i) { + if (src[i] == c) + break; + } + const unsigned char *expected = i < new_size ? src + i : nullptr; + + if (__llvm_libc::memchr(data, c, new_size) != expected) + __builtin_trap(); + + return 0; +} diff --git a/libc/fuzzing/string/strlen_fuzz.cpp b/libc/fuzzing/string/strlen_fuzz.cpp new file mode 100644 --- /dev/null +++ b/libc/fuzzing/string/strlen_fuzz.cpp @@ -0,0 +1,29 @@ +//===-- strlen_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 strlen implementation. +/// +//===----------------------------------------------------------------------===// +#include "src/string/strlen.h" +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + // Verify the size is at least 1 and the data is null terminated. + if (!size || data[size - 1] != '\0') + return 0; + + size_t count; + for (count = 0; data[count]; ++count) + ; + + if (__llvm_libc::strlen(reinterpret_cast(data)) != count) + __builtin_trap(); + + return 0; +}