linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii()
@ 2021-05-04 18:08 Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 01/15] lib/string_helpers: Switch to use BIT() macro Andy Shevchenko
                   ` (15 more replies)
  0 siblings, 16 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Get rid of ugly *_escape_mem_ascii() API since it's not flexible and
has the only single user. Provide better approach based on usage of the
string_escape_mem() with appropriate flags.

Test cases has been expanded accordingly to cover new functionality.

This is assumed to go either thru VFS or Andrew's tree. I don't expect
too many changes in string_helpers.

Changelog v3:
- dropped moving seq_escape() to the header due to a lot of complaints from
  the (very) old code
- added seq_escape_str() inliner
- converted seq_escape() to use seq_escape_str() instead of seq_escape_mem()

Changelog v2:
- introduced seq_escape_mem() instead of poking seq_get_buf() (Al)
- to keep balance of seq_get_buf() usage, convert seq_escape() to use above
- added missed ESCAPE_APPEND flag in NFSv4 patch
- moved indentation patch closer to the beginning of the series
- reshuffled series to be in two groups: generic library extension
  followed by seq_file updates

Andy Shevchenko (15):
  lib/string_helpers: Switch to use BIT() macro
  lib/string_helpers: Move ESCAPE_NP check inside 'else' branch in a
    loop
  lib/string_helpers: Drop indentation level in string_escape_mem()
  lib/string_helpers: Introduce ESCAPE_NA for escaping non-ASCII
  lib/string_helpers: Introduce ESCAPE_NAP to escape non-ASCII and
    non-printable
  lib/string_helpers: Allow to append additional characters to be
    escaped
  lib/test-string_helpers: Print flags in hexadecimal format
  lib/test-string_helpers: Get rid of trailing comma in terminators
  lib/test-string_helpers: Add test cases for new features
  MAINTAINERS: Add myself as designated reviewer for generic string
    library
  seq_file: Introduce seq_escape_mem()
  seq_file: Add seq_escape_str() as replica of string_escape_str()
  seq_file: Convert seq_escape() to use seq_escape_str()
  nfsd: Avoid non-flexible API in seq_quote_mem()
  seq_file: Drop unused *_escape_mem_ascii()

 MAINTAINERS                    |   8 ++
 fs/nfsd/nfs4state.c            |   2 +-
 fs/seq_file.c                  |  43 +++++----
 include/linux/seq_file.h       |  10 ++-
 include/linux/string_helpers.h |  31 ++++---
 lib/string_helpers.c           | 102 ++++++++++++---------
 lib/test-string_helpers.c      | 157 +++++++++++++++++++++++++++++----
 7 files changed, 264 insertions(+), 89 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 01/15] lib/string_helpers: Switch to use BIT() macro
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 02/15] lib/string_helpers: Move ESCAPE_NP check inside 'else' branch in a loop Andy Shevchenko
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Switch to use BIT() macro for flag definitions. No changes implied.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/string_helpers.h | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index fa06dcdc481e..bf01e24edd89 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -2,6 +2,7 @@
 #ifndef _LINUX_STRING_HELPERS_H_
 #define _LINUX_STRING_HELPERS_H_
 
+#include <linux/bits.h>
 #include <linux/ctype.h>
 #include <linux/types.h>
 
@@ -18,10 +19,10 @@ enum string_size_units {
 void string_get_size(u64 size, u64 blk_size, enum string_size_units units,
 		     char *buf, int len);
 
-#define UNESCAPE_SPACE		0x01
-#define UNESCAPE_OCTAL		0x02
-#define UNESCAPE_HEX		0x04
-#define UNESCAPE_SPECIAL	0x08
+#define UNESCAPE_SPACE		BIT(0)
+#define UNESCAPE_OCTAL		BIT(1)
+#define UNESCAPE_HEX		BIT(2)
+#define UNESCAPE_SPECIAL	BIT(3)
 #define UNESCAPE_ANY		\
 	(UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_HEX | UNESCAPE_SPECIAL)
 
@@ -42,15 +43,15 @@ static inline int string_unescape_any_inplace(char *buf)
 	return string_unescape_any(buf, buf, 0);
 }
 
-#define ESCAPE_SPACE		0x01
-#define ESCAPE_SPECIAL		0x02
-#define ESCAPE_NULL		0x04
-#define ESCAPE_OCTAL		0x08
+#define ESCAPE_SPACE		BIT(0)
+#define ESCAPE_SPECIAL		BIT(1)
+#define ESCAPE_NULL		BIT(2)
+#define ESCAPE_OCTAL		BIT(3)
 #define ESCAPE_ANY		\
 	(ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_SPECIAL | ESCAPE_NULL)
-#define ESCAPE_NP		0x10
+#define ESCAPE_NP		BIT(4)
 #define ESCAPE_ANY_NP		(ESCAPE_ANY | ESCAPE_NP)
-#define ESCAPE_HEX		0x20
+#define ESCAPE_HEX		BIT(5)
 
 int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 		unsigned int flags, const char *only);
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 02/15] lib/string_helpers: Move ESCAPE_NP check inside 'else' branch in a loop
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 01/15] lib/string_helpers: Switch to use BIT() macro Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 03/15] lib/string_helpers: Drop indentation level in string_escape_mem() Andy Shevchenko
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Refactor code to have better readability by moving ESCAPE_NP handling
inside 'else' branch in the loop.

No functional change intended.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/string_helpers.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index 7f2d5fbaf243..b10a18b4663b 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -452,10 +452,10 @@ static bool escape_hex(unsigned char c, char **dst, char *end)
  * The process of escaping byte buffer includes several parts. They are applied
  * in the following sequence.
  *
- *	1. 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 not matched to the one from @only string and thus
+ *	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.
  *	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
@@ -506,19 +506,22 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 
 		/*
 		 * Apply rules in the following sequence:
-		 *	- the character is printable, when @flags has
-		 *	  %ESCAPE_NP bit set
 		 *	- the @only string is supplied and does not contain a
 		 *	  character under question
+		 *	- the character is printable, when @flags has
+		 *	  %ESCAPE_NP 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
 		 * output buffer.
 		 */
-		if ((flags & ESCAPE_NP && isprint(c)) ||
-		    (is_dict && !strchr(only, c))) {
+		if (is_dict && !strchr(only, c)) {
 			/* do nothing */
 		} else {
+			if (isprint(c) &&
+			    flags & ESCAPE_NP && escape_passthrough(c, &p, end))
+				continue;
+
 			if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
 				continue;
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 03/15] lib/string_helpers: Drop indentation level in string_escape_mem()
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 01/15] lib/string_helpers: Switch to use BIT() macro Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 02/15] lib/string_helpers: Move ESCAPE_NP check inside 'else' branch in a loop Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 04/15] lib/string_helpers: Introduce ESCAPE_NA for escaping non-ASCII Andy Shevchenko
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

The only one conditional is left on the upper level, move the rest
to the same level and drop indentation level. No functional changes.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/string_helpers.c | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index b10a18b4663b..e3ef9f86cc34 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -515,29 +515,29 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 		 * In these cases we just pass through a character to the
 		 * output buffer.
 		 */
-		if (is_dict && !strchr(only, c)) {
-			/* do nothing */
-		} else {
-			if (isprint(c) &&
-			    flags & ESCAPE_NP && escape_passthrough(c, &p, end))
-				continue;
+		if (is_dict && !strchr(only, c) &&
+					  escape_passthrough(c, &p, end))
+			continue;
 
-			if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
-				continue;
+		if (isprint(c) &&
+		    flags & ESCAPE_NP && escape_passthrough(c, &p, end))
+			continue;
 
-			if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
-				continue;
+		if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
+			continue;
 
-			if (flags & ESCAPE_NULL && escape_null(c, &p, end))
-				continue;
+		if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
+			continue;
 
-			/* ESCAPE_OCTAL and ESCAPE_HEX always go last */
-			if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
-				continue;
+		if (flags & ESCAPE_NULL && escape_null(c, &p, end))
+			continue;
 
-			if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
-				continue;
-		}
+		/* ESCAPE_OCTAL and ESCAPE_HEX always go last */
+		if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
+			continue;
+
+		if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
+			continue;
 
 		escape_passthrough(c, &p, end);
 	}
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 04/15] lib/string_helpers: Introduce ESCAPE_NA for escaping non-ASCII
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (2 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 03/15] lib/string_helpers: Drop indentation level in string_escape_mem() Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 05/15] lib/string_helpers: Introduce ESCAPE_NAP to escape non-ASCII and non-printable Andy Shevchenko
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Some users may want to have an ASCII based filter, provided by
isascii() function. Here is the addition of a such.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/string_helpers.h |  1 +
 lib/string_helpers.c           | 21 +++++++++++++++++----
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index bf01e24edd89..d6cf6fe10f74 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -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);
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index e3ef9f86cc34..a963404b8c16 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -454,8 +454,8 @@ 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
@@ -463,7 +463,7 @@ static bool escape_hex(unsigned char c, char **dst, char *end)
  *
  * 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
@@ -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
@@ -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
@@ -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;
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 05/15] lib/string_helpers: Introduce ESCAPE_NAP to escape non-ASCII and non-printable
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (3 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 04/15] lib/string_helpers: Introduce ESCAPE_NA for escaping non-ASCII Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 06/15] lib/string_helpers: Allow to append additional characters to be escaped Andy Shevchenko
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Some users may want to have an ASCII based filter for printable only characters,
provided by conjunction of isascii() and isprint() functions.

Here is the addition of a such.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/string_helpers.h |  1 +
 lib/string_helpers.c           | 20 ++++++++++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index d6cf6fe10f74..811c6a627620 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -53,6 +53,7 @@ static inline int string_unescape_any_inplace(char *buf)
 #define ESCAPE_ANY_NP		(ESCAPE_ANY | ESCAPE_NP)
 #define ESCAPE_HEX		BIT(5)
 #define ESCAPE_NA		BIT(6)
+#define ESCAPE_NAP		BIT(7)
 
 int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 		unsigned int flags, const char *only);
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index a963404b8c16..ceca5fbbd92c 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -454,9 +454,11 @@ 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 or ASCII class, if asked,
+ *	2. The character is matched to the printable and ASCII classes, 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.
+ *	3. The character is matched to the printable or ASCII class, if asked,
+ *	   and in case of match it passes through to the output.
+ *	4. 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.
@@ -489,11 +491,15 @@ static bool escape_hex(unsigned char c, char **dst, char *end)
  *		'\xHH' - byte with hexadecimal value HH (2 digits)
  *	%ESCAPE_NA:
  *		escape only non-ascii characters, checked by isascii()
+ *	%ESCAPE_NAP:
+ *		escape only non-printable or non-ascii characters
  *
- * 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).
+ * One notable caveat, the %ESCAPE_NAP, %ESCAPE_NP and %ESCAPE_NA have the
+ * higher priority than the rest of the flags (%ESCAPE_NAP is the highest).
  * 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.
+ * %ESCAPE_NAP can utilize %ESCAPE_SPACE or %ESCAPE_SPECIAL in addition to
+ * the above.
  *
  * Return:
  * The total size of the escaped output that would be generated for
@@ -515,6 +521,8 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 		 * Apply rules in the following sequence:
 		 *	- the @only string is supplied and does not contain a
 		 *	  character under question
+		 *	- the character is printable and ASCII, when @flags has
+		 *	  %ESCAPE_NAP bit set
 		 *	- the character is printable, when @flags has
 		 *	  %ESCAPE_NP bit set
 		 *	- the character is ASCII, when @flags has
@@ -528,6 +536,10 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 					  escape_passthrough(c, &p, end))
 			continue;
 
+		if (isascii(c) && isprint(c) &&
+		    flags & ESCAPE_NAP && escape_passthrough(c, &p, end))
+			continue;
+
 		if (isprint(c) &&
 		    flags & ESCAPE_NP && escape_passthrough(c, &p, end))
 			continue;
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 06/15] lib/string_helpers: Allow to append additional characters to be escaped
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (4 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 05/15] lib/string_helpers: Introduce ESCAPE_NAP to escape non-ASCII and non-printable Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 07/15] lib/test-string_helpers: Print flags in hexadecimal format Andy Shevchenko
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Introduce a new flag to append additional characters, passed in 'only'
parameter, to be escaped if they fall in the corresponding class.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/string_helpers.h |  1 +
 lib/string_helpers.c           | 19 +++++++++++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index 811c6a627620..f8728ed4d563 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -54,6 +54,7 @@ static inline int string_unescape_any_inplace(char *buf)
 #define ESCAPE_HEX		BIT(5)
 #define ESCAPE_NA		BIT(6)
 #define ESCAPE_NAP		BIT(7)
+#define ESCAPE_APPEND		BIT(8)
 
 int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 		unsigned int flags, const char *only);
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index ceca5fbbd92c..c15aea7a82e9 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -493,6 +493,11 @@ static bool escape_hex(unsigned char c, char **dst, char *end)
  *		escape only non-ascii characters, checked by isascii()
  *	%ESCAPE_NAP:
  *		escape only non-printable or non-ascii characters
+ *	%ESCAPE_APPEND:
+ *		append characters from @only to be escaped by the given classes
+ *
+ * %ESCAPE_APPEND would help to pass additional characters to the escaped, when
+ * one of %ESCAPE_NP, %ESCAPE_NA, or %ESCAPE_NAP is provided.
  *
  * One notable caveat, the %ESCAPE_NAP, %ESCAPE_NP and %ESCAPE_NA have the
  * higher priority than the rest of the flags (%ESCAPE_NAP is the highest).
@@ -513,9 +518,11 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 	char *p = dst;
 	char *end = p + osz;
 	bool is_dict = only && *only;
+	bool is_append = flags & ESCAPE_APPEND;
 
 	while (isz--) {
 		unsigned char c = *src++;
+		bool in_dict = is_dict && strchr(only, c);
 
 		/*
 		 * Apply rules in the following sequence:
@@ -531,20 +538,24 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 		 *	  defined by given @flags
 		 * In these cases we just pass through a character to the
 		 * output buffer.
+		 *
+		 * When %ESCAPE_APPEND is passed, the characters from @only
+		 * have been excluded from the %ESCAPE_NAP, %ESCAPE_NP, and
+		 * %ESCAPE_NA cases.
 		 */
-		if (is_dict && !strchr(only, c) &&
+		if (!(is_append || in_dict) && is_dict &&
 					  escape_passthrough(c, &p, end))
 			continue;
 
-		if (isascii(c) && isprint(c) &&
+		if (!(is_append && in_dict) && isascii(c) && isprint(c) &&
 		    flags & ESCAPE_NAP && escape_passthrough(c, &p, end))
 			continue;
 
-		if (isprint(c) &&
+		if (!(is_append && in_dict) && isprint(c) &&
 		    flags & ESCAPE_NP && escape_passthrough(c, &p, end))
 			continue;
 
-		if (isascii(c) &&
+		if (!(is_append && in_dict) && isascii(c) &&
 		    flags & ESCAPE_NA && escape_passthrough(c, &p, end))
 			continue;
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 07/15] lib/test-string_helpers: Print flags in hexadecimal format
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (5 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 06/15] lib/string_helpers: Allow to append additional characters to be escaped Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 08/15] lib/test-string_helpers: Get rid of trailing comma in terminators Andy Shevchenko
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Since flags are bitmapped, it's better to print them in hexadecimal format.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/test-string_helpers.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c
index 10360d4ea273..079fb12d59cc 100644
--- a/lib/test-string_helpers.c
+++ b/lib/test-string_helpers.c
@@ -19,7 +19,7 @@ static __init bool test_string_check_buf(const char *name, unsigned int flags,
 	if (q_real == q_test && !memcmp(out_test, out_real, q_test))
 		return true;
 
-	pr_warn("Test '%s' failed: flags = %u\n", name, flags);
+	pr_warn("Test '%s' failed: flags = %#x\n", name, flags);
 
 	print_hex_dump(KERN_WARNING, "Input: ", DUMP_PREFIX_NONE, 16, 1,
 		       in, p, true);
@@ -290,7 +290,7 @@ test_string_escape_overflow(const char *in, int p, unsigned int flags, const cha
 
 	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",
+		pr_warn("Test '%s' failed: flags = %#x, osz = 0, expected %d, got %d\n",
 			name, flags, q_test, q_real);
 }
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 08/15] lib/test-string_helpers: Get rid of trailing comma in terminators
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (6 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 07/15] lib/test-string_helpers: Print flags in hexadecimal format Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 09/15] lib/test-string_helpers: Add test cases for new features Andy Shevchenko
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Terminators by definition shouldn't accept anything behind.
Make them robust by removing trailing commas.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/test-string_helpers.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c
index 079fb12d59cc..3e2def9ccfac 100644
--- a/lib/test-string_helpers.c
+++ b/lib/test-string_helpers.c
@@ -136,7 +136,7 @@ static const struct test_string_2 escape0[] __initconst = {{
 		.flags = ESCAPE_SPACE | ESCAPE_HEX,
 	},{
 		/* terminator */
-	}},
+	}}
 },{
 	.in = "\\h\\\"\a\e\\",
 	.s1 = {{
@@ -150,7 +150,7 @@ static const struct test_string_2 escape0[] __initconst = {{
 		.flags = ESCAPE_SPECIAL | ESCAPE_HEX,
 	},{
 		/* terminator */
-	}},
+	}}
 },{
 	.in = "\eb \\C\007\"\x90\r]",
 	.s1 = {{
@@ -201,7 +201,7 @@ static const struct test_string_2 escape0[] __initconst = {{
 		.flags = ESCAPE_NP | ESCAPE_HEX,
 	},{
 		/* terminator */
-	}},
+	}}
 },{
 	/* terminator */
 }};
@@ -217,7 +217,7 @@ static const struct test_string_2 escape1[] __initconst = {{
 		.flags = ESCAPE_HEX,
 	},{
 		/* terminator */
-	}},
+	}}
 },{
 	.in = "\\h\\\"\a\e\\",
 	.s1 = {{
@@ -225,7 +225,7 @@ static const struct test_string_2 escape1[] __initconst = {{
 		.flags = ESCAPE_OCTAL,
 	},{
 		/* terminator */
-	}},
+	}}
 },{
 	.in = "\eb \\C\007\"\x90\r]",
 	.s1 = {{
@@ -233,7 +233,7 @@ static const struct test_string_2 escape1[] __initconst = {{
 		.flags = ESCAPE_OCTAL,
 	},{
 		/* terminator */
-	}},
+	}}
 },{
 	/* terminator */
 }};
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 09/15] lib/test-string_helpers: Add test cases for new features
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (7 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 08/15] lib/test-string_helpers: Get rid of trailing comma in terminators Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 10/15] MAINTAINERS: Add myself as designated reviewer for generic string library Andy Shevchenko
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

We have got new flags and hence new features of string_escape_mem().
Add test cases for that.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/string_helpers.h |   4 +
 lib/test-string_helpers.c      | 141 +++++++++++++++++++++++++++++++--
 2 files changed, 137 insertions(+), 8 deletions(-)

diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index f8728ed4d563..9b0eca2badf2 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -26,6 +26,8 @@ void string_get_size(u64 size, u64 blk_size, enum string_size_units units,
 #define UNESCAPE_ANY		\
 	(UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_HEX | UNESCAPE_SPECIAL)
 
+#define UNESCAPE_ALL_MASK	GENMASK(3, 0)
+
 int string_unescape(char *src, char *dst, size_t size, unsigned int flags);
 
 static inline int string_unescape_inplace(char *buf, unsigned int flags)
@@ -56,6 +58,8 @@ static inline int string_unescape_any_inplace(char *buf)
 #define ESCAPE_NAP		BIT(7)
 #define ESCAPE_APPEND		BIT(8)
 
+#define ESCAPE_ALL_MASK		GENMASK(8, 0)
+
 int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 		unsigned int flags, const char *only);
 
diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c
index 3e2def9ccfac..2185d71704f0 100644
--- a/lib/test-string_helpers.c
+++ b/lib/test-string_helpers.c
@@ -202,11 +202,25 @@ static const struct test_string_2 escape0[] __initconst = {{
 	},{
 		/* terminator */
 	}}
+},{
+	.in = "\007 \eb\"\x90\xCF\r",
+	.s1 = {{
+		.out = "\007 \eb\"\\220\\317\r",
+		.flags = ESCAPE_OCTAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\\x90\\xcf\r",
+		.flags = ESCAPE_HEX | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_NA,
+	},{
+		/* terminator */
+	}}
 },{
 	/* terminator */
 }};
 
-#define	TEST_STRING_2_DICT_1		"b\\ \t\r"
+#define	TEST_STRING_2_DICT_1		"b\\ \t\r\xCF"
 static const struct test_string_2 escape1[] __initconst = {{
 	.in = "\f\\ \n\r\t\v",
 	.s1 = {{
@@ -215,14 +229,38 @@ static const struct test_string_2 escape1[] __initconst = {{
 	},{
 		.out = "\f\\x5c\\x20\n\\x0d\\x09\v",
 		.flags = ESCAPE_HEX,
+	},{
+		.out = "\f\\134\\040\n\\015\\011\v",
+		.flags = ESCAPE_ANY | ESCAPE_APPEND,
+	},{
+		.out = "\\014\\134\\040\\012\\015\\011\\013",
+		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NAP,
+	},{
+		.out = "\\x0c\\x5c\\x20\\x0a\\x0d\\x09\\x0b",
+		.flags = ESCAPE_HEX | ESCAPE_APPEND | ESCAPE_NAP,
+	},{
+		.out = "\f\\134\\040\n\\015\\011\v",
+		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NA,
+	},{
+		.out = "\f\\x5c\\x20\n\\x0d\\x09\v",
+		.flags = ESCAPE_HEX | ESCAPE_APPEND | ESCAPE_NA,
 	},{
 		/* terminator */
 	}}
 },{
-	.in = "\\h\\\"\a\e\\",
+	.in = "\\h\\\"\a\xCF\e\\",
 	.s1 = {{
-		.out = "\\134h\\134\"\a\e\\134",
+		.out = "\\134h\\134\"\a\\317\e\\134",
 		.flags = ESCAPE_OCTAL,
+	},{
+		.out = "\\134h\\134\"\a\\317\e\\134",
+		.flags = ESCAPE_ANY | ESCAPE_APPEND,
+	},{
+		.out = "\\134h\\134\"\\007\\317\\033\\134",
+		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NAP,
+	},{
+		.out = "\\134h\\134\"\a\\317\e\\134",
+		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NA,
 	},{
 		/* terminator */
 	}}
@@ -234,6 +272,88 @@ static const struct test_string_2 escape1[] __initconst = {{
 	},{
 		/* terminator */
 	}}
+},{
+	.in = "\007 \eb\"\x90\xCF\r",
+	.s1 = {{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_SPACE | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_SPECIAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_OCTAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_ANY | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\r",
+		.flags = ESCAPE_HEX | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\r",
+		.flags = ESCAPE_SPACE | ESCAPE_HEX | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\r",
+		.flags = ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\r",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NA,
+	},{
+		/* terminator */
+	}}
+},{
+	.in = "\007 \eb\"\x90\xCF\r",
+	.s1 = {{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\xCF\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_SPECIAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\xCF\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\317\\015",
+		.flags = ESCAPE_OCTAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\317\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\317\\015",
+		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_ANY | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\\x0d",
+		.flags = ESCAPE_HEX | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_HEX | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\\x0d",
+		.flags = ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NAP,
+	},{
+		/* terminator */
+	}}
 },{
 	/* terminator */
 }};
@@ -315,8 +435,13 @@ static __init void test_string_escape(const char *name,
 		/* NULL injection */
 		if (flags & ESCAPE_NULL) {
 			in[p++] = '\0';
-			out_test[q_test++] = '\\';
-			out_test[q_test++] = '0';
+			/* '\0' passes isascii() test */
+			if (flags & ESCAPE_NA && !(flags & ESCAPE_APPEND && esc)) {
+				out_test[q_test++] = '\0';
+			} else {
+				out_test[q_test++] = '\\';
+				out_test[q_test++] = '0';
+			}
 		}
 
 		/* Don't try strings that have no output */
@@ -459,17 +584,17 @@ static int __init test_string_helpers_init(void)
 	unsigned int i;
 
 	pr_info("Running tests...\n");
-	for (i = 0; i < UNESCAPE_ANY + 1; i++)
+	for (i = 0; i < UNESCAPE_ALL_MASK + 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++)
+	for (i = 0; i < ESCAPE_ALL_MASK + 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++)
+	for (i = 0; i < ESCAPE_ALL_MASK + 1; i++)
 		test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1);
 
 	/* Test string_get_size() */
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 10/15] MAINTAINERS: Add myself as designated reviewer for generic string library
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (8 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 09/15] lib/test-string_helpers: Add test cases for new features Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-12  6:20   ` Joe Perches
  2021-05-04 18:08 ` [PATCH v3 11/15] seq_file: Introduce seq_escape_mem() Andy Shevchenko
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Add myself as designated reviewer for generic string library.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1783372a608a..2c5797fc462c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7650,6 +7650,14 @@ L:	linux-input@vger.kernel.org
 S:	Maintained
 F:	drivers/input/touchscreen/resistive-adc-touch.c
 
+GENERIC STRING LIBRARY
+R:	Andy Shevchenko <andy@kernel.org>
+S:	Maintained
+F:	lib/string.c
+F:	lib/string_helpers.c
+F:	lib/test_string.c
+F:	lib/test-string_helpers.c
+
 GENERIC UIO DRIVER FOR PCI DEVICES
 M:	"Michael S. Tsirkin" <mst@redhat.com>
 L:	kvm@vger.kernel.org
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 11/15] seq_file: Introduce seq_escape_mem()
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (9 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 10/15] MAINTAINERS: Add myself as designated reviewer for generic string library Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 12/15] seq_file: Add seq_escape_str() as replica of string_escape_str() Andy Shevchenko
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Introduce seq_escape_mem() to allow users to pass additional parameters
to string_escape_mem().

Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 fs/seq_file.c            | 25 +++++++++++++++++++++++++
 include/linux/seq_file.h |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index 5059248f2d64..532cac2eae0f 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -355,6 +355,31 @@ int seq_release(struct inode *inode, struct file *file)
 }
 EXPORT_SYMBOL(seq_release);
 
+/**
+ * seq_escape_mem - print data into buffer, escaping some characters
+ * @m: target buffer
+ * @src: source buffer
+ * @len: size of source buffer
+ * @flags: flags to pass to string_escape_mem()
+ * @esc: set of characters that need escaping
+ *
+ * Puts data into buffer, replacing each occurrence of character from
+ * given class (defined by @flags and @esc) with printable escaped sequence.
+ *
+ * Use seq_has_overflowed() to check for errors.
+ */
+void seq_escape_mem(struct seq_file *m, const char *src, size_t len,
+		    unsigned int flags, const char *esc)
+{
+	char *buf;
+	size_t size = seq_get_buf(m, &buf);
+	int ret;
+
+	ret = string_escape_mem(src, len, buf, size, flags, esc);
+	seq_commit(m, ret < size ? ret : -1);
+}
+EXPORT_SYMBOL(seq_escape_mem);
+
 /**
  *	seq_escape -	print string into buffer, escaping some characters
  *	@m:	target buffer
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 723b1fa1177e..6de442182784 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -126,6 +126,8 @@ void seq_put_decimal_ll(struct seq_file *m, const char *delimiter, long long num
 void seq_put_hex_ll(struct seq_file *m, const char *delimiter,
 		    unsigned long long v, unsigned int width);
 
+void seq_escape_mem(struct seq_file *m, const char *src, size_t len,
+		    unsigned int flags, const char *esc);
 void seq_escape(struct seq_file *m, const char *s, const char *esc);
 void seq_escape_mem_ascii(struct seq_file *m, const char *src, size_t isz);
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 12/15] seq_file: Add seq_escape_str() as replica of string_escape_str()
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (10 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 11/15] seq_file: Introduce seq_escape_mem() Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 13/15] seq_file: Convert seq_escape() to use seq_escape_str() Andy Shevchenko
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

In some cases we want to escape characters from NULL-terminated strings.
Add seq_escape_str() as replica of string_escape_str() for that.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/seq_file.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 6de442182784..63f021cb1b12 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -128,6 +128,13 @@ void seq_put_hex_ll(struct seq_file *m, const char *delimiter,
 
 void seq_escape_mem(struct seq_file *m, const char *src, size_t len,
 		    unsigned int flags, const char *esc);
+
+static inline void seq_escape_str(struct seq_file *m, const char *src,
+				  unsigned int flags, const char *esc)
+{
+	seq_escape_mem(m, src, strlen(src), flags, esc);
+}
+
 void seq_escape(struct seq_file *m, const char *s, const char *esc);
 void seq_escape_mem_ascii(struct seq_file *m, const char *src, size_t isz);
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 13/15] seq_file: Convert seq_escape() to use seq_escape_str()
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (11 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 12/15] seq_file: Add seq_escape_str() as replica of string_escape_str() Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 14/15] nfsd: Avoid non-flexible API in seq_quote_mem() Andy Shevchenko
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

Convert seq_escape() to use seq_escape_str() rather than open coding it.

Note, for now we leave it as an exported symbol due to some old code
that can't tolerate ctype.h being (indirectly) included.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 fs/seq_file.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index 532cac2eae0f..08f54029c2b1 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -392,12 +392,7 @@ EXPORT_SYMBOL(seq_escape_mem);
  */
 void seq_escape(struct seq_file *m, const char *s, const char *esc)
 {
-	char *buf;
-	size_t size = seq_get_buf(m, &buf);
-	int ret;
-
-	ret = string_escape_str(s, buf, size, ESCAPE_OCTAL, esc);
-	seq_commit(m, ret < size ? ret : -1);
+	seq_escape_str(m, s, ESCAPE_OCTAL, esc);
 }
 EXPORT_SYMBOL(seq_escape);
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 14/15] nfsd: Avoid non-flexible API in seq_quote_mem()
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (12 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 13/15] seq_file: Convert seq_escape() to use seq_escape_str() Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-04 18:08 ` [PATCH v3 15/15] seq_file: Drop unused *_escape_mem_ascii() Andy Shevchenko
  2021-05-11 18:57 ` [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() J. Bruce Fields
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

The seq_escape_mem_ascii() is completely non-flexible and shouldn't be used.
Replace it with properly called seq_escape_mem().

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 fs/nfsd/nfs4state.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b517a8794400..cd5eac2ba054 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2351,7 +2351,7 @@ static struct nfs4_client *get_nfsdfs_clp(struct inode *inode)
 static void seq_quote_mem(struct seq_file *m, char *data, int len)
 {
 	seq_printf(m, "\"");
-	seq_escape_mem_ascii(m, data, len);
+	seq_escape_mem(m, data, len, ESCAPE_HEX | ESCAPE_NAP | ESCAPE_APPEND, "\"\\");
 	seq_printf(m, "\"");
 }
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 15/15] seq_file: Drop unused *_escape_mem_ascii()
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (13 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 14/15] nfsd: Avoid non-flexible API in seq_quote_mem() Andy Shevchenko
@ 2021-05-04 18:08 ` Andy Shevchenko
  2021-05-11 18:57 ` [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() J. Bruce Fields
  15 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2021-05-04 18:08 UTC (permalink / raw)
  To: J. Bruce Fields, Andy Shevchenko, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

There are no more users of the seq_escape_mem_ascii()
followed by string_escape_mem_ascii().

Remove them for good.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 fs/seq_file.c                  | 11 -----------
 include/linux/seq_file.h       |  1 -
 include/linux/string_helpers.h |  3 ---
 lib/string_helpers.c           | 19 -------------------
 4 files changed, 34 deletions(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index 08f54029c2b1..b117b212ef28 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -396,17 +396,6 @@ void seq_escape(struct seq_file *m, const char *s, const char *esc)
 }
 EXPORT_SYMBOL(seq_escape);
 
-void seq_escape_mem_ascii(struct seq_file *m, const char *src, size_t isz)
-{
-	char *buf;
-	size_t size = seq_get_buf(m, &buf);
-	int ret;
-
-	ret = string_escape_mem_ascii(src, isz, buf, size);
-	seq_commit(m, ret < size ? ret : -1);
-}
-EXPORT_SYMBOL(seq_escape_mem_ascii);
-
 void seq_vprintf(struct seq_file *m, const char *f, va_list args)
 {
 	int len;
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 63f021cb1b12..dd99569595fd 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -136,7 +136,6 @@ static inline void seq_escape_str(struct seq_file *m, const char *src,
 }
 
 void seq_escape(struct seq_file *m, const char *s, const char *esc);
-void seq_escape_mem_ascii(struct seq_file *m, const char *src, size_t isz);
 
 void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
 		  int rowsize, int groupsize, const void *buf, size_t len,
diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index 9b0eca2badf2..68189c4a2eb1 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -63,9 +63,6 @@ static inline int string_unescape_any_inplace(char *buf)
 int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 		unsigned int flags, const char *only);
 
-int string_escape_mem_ascii(const char *src, size_t isz, char *dst,
-					size_t osz);
-
 static inline int string_escape_mem_any_np(const char *src, size_t isz,
 		char *dst, size_t osz, const char *only)
 {
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index c15aea7a82e9..5a35c7e16e96 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -582,25 +582,6 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
 }
 EXPORT_SYMBOL(string_escape_mem);
 
-int string_escape_mem_ascii(const char *src, size_t isz, char *dst,
-					size_t osz)
-{
-	char *p = dst;
-	char *end = p + osz;
-
-	while (isz--) {
-		unsigned char c = *src++;
-
-		if (!isprint(c) || !isascii(c) || c == '"' || c == '\\')
-			escape_hex(c, &p, end);
-		else
-			escape_passthrough(c, &p, end);
-	}
-
-	return p - dst;
-}
-EXPORT_SYMBOL(string_escape_mem_ascii);
-
 /*
  * Return an allocated string that has been escaped of special characters
  * and double quotes, making it safe to log in quotes.
-- 
2.30.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii()
  2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
                   ` (14 preceding siblings ...)
  2021-05-04 18:08 ` [PATCH v3 15/15] seq_file: Drop unused *_escape_mem_ascii() Andy Shevchenko
@ 2021-05-11 18:57 ` J. Bruce Fields
  15 siblings, 0 replies; 18+ messages in thread
