On 30/11/14 14:38, Andrei Borzenkov wrote:
> Every po file seems to include entry with empty msgid with some
> meta information about it. If argp->doc string contains empty pre section
> (like "\v" "Some text to output after options"), argp_help tries to
> translate empty string and emits this meta information, like in
> 
> bor@opensuse:~/src/grub> grub2-mknetdir --help
> Использование: grub2-mknetdir [ПАРАМЕТР…]
> Project-Id-Version: grub 2.02-pre2
> Report-Msgid-Bugs-To: bug-g...@gnu.org
> POT-Creation-Date: 2013-12-24 21:18+0100
> PO-Revision-Date: 2013-12-31 10:57+0400
> ...
> 
> Check that pre doc string is empty before translating it.
> 
> This is less of a problem with post doc which simply can omit "\v"
> entirely, but there is no other way to skip pre doc, except explicitly
> using help_filter (which is redundant in this case).
> 
> Signed-off-by: Andrei Borzenkov <arvidj...@gmail.com>
> 
> ---
>  lib/argp-help.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/lib/argp-help.c b/lib/argp-help.c
> index 9044e1b..e470cec 100644
> --- a/lib/argp-help.c
> +++ b/lib/argp-help.c
> @@ -1510,7 +1510,7 @@ argp_doc (const struct argp *argp, const struct 
> argp_state *state,
>            else
>              {
>                inp_text_len = vt - argp->doc;
> -              inp_text = __strndup (argp->doc, inp_text_len);
> +              inp_text = inp_text_len ? __strndup (argp->doc, inp_text_len) 
> : 0;
>              }
>          }
>        else
> 

Yes the empty string is reserved to output the po header,
which you can see with this for example:

  $ LC_MESSAGES=fr_FR.utf8 gettext coreutils ''

I see the gnulib code diverged from the glibc code in this regard
since the support for the "\v" separator was added in:
http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=commit;h=1c54588f7

Therefore the fix looks good, though I see you don't handle the post case,
as that's not needed as it's the same behavior as not specifying "\v" at all.
But since this is a runtime gotcha it's probably safer to ignore a trailing 
"\v" too.

I'll apply the attached if you're OK with it.

thanks!
Pádraig.
From a545b5e44bff6e3dca75bc223a8edd885fc964f8 Mon Sep 17 00:00:00 2001
From: Andrei Borzenkov <arvidj...@gmail.com>
Date: Tue, 2 Dec 2014 16:05:10 +0000
Subject: [PATCH] argp: avoid extraneous translation and mem leak with empty
 pre doc

* lib/argp-help.c (argp_doc): Never translate the empty string,
when "\v" is the first or last character of the string, as that
has a reserved meaning to return the header info from a po file.
This also fixes a small memory leak in the !post case.
The issue can be seen with this command for example:
LC_MESSAGES=en_US grub2-mknetdir --help
---
 ChangeLog       | 10 ++++++++++
 lib/argp-help.c |  8 ++++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2dd5516..d7911af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-12-02  Andrei Borzenkov  <arvidj...@gmail.com>
+
+	argp: avoid extraneous translation and mem leak with empty pre doc
+	* lib/argp-help.c (argp_doc): Never translate the empty string,
+	when "\v" is the first or last character of the string, as that
+	has a reserved meaning to return the header info from a po file.
+	This also fixes a small memory leak in the !post case.
+	The issue can be seen with this command for example:
+	LC_MESSAGES=en_US grub2-mknetdir --help
+
 2014-11-27  Daiki Ueno  <u...@gnu.org>
 
 	uniname/uniname-tests: skip if system's libunistring is used
diff --git a/lib/argp-help.c b/lib/argp-help.c
index 9044e1b..f15138b 100644
--- a/lib/argp-help.c
+++ b/lib/argp-help.c
@@ -1506,11 +1506,15 @@ argp_doc (const struct argp *argp, const struct argp_state *state,
       if (vt)
         {
           if (post)
-            inp_text = vt + 1;
+            {
+              inp_text = vt + 1;
+              if (! *inp_text)
+                inp_text = 0;
+            }
           else
             {
               inp_text_len = vt - argp->doc;
-              inp_text = __strndup (argp->doc, inp_text_len);
+              inp_text = inp_text_len ? __strndup (argp->doc, inp_text_len) : 0;
             }
         }
       else
-- 
2.1.0

Reply via email to