Blame view

lib/test-string_helpers.c 2.48 KB
16c7fa058   Andy Shevchenko   lib/string_helper...
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
102
103
104
105
106
107
108
  /*
   * 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/module.h>
  #include <linux/random.h>
  #include <linux/string.h>
  #include <linux/string_helpers.h>
  
  struct test_string {
  	const char *in;
  	const char *out;
  	unsigned int flags;
  };
  
  static const struct test_string strings[] __initconst = {
  	{
  		.in = "\\f\\ \
  \\r\\t\\v",
  		.out = "\f\\ 
  \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
  ,\ro2",
  		.flags = UNESCAPE_HEX,
  	},
  	{
  		.in = "\\h\\\\\\\"\\a\\e\\",
  		.out = "\\h\\\"\a\e\\",
  		.flags = UNESCAPE_SPECIAL,
  	},
  };
  
  static void __init test_string_unescape(unsigned int flags, bool inplace)
  {
  	char in[256];
  	char out_test[256];
  	char out_real[256];
  	int i, p = 0, q_test = 0, q_real = sizeof(out_real);
  
  	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);
  	}
  
  	if (q_real != q_test || memcmp(out_test, out_real, q_test)) {
  		pr_warn("Test failed: flags = %u
  ", flags);
  		print_hex_dump(KERN_WARNING, "Input: ",
  			       DUMP_PREFIX_NONE, 16, 1, in, p - 1, 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);
  	}
  }
  
  static int __init test_string_helpers_init(void)
  {
  	unsigned int i;
  
  	pr_info("Running tests...
  ");
  	for (i = 0; i < UNESCAPE_ANY + 1; i++)
  		test_string_unescape(i, false);
  	test_string_unescape(get_random_int() % (UNESCAPE_ANY + 1), true);
  
  	return -EINVAL;
  }
  module_init(test_string_helpers_init);
  MODULE_LICENSE("Dual BSD/GPL");