Message ID | 1404746512-12749-5-git-send-email-andriy.shevchenko@linux.intel.com (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
[trivial notes] On Mon, 2014-07-07 at 18:21 +0300, Andy Shevchenko wrote: > This allows user to print a given buffer as esaped string. The rules applied as an escaped > accordingly to the mix of the flags provided by additional format letters. rules are applied according to an optional mix of flags > For example, if the given buffer: > > 1b 62 20 5c 43 07 22 90 0d 5d > > The result strings could be: would be > %*pE "\eb \C\a"\220\r]" Maybe say something about ssid's here. or maybe add an %*pES just for the ssid type. > diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt [] > @@ -70,6 +70,34 @@ DMA addresses types dma_addr_t: > For printing a dma_addr_t type which can vary based on build options, > regardless of the width of the CPU data path. Passed by reference. > > +Raw buffer as an escaped string: > + > + %*pE[achnops] > + > + For printing raw buffer as an escaped string. For the following buffer > + > + 1b 62 20 5c 43 07 22 90 0d 5d > + > + few examples show how the conversion could be done (the result string > + without embraced quotes): 'embraced' is a bit of an awkward word choice. Maybe surrounding. > + > + %*pE "\eb \C\a"\220\r]" Oh, the initial commit log comments above are really for this block > + %*pEhp "\x1bb \C\x07"\x90\x0d]" > + %*pEa "\e\142\040\\\103\a\042\220\r\135" > + > + The converion rules are defined by combination of the following flags conversion > + (see string_escape_mem() kernel documentation for the details): > + a - ESCAPE_ANY > + c - ESCAPE_SPECIAL > + h - ESCAPE_HEX > + n - ESCAPE_NULL > + o - ESCAPE_OCTAL > + p - ESCAPE_NP > + s - ESCAPE_SPACE > + By default ESCAPE_ANY_NP is used. > + > + If field width is ommited the 1 byte only will be escaped. omitted -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 2014-07-07 at 18:21 +0300, Andy Shevchenko wrote: > diff --git a/lib/vsprintf.c b/lib/vsprintf.c [] > static noinline_for_stack > +char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec, > + const char *fmt) [] > + if (spec.field_width == 0) > + /* nothing to print */ > + return buf; [] > + len = spec.field_width < 0 ? 1 : spec.field_width; If field_width is not specified, emit a single byte? Perhaps better if -1 was accepted by string_escape_mem as a strlen request or just ignored as a 0 length is above. fyi: hex_string emits nothing on printk("%ph", buf); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 2014-07-07 at 09:50 -0700, Joe Perches wrote: > On Mon, 2014-07-07 at 18:21 +0300, Andy Shevchenko wrote: > > > diff --git a/lib/vsprintf.c b/lib/vsprintf.c > [] > > static noinline_for_stack > > +char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec, > > + const char *fmt) > [] > > + if (spec.field_width == 0) > > + /* nothing to print */ > > + return buf; > [] > > + len = spec.field_width < 0 ? 1 : spec.field_width; > > If field_width is not specified, emit a single byte? A single byte to be escaped (it might be \000, for example, on output). > Perhaps better if -1 was accepted by string_escape_mem > as a strlen request or just ignored as a 0 length is > above. Would it be any benefit here? > fyi: hex_string emits nothing on printk("%ph", buf); Works just fine. How did you check it? pr_info("%ph\n", in); => test_string_helpers: 1b (I suppose "\n" flushes a buffer for me.)
On Mon, 2014-07-07 at 09:25 -0700, Joe Perches wrote: > [trivial notes] Thanks! Fixed locally, though am waiting for few more days if any other comment comes. > > On Mon, 2014-07-07 at 18:21 +0300, Andy Shevchenko wrote: > > This allows user to print a given buffer as esaped string. The rules applied > > as an escaped > > > accordingly to the mix of the flags provided by additional format letters. > > rules are applied according to an optional mix of flags > > > For example, if the given buffer: > > > > 1b 62 20 5c 43 07 22 90 0d 5d > > > > The result strings could be: > > would be > > > %*pE "\eb \C\a"\220\r]" > > Maybe say something about ssid's here. Mentioned in the printk-formats.txt part. > or maybe add an %*pES just for the ssid type. I gave a thought to it, and it seems to me we will increase complexity of the code to get none beneficial. The SSID in most cases has a variable-length, thus we will pass it anyway, what else could be differ here? Default set of flags? > > > diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt > [] > > @@ -70,6 +70,34 @@ DMA addresses types dma_addr_t: > > For printing a dma_addr_t type which can vary based on build options, > > regardless of the width of the CPU data path. Passed by reference. > > > > +Raw buffer as an escaped string: > > + > > + %*pE[achnops] > > + > > + For printing raw buffer as an escaped string. For the following buffer > > + > > + 1b 62 20 5c 43 07 22 90 0d 5d > > + > > + few examples show how the conversion could be done (the result string > > + without embraced quotes): > > 'embraced' is a bit of an awkward word choice. Maybe surrounding. > > > + > > + %*pE "\eb \C\a"\220\r]" > > Oh, the initial commit log comments above are really for this block Phrasing is a bit different, though I rephrased above sentence. > > > + %*pEhp "\x1bb \C\x07"\x90\x0d]" > > + %*pEa "\e\142\040\\\103\a\042\220\r\135" > > + > > + The converion rules are defined by combination of the following flags > > conversion > > > + (see string_escape_mem() kernel documentation for the details): > > + a - ESCAPE_ANY > > + c - ESCAPE_SPECIAL > > + h - ESCAPE_HEX > > + n - ESCAPE_NULL > > + o - ESCAPE_OCTAL > > + p - ESCAPE_NP > > + s - ESCAPE_SPACE > > + By default ESCAPE_ANY_NP is used. > > + > > + If field width is ommited the 1 byte only will be escaped. > > omitted > >
On Tue, 2014-07-08 at 11:24 +0300, Andy Shevchenko wrote: > On Mon, 2014-07-07 at 09:50 -0700, Joe Perches wrote: > > Perhaps better if -1 was accepted by string_escape_mem > > as a strlen request or just ignored as a 0 length is > > above. > > Would it be any benefit here? Dunno, it was just a thought for you. > > fyi: hex_string emits nothing on printk("%ph", buf); > > Works just fine. How did you check it? By not reading the code correctly. So what you have is fine. -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 3b56a99..e2dc566 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -70,6 +70,34 @@ DMA addresses types dma_addr_t: For printing a dma_addr_t type which can vary based on build options, regardless of the width of the CPU data path. Passed by reference. +Raw buffer as an escaped string: + + %*pE[achnops] + + For printing raw buffer as an escaped string. For the following buffer + + 1b 62 20 5c 43 07 22 90 0d 5d + + few examples show how the conversion could be done (the result string + without embraced quotes): + + %*pE "\eb \C\a"\220\r]" + %*pEhp "\x1bb \C\x07"\x90\x0d]" + %*pEa "\e\142\040\\\103\a\042\220\r\135" + + The converion rules are defined by combination of the following flags + (see string_escape_mem() kernel documentation for the details): + a - ESCAPE_ANY + c - ESCAPE_SPECIAL + h - ESCAPE_HEX + n - ESCAPE_NULL + o - ESCAPE_OCTAL + p - ESCAPE_NP + s - ESCAPE_SPACE + By default ESCAPE_ANY_NP is used. + + If field width is ommited the 1 byte only will be escaped. + Raw buffer as a hex string: %*ph 00 01 02 ... 3f %*phC 00:01:02: ... :3f diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 0eced40..6913046 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -33,6 +33,7 @@ #include <asm/page.h> /* for PAGE_SIZE */ #include <asm/sections.h> /* for dereference_function_descriptor() */ +#include <linux/string_helpers.h> #include "kstrtox.h" /** @@ -1101,6 +1102,63 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, } static noinline_for_stack +char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec, + const char *fmt) +{ + bool found = true; + int count = 1; + unsigned int flags = 0; + int len; + + if (spec.field_width == 0) + /* nothing to print */ + return buf; + + if (ZERO_OR_NULL_PTR(addr)) + /* NULL pointer */ + return string(buf, end, NULL, spec); + + do { + switch (fmt[count++]) { + case 'a': + flags |= ESCAPE_ANY; + break; + case 'c': + flags |= ESCAPE_SPECIAL; + break; + case 'h': + flags |= ESCAPE_HEX; + break; + case 'n': + flags |= ESCAPE_NULL; + break; + case 'o': + flags |= ESCAPE_OCTAL; + break; + case 'p': + flags |= ESCAPE_NP; + break; + case 's': + flags |= ESCAPE_SPACE; + break; + default: + found = false; + break; + } + } while (found); + + if (!flags) + flags = ESCAPE_ANY_NP; + + len = spec.field_width < 0 ? 1 : spec.field_width; + + /* Ignore the error. We print as many characters as we can */ + string_escape_mem(addr, len, &buf, end - buf, flags, NULL); + + return buf; +} + +static noinline_for_stack char *uuid_string(char *buf, char *end, const u8 *addr, struct printf_spec spec, const char *fmt) { @@ -1236,6 +1294,17 @@ int kptr_restrict __read_mostly; * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order * - 'I[6S]c' for IPv6 addresses printed as specified by * http://tools.ietf.org/html/rfc5952 + * - 'E[achnops]' For an escaped buffer, where rules are defined by combination + * of the following flags (see string_escape_mem() for the + * details): + * a - ESCAPE_ANY + * c - ESCAPE_SPECIAL + * h - ESCAPE_HEX + * n - ESCAPE_NULL + * o - ESCAPE_OCTAL + * p - ESCAPE_NP + * s - ESCAPE_SPACE + * By default ESCAPE_ANY_NP is used. * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" * Options for %pU are: @@ -1337,6 +1406,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, }} } break; + case 'E': + return escaped_string(buf, end, ptr, spec, fmt); case 'U': return uuid_string(buf, end, ptr, spec, fmt); case 'V': @@ -1651,6 +1722,7 @@ qualifier: * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper * case. + * %*pE[achnops] print an escaped buffer * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 * bytes of the input) * %n is ignored
This allows user to print a given buffer as esaped string. The rules applied accordingly to the mix of the flags provided by additional format letters. For example, if the given buffer: 1b 62 20 5c 43 07 22 90 0d 5d The result strings could be: %*pE "\eb \C\a"\220\r]" %*pEhp "\x1bb \C\x07"\x90\x0d]" %*pEa "\e\142\040\\\103\a\042\220\r\135" Please, read Documentation/printk-formats.txt and lib/string_helpers.c kernel documentation to get further information. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Suggested-by: Joe Perches <joe@perches.com> --- Documentation/printk-formats.txt | 28 ++++++++++++++++ lib/vsprintf.c | 72 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+)