xref: /kernel/linux/linux-5.10/lib/test_string.c (revision 8c2ecf20)
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
7static __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
36fail:
37	kfree(p);
38	if (i < 256)
39		return (i << 24) | (j << 16) | k | 0x8000;
40	return 0;
41}
42
43static __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
72fail:
73	kfree(p);
74	if (i < 256)
75		return (i << 24) | (j << 16) | k | 0x8000;
76	return 0;
77}
78
79static __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
108fail:
109	kfree(p);
110	if (i < 256)
111		return (i << 24) | (j << 16) | k | 0x8000;
112	return 0;
113}
114
115static __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
143static __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
182static __init int string_selftest_init(void)
183{
184	int test, subtest;
185
186	test = 1;
187	subtest = memset16_selftest();
188	if (subtest)
189		goto fail;
190
191	test = 2;
192	subtest = memset32_selftest();
193	if (subtest)
194		goto fail;
195
196	test = 3;
197	subtest = memset64_selftest();
198	if (subtest)
199		goto fail;
200
201	test = 4;
202	subtest = strchr_selftest();
203	if (subtest)
204		goto fail;
205
206	test = 5;
207	subtest = strnchr_selftest();
208	if (subtest)
209		goto fail;
210
211	pr_info("String selftests succeeded\n");
212	return 0;
213fail:
214	pr_crit("String selftest failure %d.%08x\n", test, subtest);
215	return 0;
216}
217
218module_init(string_selftest_init);
219MODULE_LICENSE("GPL v2");
220