15540765bScgyurgyik //===-- strcmp_fuzz.cpp ---------------------------------------------------===// 25540765bScgyurgyik // 35540765bScgyurgyik // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45540765bScgyurgyik // See https://llvm.org/LICENSE.txt for license information. 55540765bScgyurgyik // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65540765bScgyurgyik // 75540765bScgyurgyik //===----------------------------------------------------------------------===// 85540765bScgyurgyik /// 95540765bScgyurgyik /// Fuzzing test for llvm-libc strcmp implementation. 105540765bScgyurgyik /// 115540765bScgyurgyik //===----------------------------------------------------------------------===// 125540765bScgyurgyik #include "src/string/strcmp.h" 13*f1c67192SSimon Pilgrim #include <stddef.h> 145540765bScgyurgyik #include <stdint.h> 155540765bScgyurgyik 165540765bScgyurgyik extern "C" int LLVMFuzzerTestTwoInputs(const uint8_t *data1, size_t size1, 175540765bScgyurgyik const uint8_t *data2, size_t size2) { 185540765bScgyurgyik // Verify each data source contains at least one character. 195540765bScgyurgyik if (!size1 || !size2) 205540765bScgyurgyik return 0; 215540765bScgyurgyik // Verify that the final character is the null terminator. 225540765bScgyurgyik if (data1[size1 - 1] != '\0' || data2[size2 - 1] != '\0') 235540765bScgyurgyik return 0; 245540765bScgyurgyik 255540765bScgyurgyik const char *s1 = reinterpret_cast<const char *>(data1); 265540765bScgyurgyik const char *s2 = reinterpret_cast<const char *>(data2); 275540765bScgyurgyik 284ffe2b24Scgyurgyik const size_t minimum_size = size1 < size2 ? size1 : size2; 295540765bScgyurgyik 305540765bScgyurgyik // Iterate through until either the minimum size is hit, 315540765bScgyurgyik // a character is the null terminator, or the first set 325540765bScgyurgyik // of differed bytes between s1 and s2 are found. 335540765bScgyurgyik // No bytes following a null byte should be compared. 345540765bScgyurgyik size_t i; 354ffe2b24Scgyurgyik for (i = 0; i < minimum_size; ++i) { 364ffe2b24Scgyurgyik if (!s1[i] || s1[i] != s2[i]) 374ffe2b24Scgyurgyik break; 384ffe2b24Scgyurgyik } 395540765bScgyurgyik 405540765bScgyurgyik int expected_result = s1[i] - s2[i]; 415540765bScgyurgyik int actual_result = __llvm_libc::strcmp(s1, s2); 425540765bScgyurgyik 435540765bScgyurgyik // The expected result should be the difference between the first non-equal 445540765bScgyurgyik // characters of s1 and s2. If all characters are equal, the expected result 455540765bScgyurgyik // should be '\0' - '\0' = 0. 465540765bScgyurgyik if (expected_result != actual_result) 475540765bScgyurgyik __builtin_trap(); 485540765bScgyurgyik 495540765bScgyurgyik // Verify reversed operands. This should be the negated value of the previous 505540765bScgyurgyik // result, except of course if the previous result was zero. 515540765bScgyurgyik expected_result = s2[i] - s1[i]; 525540765bScgyurgyik actual_result = __llvm_libc::strcmp(s2, s1); 535540765bScgyurgyik if (expected_result != actual_result) 545540765bScgyurgyik __builtin_trap(); 555540765bScgyurgyik 565540765bScgyurgyik return 0; 575540765bScgyurgyik } 58