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