1*5540765bScgyurgyik //===-- strcmp_fuzz.cpp ---------------------------------------------------===// 2*5540765bScgyurgyik // 3*5540765bScgyurgyik // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5540765bScgyurgyik // See https://llvm.org/LICENSE.txt for license information. 5*5540765bScgyurgyik // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5540765bScgyurgyik // 7*5540765bScgyurgyik //===----------------------------------------------------------------------===// 8*5540765bScgyurgyik /// 9*5540765bScgyurgyik /// Fuzzing test for llvm-libc strcmp implementation. 10*5540765bScgyurgyik /// 11*5540765bScgyurgyik //===----------------------------------------------------------------------===// 12*5540765bScgyurgyik #include "src/string/strcmp.h" 13*5540765bScgyurgyik #include <algorithm> 14*5540765bScgyurgyik #include <stdint.h> 15*5540765bScgyurgyik 16*5540765bScgyurgyik extern "C" int LLVMFuzzerTestTwoInputs(const uint8_t *data1, size_t size1, 17*5540765bScgyurgyik const uint8_t *data2, size_t size2) { 18*5540765bScgyurgyik // Verify each data source contains at least one character. 19*5540765bScgyurgyik if (!size1 || !size2) 20*5540765bScgyurgyik return 0; 21*5540765bScgyurgyik // Verify that the final character is the null terminator. 22*5540765bScgyurgyik if (data1[size1 - 1] != '\0' || data2[size2 - 1] != '\0') 23*5540765bScgyurgyik return 0; 24*5540765bScgyurgyik 25*5540765bScgyurgyik const char *s1 = reinterpret_cast<const char *>(data1); 26*5540765bScgyurgyik const char *s2 = reinterpret_cast<const char *>(data2); 27*5540765bScgyurgyik 28*5540765bScgyurgyik const size_t minimum_size = std::min(size1, size2); 29*5540765bScgyurgyik 30*5540765bScgyurgyik // Iterate through until either the minimum size is hit, 31*5540765bScgyurgyik // a character is the null terminator, or the first set 32*5540765bScgyurgyik // of differed bytes between s1 and s2 are found. 33*5540765bScgyurgyik // No bytes following a null byte should be compared. 34*5540765bScgyurgyik size_t i; 35*5540765bScgyurgyik for (i = 0; i < minimum_size && s1[i] && s1[i] == s2[i]; ++i) 36*5540765bScgyurgyik ; 37*5540765bScgyurgyik 38*5540765bScgyurgyik int expected_result = s1[i] - s2[i]; 39*5540765bScgyurgyik int actual_result = __llvm_libc::strcmp(s1, s2); 40*5540765bScgyurgyik 41*5540765bScgyurgyik // The expected result should be the difference between the first non-equal 42*5540765bScgyurgyik // characters of s1 and s2. If all characters are equal, the expected result 43*5540765bScgyurgyik // should be '\0' - '\0' = 0. 44*5540765bScgyurgyik if (expected_result != actual_result) 45*5540765bScgyurgyik __builtin_trap(); 46*5540765bScgyurgyik 47*5540765bScgyurgyik // Verify reversed operands. This should be the negated value of the previous 48*5540765bScgyurgyik // result, except of course if the previous result was zero. 49*5540765bScgyurgyik expected_result = s2[i] - s1[i]; 50*5540765bScgyurgyik actual_result = __llvm_libc::strcmp(s2, s1); 51*5540765bScgyurgyik if (expected_result != actual_result) 52*5540765bScgyurgyik __builtin_trap(); 53*5540765bScgyurgyik 54*5540765bScgyurgyik return 0; 55*5540765bScgyurgyik } 56