From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Trond Myklebust <trond.myklebust@primarydata.com>,
"J. Bruce Fields" <bfields@fieldses.org>,
"David S. Miller" <davem@davemloft.net>,
linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org,
netdev@vger.kernel.org
Subject: Re: [PATCH v2 3/3] lib/string_helpers.c: Change semantics of string_escape_mem
Date: Thu, 29 Jan 2015 15:29:21 +0100 [thread overview]
Message-ID: <87oaphbqym.fsf@rasmusvillemoes.dk> (raw)
In-Reply-To: <1422538178.31903.325.camel@linux.intel.com> (Andy Shevchenko's message of "Thu, 29 Jan 2015 15:29:38 +0200")
On Thu, Jan 29 2015, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>> *
>> * Return:
>> - * The amount of the characters processed to the destination buffer, or
>> - * %-ENOMEM if the size of buffer is not enough to put an escaped character is
>> - * returned.
>> - *
>> - * Even in the case of error @dst pointer will be updated to point to the byte
>> - * after the last processed character.
>> + * 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.
>> */
>> -int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz,
>> - unsigned int flags, const char *esc)
>> +size_t string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
>> + unsigned int flags, const char *esc)
>
> I prefer to leave the prototype the same. int for return is okay. dst
> should be updated accordingly.
Please explain exactly what you think the return value should be, and
what *dst should be set to.
>> {
>> - char *p = *dst;
>> + char *p = dst;
>> char *end = p + osz;
>> bool is_dict = esc && *esc;
>> - int ret;
>>
>> while (isz--) {
>> unsigned char c = *src++;
>> @@ -466,13 +463,7 @@ int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz,
>>
>> escape_passthrough(c, &p, end);
>> }
>> - if (p > end) {
>> - *dst = end;
>> - return -ENOMEM;
>> - }
>>
>> - ret = p - *dst;
>> - *dst = p;
>> - return ret;
>> + return p - dst;
>> }
>> EXPORT_SYMBOL(string_escape_mem);
>> diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c
>> index ab0d30e1e18f..5f95114a2f86 100644
>> --- a/lib/test-string_helpers.c
>> +++ b/lib/test-string_helpers.c
>> @@ -264,12 +264,12 @@ static __init void test_string_escape(const char *name,
>> const struct test_string_2 *s2,
>> unsigned int flags, const char *esc)
>> {
>> - int q_real = 512;
>> - char *out_test = kmalloc(q_real, GFP_KERNEL);
>> - char *out_real = kmalloc(q_real, GFP_KERNEL);
>> + size_t out_size = 512;
>> + char *out_test = kmalloc(out_size, GFP_KERNEL);
>> + char *out_real = kmalloc(out_size, GFP_KERNEL);
>> char *in = kmalloc(256, GFP_KERNEL);
>> - char *buf = out_real;
>> - int p = 0, q_test = 0;
>> + size_t p = 0, q_test = 0;
>> + size_t q_real;
>>
>> if (!out_test || !out_real || !in)
>> goto out;
>> @@ -301,29 +301,26 @@ static __init void test_string_escape(const char *name,
>> q_test += len;
>> }
>>
>> - q_real = string_escape_mem(in, p, &buf, q_real, flags, esc);
>> + q_real = string_escape_mem(in, p, out_real, out_size, flags, esc);
>>
>> test_string_check_buf(name, flags, in, p, out_real, q_real, out_test,
>> q_test);
>> +
>> + memset(out_real, 'Z', out_size);
>> + q_real = string_escape_mem(in, p, out_real, 0, flags, esc);
>> + if (q_real != q_test)
>> + pr_warn("Test '%s' failed: flags = %u, osz = 0, expected %zu, got %zu\n",
>> + name, flags, q_test, q_real);
>> + if (memchr_inv(out_real, 'Z', out_size))
>> + pr_warn("Test '%s' failed: osz = 0 but string_escape_mem wrote to the buffer\n",
>> + name);
>
> Could it be a part of nomem test still?
What nomem test? string_escape_mem with snprintf-like semantics cannot
return an error; that has to be checked by the caller.
>> +
>> out:
>> kfree(in);
>> kfree(out_real);
>> kfree(out_test);
>> }
>>
>> -static __init void test_string_escape_nomem(void)
>> -{
>> - char *in = "\eb \\C\007\"\x90\r]";
>> - char out[64], *buf = out;
>> - int rc = -ENOMEM, ret;
>> -
>> - ret = string_escape_str_any_np(in, &buf, strlen(in), NULL);
>> - if (ret == rc)
>> - return;
>> -
>> - pr_err("Test 'escape nomem' failed: got %d instead of %d\n", ret, rc);
>> -}
>> -
>> static int __init test_string_helpers_init(void)
>> {
>> unsigned int i;
>> @@ -342,8 +339,6 @@ static int __init test_string_helpers_init(void)
>> for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++)
>> test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1);
>>
>> - test_string_escape_nomem();
>> -
>> return -EINVAL;
>> }
>> module_init(test_string_helpers_init);
>> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
>> index 3568e3906777..d02c394b5b58 100644
>> --- a/lib/vsprintf.c
>> +++ b/lib/vsprintf.c
>> @@ -1160,7 +1160,7 @@ char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
>> 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);
>> + buf += string_escape_mem(addr, len, buf, buf < end ? end - buf : 0, flags, NULL);
>
> So, the problem is when we have end < buf, right?
> How about to move this check out of the call parameters?
>
> [Keep in might the original prototype]
>
> if (buf < end)
> string_escape_mem(addr, len, &buf, end - buf, flags, NULL);
> else
> string_escape_mem(addr, len, &buf, 0, flags, NULL);
In that case, I just did the same as is done for %pV, and prefer to keep
it that way.
>> diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
>> index 33fb105d4352..22c4418057f4 100644
>> --- a/net/sunrpc/cache.c
>> +++ b/net/sunrpc/cache.c
>> @@ -1068,12 +1068,14 @@ void qword_add(char **bpp, int *lp, char *str)
>> {
>> char *bp = *bpp;
>> int len = *lp;
>> - int ret;
>> + int ret, written;
>>
>> if (len < 0) return;
>>
>> - ret = string_escape_str(str, &bp, len, ESCAPE_OCTAL, "\\ \n\t");
>> - if (ret < 0 || ret == len)
>> + ret = string_escape_str(str, bp, len, ESCAPE_OCTAL, "\\ \n\t");
>> + written = min(ret, len);
>> + bp += written;
>> + if (ret >= len)
>> len = -1;
>> else {
>> len -= ret;
>
> For this part the comment from J. Bruce is needed.
>
> There is one more user, i.e. fs/proc/array.c::task_name().
>
> In all of them we have to amend a prepend commentary. Like changing
> 'Ignore the error' to 'Ignore the overflow'.
I hadn't looked for users in -next. I'll leave it to you to amend that
patch before it hits mainline.
Rasmus
next prev parent reply other threads:[~2015-01-29 14:29 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-28 13:25 [PATCH 0/2] Two printf fixes Rasmus Villemoes
2015-01-28 13:25 ` [PATCH 2/2] string_helpers: Change semantics of string_escape_mem Rasmus Villemoes
2015-01-28 15:05 ` Andy Shevchenko
2015-01-29 10:03 ` [PATCH v2 0/3] Two printf fixes Rasmus Villemoes
2015-01-29 10:03 ` [PATCH v2 3/3] lib/string_helpers.c: Change semantics of string_escape_mem Rasmus Villemoes
2015-01-29 13:29 ` Andy Shevchenko
2015-01-29 14:29 ` Rasmus Villemoes [this message]
2015-01-30 10:27 ` Andy Shevchenko
[not found] ` <1422613655.31903.351.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-01-30 23:39 ` Rasmus Villemoes
2015-02-02 10:56 ` Andy Shevchenko
[not found] ` <1422525801-26560-1-git-send-email-linux-qQsb+v5E8BnlAoU/VqSP6n9LOBIZ5rWg@public.gmane.org>
2015-02-09 23:44 ` [PATCH v3 0/3] Two printf fixes Rasmus Villemoes
[not found] ` <1423525491-12613-1-git-send-email-linux-qQsb+v5E8BnlAoU/VqSP6n9LOBIZ5rWg@public.gmane.org>
2015-02-09 23:44 ` [PATCH v3 3/3] lib/string_helpers.c: Change semantics of string_escape_mem Rasmus Villemoes
[not found] ` <1423525491-12613-4-git-send-email-linux-qQsb+v5E8BnlAoU/VqSP6n9LOBIZ5rWg@public.gmane.org>
2015-02-10 12:32 ` Andy Shevchenko
2015-02-10 13:02 ` Rasmus Villemoes
[not found] ` <87386dj4x0.fsf-qQsb+v5E8BnlAoU/VqSP6n9LOBIZ5rWg@public.gmane.org>
2015-02-10 14:22 ` Andy Shevchenko
2015-02-21 1:35 ` Rasmus Villemoes
[not found] ` <87oaoo59n2.fsf-qQsb+v5E8BnlAoU/VqSP6n9LOBIZ5rWg@public.gmane.org>
2015-02-23 12:50 ` Andy Shevchenko
[not found] ` <1424695820.14897.10.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-02-23 22:55 ` Rasmus Villemoes
[not found] ` <87k2z86xvs.fsf-qQsb+v5E8BnlAoU/VqSP6n9LOBIZ5rWg@public.gmane.org>
2015-03-02 12:37 ` Andy Shevchenko
2015-03-02 23:03 ` Rasmus Villemoes
[not found] ` <87a8zvovcj.fsf-qQsb+v5E8BnlAoU/VqSP6n9LOBIZ5rWg@public.gmane.org>
2015-03-03 10:26 ` Andy Shevchenko
2015-03-03 23:20 ` [PATCH v4 0/3] Two printf fixes Rasmus Villemoes
2015-03-03 23:20 ` [PATCH v4 3/3] lib/string_helpers.c: Change semantics of string_escape_mem Rasmus Villemoes
[not found] ` <1425424836-17947-4-git-send-email-linux-qQsb+v5E8BnlAoU/VqSP6n9LOBIZ5rWg@public.gmane.org>
2015-03-04 11:49 ` Andy Shevchenko
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=87oaphbqym.fsf@rasmusvillemoes.dk \
--to=linux@rasmusvillemoes.dk \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bfields@fieldses.org \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=trond.myklebust@primarydata.com \
/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;
as well as URLs for NNTP newsgroup(s).