/src/samba/lib/fuzzing/fuzz_strncasecmp_ldb.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Fuzzing ldb_comparison_fold() |
3 | | Copyright (C) Catalyst IT 2020 |
4 | | |
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. |
9 | | |
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. |
14 | | |
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/>. |
17 | | */ |
18 | | #include "includes.h" |
19 | | #include "fuzzing/fuzzing.h" |
20 | | #include "charset.h" |
21 | | |
22 | | |
23 | | int LLVMFuzzerInitialize(int *argc, char ***argv) |
24 | 372 | { |
25 | 372 | return 0; |
26 | 372 | } |
27 | | |
28 | | |
29 | | int LLVMFuzzerTestOneInput(const uint8_t *input, size_t len) |
30 | 574 | { |
31 | 574 | struct ldb_val v[3] = {{},{},{}}; |
32 | 574 | size_t i, j, k; |
33 | 574 | int results[9], ab, ac, bc; |
34 | | |
35 | 574 | if (len < 3) { |
36 | 2 | return 0; |
37 | 2 | } |
38 | | |
39 | 572 | j = 0; |
40 | 572 | k = 0; |
41 | 572 | v[j].data = discard_const(input); |
42 | | |
43 | | /* |
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. |
47 | | * |
48 | | * if there are not 2 '*' bytes, the last value[s] will be empty, with |
49 | | * a NULL pointer and zero length. |
50 | | */ |
51 | | |
52 | 16.7M | for (i = 0; i < len; i++) { |
53 | 16.7M | if (input[i] != '*') { |
54 | 16.7M | continue; |
55 | 16.7M | } |
56 | 906 | v[j].length = i - k; |
57 | 906 | i++; |
58 | 906 | j++; |
59 | 906 | if (j > 2 || i == len) { |
60 | 537 | break; |
61 | 537 | } |
62 | 369 | k = i; |
63 | 369 | v[j].data = discard_const(input + k); |
64 | 369 | } |
65 | | |
66 | 2.28k | for (i = 0; i < 3; i++) { |
67 | 1.71k | char *s1 = (char*)v[i].data; |
68 | 1.71k | size_t len1 = v[i].length; |
69 | 6.86k | for (j = 0; j < 3; j++) { |
70 | 5.14k | char *s2 = (char*)v[j].data; |
71 | 5.14k | size_t len2 = v[j].length; |
72 | 5.14k | int r = strncasecmp_ldb(s1, len1, s2, len2); |
73 | 5.14k | if (abs(r) > 1) { |
74 | 0 | abort(); |
75 | 0 | } |
76 | 5.14k | results[i * 3 + j] = r; |
77 | 5.14k | } |
78 | 1.71k | } |
79 | | |
80 | | /* |
81 | | * There are nine comparisons we make. |
82 | | * |
83 | | * A B C |
84 | | * A = x x |
85 | | * B - = x |
86 | | * C - - = |
87 | | * |
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). |
91 | | * |
92 | | * So we check for those identities first. |
93 | | */ |
94 | | |
95 | 572 | if ((results[0] != 0) || |
96 | 572 | (results[4] != 0) || |
97 | 572 | (results[8] != 0)) { |
98 | 0 | abort(); |
99 | 0 | } |
100 | | |
101 | 572 | ab = results[3]; |
102 | 572 | ac = results[6]; |
103 | 572 | bc = results[7]; |
104 | | |
105 | 572 | if (ab != -results[1] || |
106 | 572 | ac != -results[2] || |
107 | 572 | bc != -results[5]) { |
108 | 0 | abort(); |
109 | 0 | } |
110 | | |
111 | | /* |
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. |
114 | | * |
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 |
142 | | * |
143 | | * It actually turns out to be quite simple: |
144 | | */ |
145 | | |
146 | 572 | if (ab == 0) { |
147 | 85 | if (ac != bc) { |
148 | 0 | abort(); |
149 | 0 | } |
150 | 487 | } else if (ab < 0) { |
151 | 400 | if (ac >= 0 && bc <= 0) { |
152 | 0 | abort(); |
153 | 0 | } |
154 | 400 | } else { |
155 | 87 | if (ac <= 0 && bc >= 0) { |
156 | 0 | abort(); |
157 | 0 | } |
158 | 87 | } |
159 | | |
160 | 572 | return 0; |
161 | 572 | } |