From: J. Bruce Fields @ 2021-05-11 18:57 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: J. Bruce Fields, linux-kernel, linux-nfs, linux-fsdevel,
	Chuck Lever, Alexander Viro, Andy Shevchenko, Andrew Morton

These look good to me, thanks for doing this!

--b.

On Tue, May 04, 2021 at 09:08:04PM +0300, Andy Shevchenko wrote:
> Get rid of ugly *_escape_mem_ascii() API since it's not flexible and
> has the only single user. Provide better approach based on usage of the
> string_escape_mem() with appropriate flags.
> 
> Test cases has been expanded accordingly to cover new functionality.
> 
> This is assumed to go either thru VFS or Andrew's tree. I don't expect
> too many changes in string_helpers.
> 
> Changelog v3:
> - dropped moving seq_escape() to the header due to a lot of complaints from
>   the (very) old code
> - added seq_escape_str() inliner
> - converted seq_escape() to use seq_escape_str() instead of seq_escape_mem()
> 
> Changelog v2:
> - introduced seq_escape_mem() instead of poking seq_get_buf() (Al)
> - to keep balance of seq_get_buf() usage, convert seq_escape() to use above
> - added missed ESCAPE_APPEND flag in NFSv4 patch
> - moved indentation patch closer to the beginning of the series
> - reshuffled series to be in two groups: generic library extension
>   followed by seq_file updates
> 
> Andy Shevchenko (15):
>   lib/string_helpers: Switch to use BIT() macro
>   lib/string_helpers: Move ESCAPE_NP check inside 'else' branch in a
>     loop
>   lib/string_helpers: Drop indentation level in string_escape_mem()
>   lib/string_helpers: Introduce ESCAPE_NA for escaping non-ASCII
>   lib/string_helpers: Introduce ESCAPE_NAP to escape non-ASCII and
>     non-printable
>   lib/string_helpers: Allow to append additional characters to be
>     escaped
>   lib/test-string_helpers: Print flags in hexadecimal format
>   lib/test-string_helpers: Get rid of trailing comma in terminators
>   lib/test-string_helpers: Add test cases for new features
>   MAINTAINERS: Add myself as designated reviewer for generic string
>     library
>   seq_file: Introduce seq_escape_mem()
>   seq_file: Add seq_escape_str() as replica of string_escape_str()
>   seq_file: Convert seq_escape() to use seq_escape_str()
>   nfsd: Avoid non-flexible API in seq_quote_mem()
>   seq_file: Drop unused *_escape_mem_ascii()
> 
>  MAINTAINERS                    |   8 ++
>  fs/nfsd/nfs4state.c            |   2 +-
>  fs/seq_file.c                  |  43 +++++----
>  include/linux/seq_file.h       |  10 ++-
>  include/linux/string_helpers.h |  31 ++++---
>  lib/string_helpers.c           | 102 ++++++++++++---------
>  lib/test-string_helpers.c      | 157 +++++++++++++++++++++++++++++----
>  7 files changed, 264 insertions(+), 89 deletions(-)
> 
> -- 
> 2.30.2

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 10/15] MAINTAINERS: Add myself as designated reviewer for generic string library
  2021-05-04 18:08 ` [PATCH v3 10/15] MAINTAINERS: Add myself as designated reviewer for generic string library Andy Shevchenko
@ 2021-05-12  6:20   ` Joe Perches
  0 siblings, 0 replies; 18+ messages in thread
