mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
lib/string_helpers: introduce generic string_unescape
There are several places in kernel where modules unescapes input to convert C-Style Escape Sequences into byte codes. The patch provides generic implementation of such approach. Test cases are also included into the patch. [akpm@linux-foundation.org: clarify comment] [akpm@linux-foundation.org: export get_random_int() to modules] Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Samuel Thibault <samuel.thibault@ens-lyon.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jason Baron <jbaron@redhat.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: William Hubbs <w.d.hubbs@gmail.com> Cc: Chris Brannon <chris@the-brannons.com> Cc: Kirk Reiser <kirk@braille.uwo.ca> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
e1d12f3270
commit
16c7fa0582
6 changed files with 301 additions and 1 deletions
|
@ -2,10 +2,12 @@
|
|||
* Helpers for formatting and printing strings
|
||||
*
|
||||
* Copyright 31 August 2008 James Bottomley
|
||||
* Copyright (C) 2013, Intel Corporation
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
/**
|
||||
|
@ -66,3 +68,134 @@ int string_get_size(u64 size, const enum string_size_units units,
|
|||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(string_get_size);
|
||||
|
||||
static bool unescape_space(char **src, char **dst)
|
||||
{
|
||||
char *p = *dst, *q = *src;
|
||||
|
||||
switch (*q) {
|
||||
case 'n':
|
||||
*p = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
*p = '\r';
|
||||
break;
|
||||
case 't':
|
||||
*p = '\t';
|
||||
break;
|
||||
case 'v':
|
||||
*p = '\v';
|
||||
break;
|
||||
case 'f':
|
||||
*p = '\f';
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
*dst += 1;
|
||||
*src += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool unescape_octal(char **src, char **dst)
|
||||
{
|
||||
char *p = *dst, *q = *src;
|
||||
u8 num;
|
||||
|
||||
if (isodigit(*q) == 0)
|
||||
return false;
|
||||
|
||||
num = (*q++) & 7;
|
||||
while (num < 32 && isodigit(*q) && (q - *src < 3)) {
|
||||
num <<= 3;
|
||||
num += (*q++) & 7;
|
||||
}
|
||||
*p = num;
|
||||
*dst += 1;
|
||||
*src = q;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool unescape_hex(char **src, char **dst)
|
||||
{
|
||||
char *p = *dst, *q = *src;
|
||||
int digit;
|
||||
u8 num;
|
||||
|
||||
if (*q++ != 'x')
|
||||
return false;
|
||||
|
||||
num = digit = hex_to_bin(*q++);
|
||||
if (digit < 0)
|
||||
return false;
|
||||
|
||||
digit = hex_to_bin(*q);
|
||||
if (digit >= 0) {
|
||||
q++;
|
||||
num = (num << 4) | digit;
|
||||
}
|
||||
*p = num;
|
||||
*dst += 1;
|
||||
*src = q;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool unescape_special(char **src, char **dst)
|
||||
{
|
||||
char *p = *dst, *q = *src;
|
||||
|
||||
switch (*q) {
|
||||
case '\"':
|
||||
*p = '\"';
|
||||
break;
|
||||
case '\\':
|
||||
*p = '\\';
|
||||
break;
|
||||
case 'a':
|
||||
*p = '\a';
|
||||
break;
|
||||
case 'e':
|
||||
*p = '\e';
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
*dst += 1;
|
||||
*src += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
|
||||
{
|
||||
char *out = dst;
|
||||
|
||||
while (*src && --size) {
|
||||
if (src[0] == '\\' && src[1] != '\0' && size > 1) {
|
||||
src++;
|
||||
size--;
|
||||
|
||||
if (flags & UNESCAPE_SPACE &&
|
||||
unescape_space(&src, &out))
|
||||
continue;
|
||||
|
||||
if (flags & UNESCAPE_OCTAL &&
|
||||
unescape_octal(&src, &out))
|
||||
continue;
|
||||
|
||||
if (flags & UNESCAPE_HEX &&
|
||||
unescape_hex(&src, &out))
|
||||
continue;
|
||||
|
||||
if (flags & UNESCAPE_SPECIAL &&
|
||||
unescape_special(&src, &out))
|
||||
continue;
|
||||
|
||||
*out++ = '\\';
|
||||
}
|
||||
*out++ = *src++;
|
||||
}
|
||||
*out = '\0';
|
||||
|
||||
return out - dst;
|
||||
}
|
||||
EXPORT_SYMBOL(string_unescape);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue