ctdb-tests: nfs_iterate_test() marks RPC service down
[samba4-gss.git] / lib / fuzzing / fuzz_strncasecmp_ldb.c
blob0f785b5bee7d3f2963241af2cff5cfaad07a529f
1 /*
2 Fuzzing ldb_comparison_fold()
3 Copyright (C) Catalyst IT 2020
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "includes.h"
19 #include "fuzzing/fuzzing.h"
20 #include "charset.h"
23 int LLVMFuzzerInitialize(int *argc, char ***argv)
25 return 0;
29 int LLVMFuzzerTestOneInput(const uint8_t *input, size_t len)
31 struct ldb_val v[3] = {{},{},{}};
32 size_t i, j, k;
33 int results[9], ab, ac, bc;
35 if (len < 3) {
36 return 0;
39 j = 0;
40 k = 0;
41 v[j].data = discard_const(input);
44 * We split the input into 3 ldb_vals, on the byte '*' (42), chosen
45 * because it is *not* special with regard to termination, utf-8, or
46 * casefolding.
48 * if there are not 2 '*' bytes, the last value[s] will be empty, with
49 * a NULL pointer and zero length.
52 for (i = 0; i < len; i++) {
53 if (input[i] != '*') {
54 continue;
56 v[j].length = i - k;
57 i++;
58 j++;
59 if (j > 2 || i == len) {
60 break;
62 k = i;
63 v[j].data = discard_const(input + k);
66 for (i = 0; i < 3; i++) {
67 char *s1 = (char*)v[i].data;
68 size_t len1 = v[i].length;
69 for (j = 0; j < 3; j++) {
70 char *s2 = (char*)v[j].data;
71 size_t len2 = v[j].length;
72 int r = strncasecmp_ldb(s1, len1, s2, len2);
73 if (abs(r) > 1) {
74 abort();
76 results[i * 3 + j] = r;
81 * There are nine comparisons we make.
83 * A B C
84 * A = x x
85 * B - = x
86 * C - - =
88 * The diagonal should be all zeros (A == A, etc)
89 * The upper and lower triangles should complement each other
90 * (A > B implies B < A; A == B implies B == A).
92 * So we check for those identities first.
95 if ((results[0] != 0) ||
96 (results[4] != 0) ||
97 (results[8] != 0)) {
98 abort();
101 ab = results[3];
102 ac = results[6];
103 bc = results[7];
105 if (ab != -results[1] ||
106 ac != -results[2] ||
107 bc != -results[5]) {
108 abort();
112 * Then there are 27 states within the three comparisons of one
113 * triangle, because each of AB, AC, and BC can be in 3 states.
115 * 0 (A < B) (A < C) (B < C) A < B < C
116 * 1 (A < B) (A < C) (B = C) A < (B|C)
117 * 2 (A < B) (A < C) (B > C) A < C < B
118 * 3 (A < B) (A = C) (B < C) invalid
119 * 4 (A < B) (A = C) (B = C) invalid
120 * 5 (A < B) (A = C) (B > C) (A|C) < B
121 * 6 (A < B) (A > C) (B < C) invalid
122 * 7 (A < B) (A > C) (B = C) invalid
123 * 8 (A < B) (A > C) (B > C) C < A < B
124 * 9 (A = B) (A < C) (B < C) (A|B) < C
125 * 10 (A = B) (A < C) (B = C) invalid
126 * 11 (A = B) (A < C) (B > C) invalid
127 * 12 (A = B) (A = C) (B < C) invalid
128 * 13 (A = B) (A = C) (B = C) A = B = C
129 * 14 (A = B) (A = C) (B > C) invalid
130 * 15 (A = B) (A > C) (B < C) invalid
131 * 16 (A = B) (A > C) (B = C) invalid
132 * 17 (A = B) (A > C) (B > C) C < (A|B)
133 * 18 (A > B) (A < C) (B < C) B < C < A
134 * 19 (A > B) (A < C) (B = C) invalid
135 * 20 (A > B) (A < C) (B > C) invalid
136 * 21 (A > B) (A = C) (B < C) B < (A|C)
137 * 22 (A > B) (A = C) (B = C) invalid
138 * 23 (A > B) (A = C) (B > C) invalid
139 * 24 (A > B) (A > C) (B < C) B < C < A
140 * 25 (A > B) (A > C) (B = C) (B|C) < A
141 * 26 (A > B) (A > C) (B > C) C < B < A
143 * It actually turns out to be quite simple:
146 if (ab == 0) {
147 if (ac != bc) {
148 abort();
150 } else if (ab < 0) {
151 if (ac >= 0 && bc <= 0) {
152 abort();
154 } else {
155 if (ac <= 0 && bc >= 0) {
156 abort();
160 return 0;