From: Joe Perches @ 2021-05-12  6:20 UTC (permalink / raw)
  To: Andy Shevchenko, J. Bruce Fields, linux-kernel, linux-nfs, linux-fsdevel
  Cc: J. Bruce Fields, Chuck Lever, Alexander Viro, Andy Shevchenko,
	Andrew Morton

On Tue, 2021-05-04 at 21:08 +0300, Andy Shevchenko wrote:
> Add myself as designated reviewer for generic string library.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  MAINTAINERS | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1783372a608a..2c5797fc462c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7650,6 +7650,14 @@ L:	linux-input@vger.kernel.org
>  S:	Maintained
>  F:	drivers/input/touchscreen/resistive-adc-touch.c
>  
> 
> +GENERIC STRING LIBRARY
> +R:	Andy Shevchenko <andy@kernel.org>
> +S:	Maintained
> +F:	lib/string.c
> +F:	lib/string_helpers.c
> +F:	lib/test_string.c
> +F:	lib/test-string_helpers.c

How can something be maintained if it has only a reviewer?



^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2021-05-12  6:20 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-04 18:08 [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 01/15] lib/string_helpers: Switch to use BIT() macro Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 02/15] lib/string_helpers: Move ESCAPE_NP check inside 'else' branch in a loop Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 03/15] lib/string_helpers: Drop indentation level in string_escape_mem() Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 04/15] lib/string_helpers: Introduce ESCAPE_NA for escaping non-ASCII Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 05/15] lib/string_helpers: Introduce ESCAPE_NAP to escape non-ASCII and non-printable Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 06/15] lib/string_helpers: Allow to append additional characters to be escaped Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 07/15] lib/test-string_helpers: Print flags in hexadecimal format Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 08/15] lib/test-string_helpers: Get rid of trailing comma in terminators Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 09/15] lib/test-string_helpers: Add test cases for new features Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 10/15] MAINTAINERS: Add myself as designated reviewer for generic string library Andy Shevchenko
2021-05-12  6:20   ` Joe Perches
2021-05-04 18:08 ` [PATCH v3 11/15] seq_file: Introduce seq_escape_mem() Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 12/15] seq_file: Add seq_escape_str() as replica of string_escape_str() Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 13/15] seq_file: Convert seq_escape() to use seq_escape_str() Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 14/15] nfsd: Avoid non-flexible API in seq_quote_mem() Andy Shevchenko
2021-05-04 18:08 ` [PATCH v3 15/15] seq_file: Drop unused *_escape_mem_ascii() Andy Shevchenko
2021-05-11 18:57 ` [PATCH v3 00/15] lib/string_helpers: get rid of ugly *_escape_mem_ascii() J. Bruce Fields

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).