The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Petr Mladek <pmladek@suse.com>
To: Kent Overstreet <kent.overstreet@gmail.com>
Cc: linux-kernel@vger.kernel.org, rostedt@goodmis.org
Subject: Re: [PATCH v3 02/33] lib/string_helpers: Convert string_escape_mem() to printbuf
Date: Thu, 9 Jun 2022 16:25:36 +0200	[thread overview]
Message-ID: <YqIC4AWW0bF7nOGu@alley> (raw)
In-Reply-To: <20220604193042.1674951-3-kent.overstreet@gmail.com>

On Sat 2022-06-04 15:30:11, Kent Overstreet wrote:
> Like the upcoming vsprintf.c conversion, this converts string_escape_mem
> to prt_escaped_string(), which uses and outputs to a printbuf, and makes
> string_escape_mem() a smaller wrapper to support existing users.
> 
> The new printbuf helpers greatly simplify the code.
> 
> --- a/lib/string_helpers.c
> +++ b/lib/string_helpers.c
> @@ -15,6 +15,7 @@
>  #include <linux/fs.h>
>  #include <linux/limits.h>
>  #include <linux/mm.h>
> +#include <linux/printbuf.h>
>  #include <linux/slab.h>
>  #include <linux/string.h>
>  #include <linux/string_helpers.h>
> @@ -301,19 +302,14 @@ int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
>  }
>  EXPORT_SYMBOL(string_unescape);
>  
> -static bool escape_passthrough(unsigned char c, char **dst, char *end)
> +static bool escape_passthrough(struct printbuf *out, unsigned char c)
>  {
> -	char *out = *dst;
> -
> -	if (out < end)
> -		*out = c;
> -	*dst = out + 1;
> +	prt_char(out, c);

This modifies the behavior. The original code did not add
the trailing '\0'.

I agree that the original behavior is ugly but it is documented
see the comment:

 * Return:
 * The total size of the escaped output that would be generated for
 * the given input and flags. To check whether the output was
 * truncated, compare the return value to osz. There is room left in
 * dst for a '\0' terminator if and only if ret < osz.
                             ^^^^^^^^^^^^^^


I am all for changing the behavior but it would require checking
all callers.

Anyway, adding the trailing '\0' all is not much effective.
I suggest to use __prt_char() and add the trailing '\0' when
the string is complete.

We must make sure that __prt_char() is able to add the last
character even when there will not longer be space for
the trailing '\0'.


>  	return true;
>  }
>  

[...]

>  
>  /**
> - * string_escape_mem - quote characters in the given memory buffer
> + * prt_escaped_string - quote characters in the given memory buffer
> + * @out:	printbuf to output to (escaped)
>   * @src:	source buffer (unescaped)
>   * @isz:	source buffer size
> - * @dst:	destination buffer (escaped)
> - * @osz:	destination buffer size
>   * @flags:	combination of the flags
>   * @only:	NULL-terminated string containing characters used to limit
>   *		the selected escape class. If characters are included in @only
> @@ -517,11 +466,10 @@ static bool escape_hex(unsigned char c, char **dst, char *end)
>   * truncated, compare the return value to osz. There is room left in
>   * dst for a '\0' terminator if and only if ret < osz.
>   */
> -int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
> -		      unsigned int flags, const char *only)
> +void prt_escaped_string(struct printbuf *out,
> +			const char *src, size_t isz,
> +			unsigned int flags, const char *only)
>  {
> -	char *p = dst;
> -	char *end = p + osz;
>  	bool is_dict = only && *only;
>  	bool is_append = flags & ESCAPE_APPEND;
>  
> @@ -549,41 +497,49 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
>  		 * %ESCAPE_NA cases.
>  		 */
>  		if (!(is_append || in_dict) && is_dict &&
> -					  escape_passthrough(c, &p, end))
> +		    escape_passthrough(out, c))
>  			continue;
>  
>  		if (!(is_append && in_dict) && isascii(c) && isprint(c) &&
> -		    flags & ESCAPE_NAP && escape_passthrough(c, &p, end))
> +		    flags & ESCAPE_NAP && escape_passthrough(out, c))
>  			continue;
>  
>  		if (!(is_append && in_dict) && isprint(c) &&
> -		    flags & ESCAPE_NP && escape_passthrough(c, &p, end))
> +		    flags & ESCAPE_NP && escape_passthrough(out, c))
>  			continue;
>  
>  		if (!(is_append && in_dict) && isascii(c) &&
> -		    flags & ESCAPE_NA && escape_passthrough(c, &p, end))
> +		    flags & ESCAPE_NA && escape_passthrough(out, c))
>  			continue;
>  
> -		if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
> +		if (flags & ESCAPE_SPACE && escape_space(out, c))
>  			continue;
>  
> -		if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
> +		if (flags & ESCAPE_SPECIAL && escape_special(out, c))
>  			continue;
>  
> -		if (flags & ESCAPE_NULL && escape_null(c, &p, end))
> +		if (flags & ESCAPE_NULL && escape_null(out, c))
>  			continue;
>  
>  		/* ESCAPE_OCTAL and ESCAPE_HEX always go last */
> -		if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
> +		if (flags & ESCAPE_OCTAL && escape_octal(out, c))
>  			continue;
>  
> -		if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
> +		if (flags & ESCAPE_HEX && escape_hex(out, c))
>  			continue;
>  
> -		escape_passthrough(c, &p, end);
> +		escape_passthrough(out, c);
>  	}
> +}
> +EXPORT_SYMBOL(prt_escaped_string);
> +
> +int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
> +		      unsigned int flags, const char *only)

