linux/lib/test-string_helpers.c
<<
>>
Prefs
   1/*
   2 * Test cases for lib/string_helpers.c module.
   3 */
   4#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   5
   6#include <linux/init.h>
   7#include <linux/kernel.h>
   8#include <linux/module.h>
   9#include <linux/random.h>
  10#include <linux/string.h>
  11#include <linux/string_helpers.h>
  12
  13struct test_string {
  14        const char *in;
  15        const char *out;
  16        unsigned int flags;
  17};
  18
  19static const struct test_string strings[] __initconst = {
  20        {
  21                .in = "\\f\\ \\n\\r\\t\\v",
  22                .out = "\f\\ \n\r\t\v",
  23                .flags = UNESCAPE_SPACE,
  24        },
  25        {
  26                .in = "\\40\\1\\387\\0064\\05\\040\\8a\\110\\777",
  27                .out = " \001\00387\0064\005 \\8aH?7",
  28                .flags = UNESCAPE_OCTAL,
  29        },
  30        {
  31                .in = "\\xv\\xa\\x2c\\xD\\x6f2",
  32                .out = "\\xv\n,\ro2",
  33                .flags = UNESCAPE_HEX,
  34        },
  35        {
  36                .in = "\\h\\\\\\\"\\a\\e\\",
  37                .out = "\\h\\\"\a\e\\",
  38                .flags = UNESCAPE_SPECIAL,
  39        },
  40};
  41
  42static void __init test_string_unescape(unsigned int flags, bool inplace)
  43{
  44        char in[256];
  45        char out_test[256];
  46        char out_real[256];
  47        int i, p = 0, q_test = 0, q_real = sizeof(out_real);
  48
  49        for (i = 0; i < ARRAY_SIZE(strings); i++) {
  50                const char *s = strings[i].in;
  51                int len = strlen(strings[i].in);
  52
  53                /* Copy string to in buffer */
  54                memcpy(&in[p], s, len);
  55                p += len;
  56
  57                /* Copy expected result for given flags */
  58                if (flags & strings[i].flags) {
  59                        s = strings[i].out;
  60                        len = strlen(strings[i].out);
  61                }
  62                memcpy(&out_test[q_test], s, len);
  63                q_test += len;
  64        }
  65        in[p++] = '\0';
  66
  67        /* Call string_unescape and compare result */
  68        if (inplace) {
  69                memcpy(out_real, in, p);
  70                if (flags == UNESCAPE_ANY)
  71                        q_real = string_unescape_any_inplace(out_real);
  72                else
  73                        q_real = string_unescape_inplace(out_real, flags);
  74        } else if (flags == UNESCAPE_ANY) {
  75                q_real = string_unescape_any(in, out_real, q_real);
  76        } else {
  77                q_real = string_unescape(in, out_real, q_real, flags);
  78        }
  79
  80        if (q_real != q_test || memcmp(out_test, out_real, q_test)) {
  81                pr_warn("Test failed: flags = %u\n", flags);
  82                print_hex_dump(KERN_WARNING, "Input: ",
  83                               DUMP_PREFIX_NONE, 16, 1, in, p - 1, true);
  84                print_hex_dump(KERN_WARNING, "Expected: ",
  85                               DUMP_PREFIX_NONE, 16, 1, out_test, q_test, true);
  86                print_hex_dump(KERN_WARNING, "Got: ",
  87                               DUMP_PREFIX_NONE, 16, 1, out_real, q_real, true);
  88        }
  89}
  90
  91static int __init test_string_helpers_init(void)
  92{
  93        unsigned int i;
  94
  95        pr_info("Running tests...\n");
  96        for (i = 0; i < UNESCAPE_ANY + 1; i++)
  97                test_string_unescape(i, false);
  98        test_string_unescape(get_random_int() % (UNESCAPE_ANY + 1), true);
  99
 100        return -EINVAL;
 101}
 102module_init(test_string_helpers_init);
 103MODULE_LICENSE("Dual BSD/GPL");
 104