Skip to content

Commit

Permalink
lib/string_helpers: introduce ESCAPE_NA for escaping non-ASCII
Browse files Browse the repository at this point in the history
Some users may want to have an ASCII based filter, provided by isascii()
function.  Here is the addition of a such.

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Andy Shevchenko <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Chuck Lever <[email protected]>
Cc: "J. Bruce Fields" <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
andy-shev authored and torvalds committed Jul 1, 2021
1 parent 7e5969a commit a080978
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
1 change: 1 addition & 0 deletions include/linux/string_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ static inline int string_unescape_any_inplace(char *buf)
#define ESCAPE_NP BIT(4)
#define ESCAPE_ANY_NP (ESCAPE_ANY | ESCAPE_NP)
#define ESCAPE_HEX BIT(5)
#define ESCAPE_NA BIT(6)

int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
unsigned int flags, const char *only);
Expand Down
21 changes: 17 additions & 4 deletions lib/string_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,16 +454,16 @@ static bool escape_hex(unsigned char c, char **dst, char *end)
*
* 1. The character is not matched to the one from @only string and thus
* must go as-is to the output.
* 2. The character is matched to the printable class, if asked, and in
* case of match it passes through to the output.
* 2. The character is matched to the printable or ASCII class, if asked,
* and in case of match it passes through to the output.
* 3. The character is checked if it falls into the class given by @flags.
* %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any
* character. Note that they actually can't go together, otherwise
* %ESCAPE_HEX will be ignored.
*
* Caller must provide valid source and destination pointers. Be aware that
* destination buffer will not be NULL-terminated, thus caller have to append
* it if needs. The supported flags are::
* it if needs. The supported flags are::
*
* %ESCAPE_SPACE: (special white space, not space itself)
* '\f' - form feed
Expand All @@ -482,11 +482,18 @@ static bool escape_hex(unsigned char c, char **dst, char *end)
* %ESCAPE_ANY:
* all previous together
* %ESCAPE_NP:
* escape only non-printable characters (checked by isprint)
* escape only non-printable characters, checked by isprint()
* %ESCAPE_ANY_NP:
* all previous together
* %ESCAPE_HEX:
* '\xHH' - byte with hexadecimal value HH (2 digits)
* %ESCAPE_NA:
* escape only non-ascii characters, checked by isascii()
*
* One notable caveat, the %ESCAPE_NP and %ESCAPE_NA have higher priority
* than the rest of the flags (%ESCAPE_NP is higher than %ESCAPE_NA).
* It doesn't make much sense to use either of them without %ESCAPE_OCTAL
* or %ESCAPE_HEX, because they cover most of the other character classes.
*
* Return:
* The total size of the escaped output that would be generated for
Expand All @@ -510,6 +517,8 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
* character under question
* - the character is printable, when @flags has
* %ESCAPE_NP bit set
* - the character is ASCII, when @flags has
* %ESCAPE_NA bit set
* - the character doesn't fall into a class of symbols
* defined by given @flags
* In these cases we just pass through a character to the
Expand All @@ -523,6 +532,10 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
flags & ESCAPE_NP && escape_passthrough(c, &p, end))
continue;

if (isascii(c) &&
flags & ESCAPE_NA && escape_passthrough(c, &p, end))
continue;

if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
continue;

Expand Down

0 comments on commit a080978

Please sign in to comment.