Merge tag 'ovl-update-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
[platform/kernel/linux-rpi.git] / lib / test_string.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/module.h>
3 #include <linux/printk.h>
4 #include <linux/slab.h>
5 #include <linux/string.h>
6
7 static __init int memset16_selftest(void)
8 {
9         unsigned i, j, k;
10         u16 v, *p;
11
12         p = kmalloc(256 * 2 * 2, GFP_KERNEL);
13         if (!p)
14                 return -1;
15
16         for (i = 0; i < 256; i++) {
17                 for (j = 0; j < 256; j++) {
18                         memset(p, 0xa1, 256 * 2 * sizeof(v));
19                         memset16(p + i, 0xb1b2, j);
20                         for (k = 0; k < 512; k++) {
21                                 v = p[k];
22                                 if (k < i) {
23                                         if (v != 0xa1a1)
24                                                 goto fail;
25                                 } else if (k < i + j) {
26                                         if (v != 0xb1b2)
27                                                 goto fail;
28                                 } else {
29                                         if (v != 0xa1a1)
30                                                 goto fail;
31                                 }
32                         }
33                 }
34         }
35
36 fail:
37         kfree(p);
38         if (i < 256)
39                 return (i << 24) | (j << 16) | k | 0x8000;
40         return 0;
41 }
42
43 static __init int memset32_selftest(void)
44 {
45         unsigned i, j, k;
46         u32 v, *p;
47
48         p = kmalloc(256 * 2 * 4, GFP_KERNEL);
49         if (!p)
50                 return -1;
51
52         for (i = 0; i < 256; i++) {
53                 for (j = 0; j < 256; j++) {
54                         memset(p, 0xa1, 256 * 2 * sizeof(v));
55                         memset32(p + i, 0xb1b2b3b4, j);
56                         for (k = 0; k < 512; k++) {
57                                 v = p[k];
58                                 if (k < i) {
59                                         if (v != 0xa1a1a1a1)
60                                                 goto fail;
61                                 } else if (k < i + j) {
62                                         if (v != 0xb1b2b3b4)
63                                                 goto fail;
64                                 } else {
65                                         if (v != 0xa1a1a1a1)
66                                                 goto fail;
67                                 }
68                         }
69                 }
70         }
71
72 fail:
73         kfree(p);
74         if (i < 256)
75                 return (i << 24) | (j << 16) | k | 0x8000;
76         return 0;
77 }
78
79 static __init int memset64_selftest(void)
80 {
81         unsigned i, j, k;
82         u64 v, *p;
83
84         p = kmalloc(256 * 2 * 8, GFP_KERNEL);
85         if (!p)
86                 return -1;
87
88         for (i = 0; i < 256; i++) {
89                 for (j = 0; j < 256; j++) {
90                         memset(p, 0xa1, 256 * 2 * sizeof(v));
91                         memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j);
92                         for (k = 0; k < 512; k++) {
93                                 v = p[k];
94                                 if (k < i) {
95                                         if (v != 0xa1a1a1a1a1a1a1a1ULL)
96                                                 goto fail;
97                                 } else if (k < i + j) {
98                                         if (v != 0xb1b2b3b4b5b6b7b8ULL)
99                                                 goto fail;
100                                 } else {
101                                         if (v != 0xa1a1a1a1a1a1a1a1ULL)
102                                                 goto fail;
103                                 }
104                         }
105                 }
106         }
107
108 fail:
109         kfree(p);
110         if (i < 256)
111                 return (i << 24) | (j << 16) | k | 0x8000;
112         return 0;
113 }
114
115 static __init int strchr_selftest(void)
116 {
117         const char *test_string = "abcdefghijkl";
118         const char *empty_string = "";
119         char *result;
120         int i;
121
122         for (i = 0; i < strlen(test_string) + 1; i++) {
123                 result = strchr(test_string, test_string[i]);
124                 if (result - test_string != i)
125                         return i + 'a';
126         }
127
128         result = strchr(empty_string, '\0');
129         if (result != empty_string)
130                 return 0x101;
131
132         result = strchr(empty_string, 'a');
133         if (result)
134                 return 0x102;
135
136         result = strchr(test_string, 'z');
137         if (result)
138                 return 0x103;
139
140         return 0;
141 }
142
143 static __init int strnchr_selftest(void)
144 {
145         const char *test_string = "abcdefghijkl";
146         const char *empty_string = "";
147         char *result;
148         int i, j;
149
150         for (i = 0; i < strlen(test_string) + 1; i++) {
151                 for (j = 0; j < strlen(test_string) + 2; j++) {
152                         result = strnchr(test_string, j, test_string[i]);
153                         if (j <= i) {
154                                 if (!result)
155                                         continue;
156                                 return ((i + 'a') << 8) | j;
157                         }
158                         if (result - test_string != i)
159                                 return ((i + 'a') << 8) | j;
160                 }
161         }
162
163         result = strnchr(empty_string, 0, '\0');
164         if (result)
165                 return 0x10001;
166
167         result = strnchr(empty_string, 1, '\0');
168         if (result != empty_string)
169                 return 0x10002;
170
171         result = strnchr(empty_string, 1, 'a');
172         if (result)
173                 return 0x10003;
174
175         result = strnchr(NULL, 0, '\0');
176         if (result)
177                 return 0x10004;
178
179         return 0;
180 }
181
182 static __init int strspn_selftest(void)
183 {
184         static const struct strspn_test {
185                 const char str[16];
186                 const char accept[16];
187                 const char reject[16];
188                 unsigned a;
189                 unsigned r;
190         } tests[] __initconst = {
191                 { "foobar", "", "", 0, 6 },
192                 { "abba", "abc", "ABBA", 4, 4 },
193                 { "abba", "a", "b", 1, 1 },
194                 { "", "abc", "abc", 0, 0},
195         };
196         const struct strspn_test *s = tests;
197         size_t i, res;
198
199         for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) {
200                 res = strspn(s->str, s->accept);
201                 if (res != s->a)
202                         return 0x100 + 2*i;
203                 res = strcspn(s->str, s->reject);
204                 if (res != s->r)
205                         return 0x100 + 2*i + 1;
206         }
207         return 0;
208 }
209
210 static __exit void string_selftest_remove(void)
211 {
212 }
213
214 static __init int string_selftest_init(void)
215 {
216         int test, subtest;
217
218         test = 1;
219         subtest = memset16_selftest();
220         if (subtest)
221                 goto fail;
222
223         test = 2;
224         subtest = memset32_selftest();
225         if (subtest)
226                 goto fail;
227
228         test = 3;
229         subtest = memset64_selftest();
230         if (subtest)
231                 goto fail;
232
233         test = 4;
234         subtest = strchr_selftest();
235         if (subtest)
236                 goto fail;
237
238         test = 5;
239         subtest = strnchr_selftest();
240         if (subtest)
241                 goto fail;
242
243         test = 6;
244         subtest = strspn_selftest();
245         if (subtest)
246                 goto fail;
247
248         pr_info("String selftests succeeded\n");
249         return 0;
250 fail:
251         pr_crit("String selftest failure %d.%08x\n", test, subtest);
252         return 0;
253 }
254
255 module_init(string_selftest_init);
256 module_exit(string_selftest_remove);
257 MODULE_LICENSE("GPL v2");