Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
git-mirror
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
0
Pull requests
0
Actions
Projects
0
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security
Insights
Files
master
Documentation
arch
block
certs
crypto
drivers
firmware
fs
include
init
ipc
kernel
lib
842
fonts
lz4
lzo
mpi
raid6
reed_solomon
xz
zlib_deflate
zlib_inflate
.gitignore
Kconfig
Kconfig.debug
Kconfig.kasan
Kconfig.kgdb
Kconfig.kmemcheck
Kconfig.ubsan
Makefile
argv_split.c
asn1_decoder.c
assoc_array.c
atomic64.c
atomic64_test.c
audit.c
bcd.c
bch.c
bitmap.c
bitrev.c
bsearch.c
btree.c
bug.c
build_OID_registry
bust_spinlocks.c
check_signature.c
checksum.c
clz_ctz.c
clz_tab.c
cmdline.c
compat_audit.c
cordic.c
cpu-notifier-error-inject.c
cpu_rmap.c
cpumask.c
crc-ccitt.c
crc-itu-t.c
crc-t10dif.c
crc16.c
crc32.c
crc32defs.h
crc7.c
crc8.c
ctype.c
debug_info.c
debug_locks.c
debugobjects.c
dec_and_lock.c
decompress.c
decompress_bunzip2.c
decompress_inflate.c
decompress_unlz4.c
decompress_unlzma.c
decompress_unlzo.c
decompress_unxz.c
devres.c
digsig.c
div64.c
dma-debug.c
dma-noop.c
dump_stack.c
dynamic_debug.c
dynamic_queue_limits.c
earlycpio.c
extable.c
fault-inject.c
fdt.c
fdt_empty_tree.c
fdt_ro.c
fdt_rw.c
fdt_strerror.c
fdt_sw.c
fdt_wip.c
find_bit.c
flex_array.c
flex_proportions.c
gcd.c
gen_crc32table.c
genalloc.c
glob.c
halfmd4.c
hexdump.c
hweight.c
idr.c
inflate.c
int_sqrt.c
interval_tree.c
interval_tree_test.c
iomap.c
iomap_copy.c
iommu-common.c
iommu-helper.c
ioremap.c
iov_iter.c
irq_poll.c
irq_regs.c
is_single_threaded.c
jedec_ddr_data.c
kasprintf.c
kfifo.c
klist.c
kobject.c
kobject_uevent.c
kstrtox.c
kstrtox.h
lcm.c
libcrc32c.c
list_debug.c
list_sort.c
llist.c
locking-selftest-hardirq.h
locking-selftest-mutex.h
locking-selftest-rlock-hardirq.h
locking-selftest-rlock-softirq.h
locking-selftest-rlock.h
locking-selftest-rsem.h
locking-selftest-softirq.h
locking-selftest-spin-hardirq.h
locking-selftest-spin-softirq.h
locking-selftest-spin.h
locking-selftest-wlock-hardirq.h
locking-selftest-wlock-softirq.h
locking-selftest-wlock.h
locking-selftest-wsem.h
locking-selftest.c
lockref.c
lru_cache.c
md5.c
memory-notifier-error-inject.c
memweight.c
net_utils.c
netdev-notifier-error-inject.c
nlattr.c
nmi_backtrace.c
notifier-error-inject.c
notifier-error-inject.h
of-reconfig-notifier-error-inject.c
oid_registry.c
once.c
parser.c
pci_iomap.c
percpu-refcount.c
percpu_counter.c
percpu_ida.c
percpu_test.c
plist.c
pm-notifier-error-inject.c
proportions.c
radix-tree.c
random32.c
ratelimit.c
rational.c
rbtree.c
rbtree_test.c
reciprocal_div.c
rhashtable.c
scatterlist.c
seq_buf.c
sg_split.c
sha1.c
show_mem.c
smp_processor_id.c
sort.c
stackdepot.c
stmp_device.c
string.c
string_helpers.c
strncpy_from_user.c
strnlen_user.c
swiotlb.c
syscall.c
test-kstrtox.c
test-string_helpers.c
test_bitmap.c
test_bpf.c
test_firmware.c
test_hexdump.c
test_kasan.c
test_module.c
test_printf.c
test_rhashtable.c
test_static_key_base.c
test_static_keys.c
test_user_copy.c
textsearch.c
timerqueue.c
ts_bm.c
ts_fsm.c
ts_kmp.c
ubsan.c
ubsan.h
ucs2_string.c
usercopy.c
uuid.c
vsprintf.c
mm
net
samples
scripts
security
sound
tools
usr
virt
.get_maintainer.ignore
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
lib
/
test-string_helpers.c
Blame
Blame
Latest commit
History
History
417 lines (362 loc) · 10.3 KB
Breadcrumbs
linux
/
lib
/
test-string_helpers.c
Top
File metadata and controls
Code
Blame
417 lines (362 loc) · 10.3 KB
Raw
/* * Test cases for lib/string_helpers.c module. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/init.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/random.h> #include <linux/string.h> #include <linux/string_helpers.h> static __init bool test_string_check_buf(const char *name, unsigned int flags, char *in, size_t p, char *out_real, size_t q_real, char *out_test, size_t q_test) { if (q_real == q_test && !memcmp(out_test, out_real, q_test)) return true; pr_warn("Test '%s' failed: flags = %u\n", name, flags); print_hex_dump(KERN_WARNING, "Input: ", DUMP_PREFIX_NONE, 16, 1, in, p, true); print_hex_dump(KERN_WARNING, "Expected: ", DUMP_PREFIX_NONE, 16, 1, out_test, q_test, true); print_hex_dump(KERN_WARNING, "Got: ", DUMP_PREFIX_NONE, 16, 1, out_real, q_real, true); return false; } struct test_string { const char *in; const char *out; unsigned int flags; }; static const struct test_string strings[] __initconst = { { .in = "\\f\\ \\n\\r\\t\\v", .out = "\f\\ \n\r\t\v", .flags = UNESCAPE_SPACE, }, { .in = "\\40\\1\\387\\0064\\05\\040\\8a\\110\\777", .out = " \001\00387\0064\005 \\8aH?7", .flags = UNESCAPE_OCTAL, }, { .in = "\\xv\\xa\\x2c\\xD\\x6f2", .out = "\\xv\n,\ro2", .flags = UNESCAPE_HEX, }, { .in = "\\h\\\\\\\"\\a\\e\\", .out = "\\h\\\"\a\e\\", .flags = UNESCAPE_SPECIAL, }, }; static void __init test_string_unescape(const char *name, unsigned int flags, bool inplace) { int q_real = 256; char *in = kmalloc(q_real, GFP_KERNEL); char *out_test = kmalloc(q_real, GFP_KERNEL); char *out_real = kmalloc(q_real, GFP_KERNEL); int i, p = 0, q_test = 0; if (!in || !out_test || !out_real) goto out; for (i = 0; i < ARRAY_SIZE(strings); i++) { const char *s = strings[i].in; int len = strlen(strings[i].in); /* Copy string to in buffer */ memcpy(&in[p], s, len); p += len; /* Copy expected result for given flags */ if (flags & strings[i].flags) { s = strings[i].out; len = strlen(strings[i].out); } memcpy(&out_test[q_test], s, len); q_test += len; } in[p++] = '\0'; /* Call string_unescape and compare result */ if (inplace) { memcpy(out_real, in, p); if (flags == UNESCAPE_ANY) q_real = string_unescape_any_inplace(out_real); else q_real = string_unescape_inplace(out_real, flags); } else if (flags == UNESCAPE_ANY) { q_real = string_unescape_any(in, out_real, q_real); } else { q_real = string_unescape(in, out_real, q_real, flags); } test_string_check_buf(name, flags, in, p - 1, out_real, q_real, out_test, q_test); out: kfree(out_real); kfree(out_test); kfree(in); } struct test_string_1 { const char *out; unsigned int flags; }; #define TEST_STRING_2_MAX_S1 32 struct test_string_2 { const char *in; struct test_string_1 s1[TEST_STRING_2_MAX_S1]; }; #define TEST_STRING_2_DICT_0 NULL static const struct test_string_2 escape0[] __initconst = {{ .in = "\f\\ \n\r\t\v", .s1 = {{ .out = "\\f\\ \\n\\r\\t\\v", .flags = ESCAPE_SPACE, },{ .out = "\\f\\134\\040\\n\\r\\t\\v", .flags = ESCAPE_SPACE | ESCAPE_OCTAL, },{ .out = "\\f\\x5c\\x20\\n\\r\\t\\v", .flags = ESCAPE_SPACE | ESCAPE_HEX, },{ /* terminator */ }}, },{ .in = "\\h\\\"\a\e\\", .s1 = {{ .out = "\\\\h\\\\\"\\a\\e\\\\", .flags = ESCAPE_SPECIAL, },{ .out = "\\\\\\150\\\\\\042\\a\\e\\\\", .flags = ESCAPE_SPECIAL | ESCAPE_OCTAL, },{ .out = "\\\\\\x68\\\\\\x22\\a\\e\\\\", .flags = ESCAPE_SPECIAL | ESCAPE_HEX, },{ /* terminator */ }}, },{ .in = "\eb \\C\007\"\x90\r]", .s1 = {{ .out = "\eb \\C\007\"\x90\\r]", .flags = ESCAPE_SPACE, },{ .out = "\\eb \\\\C\\a\"\x90\r]", .flags = ESCAPE_SPECIAL, },{ .out = "\\eb \\\\C\\a\"\x90\\r]", .flags = ESCAPE_SPACE | ESCAPE_SPECIAL, },{ .out = "\\033\\142\\040\\134\\103\\007\\042\\220\\015\\135", .flags = ESCAPE_OCTAL, },{ .out = "\\033\\142\\040\\134\\103\\007\\042\\220\\r\\135", .flags = ESCAPE_SPACE | ESCAPE_OCTAL, },{ .out = "\\e\\142\\040\\\\\\103\\a\\042\\220\\015\\135", .flags = ESCAPE_SPECIAL | ESCAPE_OCTAL, },{ .out = "\\e\\142\\040\\\\\\103\\a\\042\\220\\r\\135", .flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_OCTAL, },{ .out = "\eb \\C\007\"\x90\r]", .flags = ESCAPE_NP, },{ .out = "\eb \\C\007\"\x90\\r]", .flags = ESCAPE_SPACE | ESCAPE_NP, },{ .out = "\\eb \\C\\a\"\x90\r]", .flags = ESCAPE_SPECIAL | ESCAPE_NP, },{ .out = "\\eb \\C\\a\"\x90\\r]", .flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NP, },{ .out = "\\033b \\C\\007\"\\220\\015]", .flags = ESCAPE_OCTAL | ESCAPE_NP, },{ .out = "\\033b \\C\\007\"\\220\\r]", .flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NP, },{ .out = "\\eb \\C\\a\"\\220\\r]", .flags = ESCAPE_SPECIAL | ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NP, },{ .out = "\\x1bb \\C\\x07\"\\x90\\x0d]", .flags = ESCAPE_NP | ESCAPE_HEX, },{ /* terminator */ }}, },{ /* terminator */ }}; #define TEST_STRING_2_DICT_1 "b\\ \t\r" static const struct test_string_2 escape1[] __initconst = {{ .in = "\f\\ \n\r\t\v", .s1 = {{ .out = "\f\\134\\040\n\\015\\011\v", .flags = ESCAPE_OCTAL, },{ .out = "\f\\x5c\\x20\n\\x0d\\x09\v", .flags = ESCAPE_HEX, },{ /* terminator */ }}, },{ .in = "\\h\\\"\a\e\\", .s1 = {{ .out = "\\134h\\134\"\a\e\\134", .flags = ESCAPE_OCTAL, },{ /* terminator */ }}, },{ .in = "\eb \\C\007\"\x90\r]", .s1 = {{ .out = "\e\\142\\040\\134C\007\"\x90\\015]", .flags = ESCAPE_OCTAL, },{ /* terminator */ }}, },{ /* terminator */ }}; static __init const char *test_string_find_match(const struct test_string_2 *s2, unsigned int flags) { const struct test_string_1 *s1 = s2->s1; unsigned int i; if (!flags) return s2->in; /* Test cases are NULL-aware */ flags &= ~ESCAPE_NULL; /* ESCAPE_OCTAL has a higher priority */ if (flags & ESCAPE_OCTAL) flags &= ~ESCAPE_HEX; for (i = 0; i < TEST_STRING_2_MAX_S1 && s1->out; i++, s1++) if (s1->flags == flags) return s1->out; return NULL; } static __init void test_string_escape_overflow(const char *in, int p, unsigned int flags, const char *esc, int q_test, const char *name) { int q_real; q_real = string_escape_mem(in, p, NULL, 0, flags, esc); if (q_real != q_test) pr_warn("Test '%s' failed: flags = %u, osz = 0, expected %d, got %d\n", name, flags, q_test, q_real); } static __init void test_string_escape(const char *name, const struct test_string_2 *s2, unsigned int flags, const char *esc) { size_t out_size = 512; char *out_test = kmalloc(out_size, GFP_KERNEL); char *out_real = kmalloc(out_size, GFP_KERNEL); char *in = kmalloc(256, GFP_KERNEL); int p = 0, q_test = 0; int q_real; if (!out_test || !out_real || !in) goto out; for (; s2->in; s2++) { const char *out; int len; /* NULL injection */ if (flags & ESCAPE_NULL) { in[p++] = '\0'; out_test[q_test++] = '\\'; out_test[q_test++] = '0'; } /* Don't try strings that have no output */ out = test_string_find_match(s2, flags); if (!out) continue; /* Copy string to in buffer */ len = strlen(s2->in); memcpy(&in[p], s2->in, len); p += len; /* Copy expected result for given flags */ len = strlen(out); memcpy(&out_test[q_test], out, len); q_test += len; } q_real = string_escape_mem(in, p, out_real, out_size, flags, esc); test_string_check_buf(name, flags, in, p, out_real, q_real, out_test, q_test); test_string_escape_overflow(in, p, flags, esc, q_test, name); out: kfree(in); kfree(out_real); kfree(out_test); } #define string_get_size_maxbuf 16 #define test_string_get_size_one(size, blk_size, exp_result10, exp_result2) \ do { \ BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf); \ BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf); \ __test_string_get_size((size), (blk_size), (exp_result10), \ (exp_result2)); \ } while (0) static __init void test_string_get_size_check(const char *units, const char *exp, char *res, const u64 size, const u64 blk_size) { if (!memcmp(res, exp, strlen(exp) + 1)) return; res[string_get_size_maxbuf - 1] = '\0'; pr_warn("Test 'test_string_get_size' failed!\n"); pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %s)\n", size, blk_size, units); pr_warn("expected: '%s', got '%s'\n", exp, res); } static __init void __test_string_get_size(const u64 size, const u64 blk_size, const char *exp_result10, const char *exp_result2) { char buf10[string_get_size_maxbuf]; char buf2[string_get_size_maxbuf]; string_get_size(size, blk_size, STRING_UNITS_10, buf10, sizeof(buf10)); string_get_size(size, blk_size, STRING_UNITS_2, buf2, sizeof(buf2)); test_string_get_size_check("STRING_UNITS_10", exp_result10, buf10, size, blk_size); test_string_get_size_check("STRING_UNITS_2", exp_result2, buf2, size, blk_size); } static __init void test_string_get_size(void) { /* small values */ test_string_get_size_one(0, 512, "0 B", "0 B"); test_string_get_size_one(1, 512, "512 B", "512 B"); test_string_get_size_one(1100, 1, "1.10 kB", "1.07 KiB"); /* normal values */ test_string_get_size_one(16384, 512, "8.39 MB", "8.00 MiB"); test_string_get_size_one(500118192, 512, "256 GB", "238 GiB"); test_string_get_size_one(8192, 4096, "33.6 MB", "32.0 MiB"); /* weird block sizes */ test_string_get_size_one(3000, 1900, "5.70 MB", "5.44 MiB"); /* huge values */ test_string_get_size_one(U64_MAX, 4096, "75.6 ZB", "64.0 ZiB"); test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB"); } static int __init test_string_helpers_init(void) { unsigned int i; pr_info("Running tests...\n"); for (i = 0; i < UNESCAPE_ANY + 1; i++) test_string_unescape("unescape", i, false); test_string_unescape("unescape inplace", get_random_int() % (UNESCAPE_ANY + 1), true); /* Without dictionary */ for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++) test_string_escape("escape 0", escape0, i, TEST_STRING_2_DICT_0); /* With dictionary */ for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++) test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1); /* Test string_get_size() */ test_string_get_size(); return -EINVAL; } module_init(test_string_helpers_init); MODULE_LICENSE("Dual BSD/GPL");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
You can’t perform that action at this time.