We need keep the comment above this API as long as it is public.

Note that it uses the docbook comment format, starging with /** ...
And the symbol is exported.

It is even more important because of the crazy behavior where
it does not add the trailing '\0'.

> +{
> +	struct printbuf out = PRINTBUF_EXTERN(dst, osz);
>  
> -	return p - dst;
> +	prt_escaped_string(&out, src, isz, flags, only);
> +	return out.pos;
>  }
>  EXPORT_SYMBOL(string_escape_mem);

Note: If you decided to change/fix the behavior then please do so
      in a separate patch(set). I was able to catch the problem
      because the patch was straightforward and "easy" to review.

Best Regards,
Petr

  reply	other threads:[~2022-06-09 14:25 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-04 19:30 [PATCH v3 00/33] Printbufs Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 01/33] lib/printbuf: New data structure for printing strings Kent Overstreet
2022-06-09 13:55   ` Petr Mladek
2022-06-04 19:30 ` [PATCH v3 02/33] lib/string_helpers: Convert string_escape_mem() to printbuf Kent Overstreet
2022-06-09 14:25   ` Petr Mladek [this message]
2022-06-09 17:53     ` Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 03/33] vsprintf: Convert " Kent Overstreet
2022-06-15  9:09   ` Rasmus Villemoes
2022-06-15 18:44     ` Kent Overstreet
2022-06-17  8:59       ` Rasmus Villemoes
2022-06-04 19:30 ` [PATCH v3 04/33] lib/hexdump: " Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 05/33] vsprintf: %pf(%p) Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 06/33] lib/string_helpers: string_get_size() now returns characters wrote Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 07/33] lib/printbuf: Heap allocation Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 08/33] lib/printbuf: Tabstops, indenting Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 09/33] lib/printbuf: Unit specifiers Kent Overstreet
2022-06-05  1:06   ` Joe Perches
2022-06-04 19:30 ` [PATCH v3 10/33] lib/pretty-printers: prt_string_option(), prt_bitflags() Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 11/33] vsprintf: Improve number() Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 12/33] vsprintf: prt_u64_minwidth(), prt_u64() Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 13/33] test_printf: Drop requirement that sprintf not write past nul Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 14/33] vsprintf: Start consolidating printf_spec handling Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 15/33] vsprintf: Refactor resource_string() Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 16/33] vsprintf: Refactor fourcc_string() Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 17/33] vsprintf: Refactor ip_addr_string() Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 18/33] vsprintf: Refactor mac_address_string() Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 19/33] vsprintf: time_and_date() no longer takes printf_spec Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 20/33] vsprintf: flags_string() " Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 21/33] vsprintf: Refactor device_node_string, fwnode_string Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 22/33] vsprintf: Refactor hex_string, bitmap_string_list, bitmap_string Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 23/33] Input/joystick/analog: Convert from seq_buf -> printbuf Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 24/33] mm/memcontrol.c: Convert to printbuf Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 25/33] clk: tegra: bpmp: " Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 26/33] tools/testing/nvdimm: " Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 27/33] powerpc: " Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 28/33] x86/resctrl: " Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 29/33] PCI/P2PDMA: " Kent Overstreet
2022-06-08 21:11   ` Bjorn Helgaas
2022-06-08 23:24     ` Kent Overstreet
2022-06-08 23:34       ` Logan Gunthorpe
2022-06-08 23:40       ` Bjorn Helgaas
2022-06-04 19:30 ` [PATCH v3 30/33] tracing: trace_events_synth: " Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 31/33] d_path: prt_path() Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 32/33] tracing: Convert to printbuf Kent Overstreet
2022-06-04 19:30 ` [PATCH v3 33/33] Delete seq_buf Kent Overstreet
2022-06-05 16:21 ` [PATCH v3 00/33] Printbufs Steven Rostedt
2022-06-05 17:55   ` Kent Overstreet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YqIC4AWW0bF7nOGu@alley \
    --to=pmladek@suse.com \
    --cc=kent.overstreet@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox