| //===-- strnlen_s_differential_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 | |
| // | |
| //===----------------------------------------------------------------------===// | |
| /// | |
| /// Differential fuzz test for llvm-libc strnlen_s implementation. | |
| /// | |
| //===----------------------------------------------------------------------===// | |
| #define __STDC_WANT_LIB_EXT1__ 1 | |
| #include "src/string/strnlen_s.h" | |
| #include <stdint.h> | |
| #include <string.h> | |
| extern "C" size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t max_size); | |
| extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size, | |
| size_t max_size, | |
| unsigned int /*seed*/) { | |
| // The buffer is constructed as follows: | |
| // data = max_len (size_t) + null-terminated string | |
| if (max_size < sizeof(size_t) + 1) | |
| return size; | |
| do { | |
| size = LLVMFuzzerMutate(data, size, max_size); | |
| } while (size < sizeof(size_t) + 1); | |
| data[size - 1] = '\0'; | |
| return size; | |
| } | |
| extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | |
| if (size < sizeof(size_t) + 1) | |
| return 0; | |
| size_t max_len; | |
| ::memcpy(&max_len, data, sizeof(size_t)); | |
| data += sizeof(size_t); | |
| // If Annex K is not available in the system's C library, we compare against | |
| // strnlen instead. We can assume this is valid because in the case where the | |
| // input string is not null, the two functions must have identical semantics. | |
| #ifdef __STDC_LIB_EXT1__ | |
| size_t ref = ::strnlen_s(reinterpret_cast<const char *>(data), max_len); | |
| #else | |
| size_t ref = ::strnlen(reinterpret_cast<const char *>(data), max_len); | |
| #endif | |
| size_t impl = | |
| LIBC_NAMESPACE::strnlen_s(reinterpret_cast<const char *>(data), max_len); | |
| if (ref != impl) | |
| __builtin_trap(); | |
| return 0; | |
| } |