Re: argp --help infloop bug

2005-12-10 Thread Sergey Poznyakoff
Jim Meyering [EMAIL PROTECTED] wrote:

 You can make any argp-using program infloop simply by running it
 with --help and with something like ARGP_HELP_FMT=rmargin=a in the
 environment.  Or use a valid (but small) width: ARGP_HELP_FMT=rmargin=2

Fixed in gnulib repository. The following patch is applied (it also
fixes a coredump one would get in some cases, e.g. when running
ARGP_HELP_FMT=rmargin=39 tar --help).

Regards,
Sergey

2005-12-10  Sergey Poznyakoff  [EMAIL PROTECTED]

* lib/argp-fmtstream.c (__argp_fmtstream_update): Fix coredump
* lib/argp-help.c (fill_in_uparams): Check if the constructed
struct uparams is valid. Fall back to the default values if it is
not.
* m4/argp.m4: Define HAVE_DECL_PROGRAM_INVOCATION_NAME and
HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME

Index: lib/argp-fmtstream.c
===
RCS file: /cvsroot/gnulib/gnulib/lib/argp-fmtstream.c,v
retrieving revision 1.6
diff -p -u -r1.6 argp-fmtstream.c
--- lib/argp-fmtstream.c29 Sep 2005 12:24:42 -  1.6
+++ lib/argp-fmtstream.c10 Dec 2005 21:30:53 -
@@ -246,9 +246,10 @@ __argp_fmtstream_update (argp_fmtstream_
 Oh well.  Put it on an overlong line by itself.  */
  p = buf + (r + 1 - fs-point_col);
  /* Find the end of the long word.  */
- do
-   ++p;
- while (p  nl  !isblank (*p));
+ if (p  nl)
+   do
+ ++p;
+   while (p  nl  !isblank (*p));
  if (p == nl)
{
  /* It already ends a line.  No fussing required.  */
Index: lib/argp-help.c
===
RCS file: /cvsroot/gnulib/gnulib/lib/argp-help.c,v
retrieving revision 1.19
diff -p -u -r1.19 argp-help.c
--- lib/argp-help.c 9 Dec 2005 12:28:58 -   1.19
+++ lib/argp-help.c 10 Dec 2005 21:30:57 -
@@ -90,15 +90,15 @@ struct uparams
   int dup_args_note;
 
   /* Various output columns.  */
-  int short_opt_col;
-  int long_opt_col;
-  int doc_opt_col;
-  int opt_doc_col;
-  int header_col;
-  int usage_indent;
-  int rmargin;
+  int short_opt_col;  /* column in which short options start */   
+  int long_opt_col;   /* column in which long options start */ 
+  int doc_opt_col;/* column in which doc options start */
+  int opt_doc_col;/* column in which option text starts */
+  int header_col; /* column in which group headers are printed */ 
+  int usage_indent;   /* indentation of wrapped usage lines */
+  int rmargin;/* right margin used for wrapping */
 
-  int valid;   /* True when the values in here are valid.  */
+  int valid; /* True when the values in here are valid.  */
 };
 
 /* This is a global variable, as user options are only ever read once.  */
@@ -132,91 +132,126 @@ static const struct uparam_name uparam_n
   { 0 }
 };
 
-/* Read user options from the environment, and fill in UPARAMS appropiately.  
*/
+static void
+validate_uparams (const struct argp_state *state, struct uparams *upptr)
+{
+  const struct uparam_name *up;
+
+  for (up = uparam_names; up-name; up++)
+{
+  if (up-is_bool
+ || up-uparams_offs == offsetof (struct uparams, rmargin))
+   continue;
+  if (*(int *)((char *)upptr + up-uparams_offs) = upptr-rmargin)
+   {
+ __argp_failure (state, 0, 0,
+ dgettext (state-root_argp-argp_domain,
+   \
+ARGP_HELP_FMT: %s value is less then or equal to %s),
+ rmargin, up-name);
+ return;
+   }
+}
+  uparams = *upptr;
+  uparams.valid = 1;
+}
+
+/* Read user options from the environment, and fill in UPARAMS appropiately. */
 static void
 fill_in_uparams (const struct argp_state *state)
 {
   const char *var = getenv (ARGP_HELP_FMT);
-
+  struct uparams new_params = uparams;
+  
 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
 
   if (var)
-/* Parse var. */
-while (*var)
-  {
-   SKIPWS (var);
-
-   if (isalpha (*var))
- {
-   size_t var_len;
-   const struct uparam_name *un;
-   int unspec = 0, val = 0;
-   const char *arg = var;
-
-   while (isalnum (*arg) || *arg == '-' || *arg == '_')
- arg++;
-   var_len = arg - var;
-
-   SKIPWS (arg);
-
-   if (*arg == '\0' || *arg == ',')
- unspec = 1;
-   else if (*arg == '=')
- {
-   arg++;
-   SKIPWS (arg);
- }
+{
+  /* Parse var. */
+  while (*var)
+   {
+ SKIPWS (var);
+ 
+ if (isalpha (*var))
+   {
+ size_t var_len;
+ const struct uparam_name *un;
+ int unspec = 0, val = 0;
+ 

Re: argp --help infloop bug

2005-12-09 Thread Sergey Poznyakoff
Jim Meyering [EMAIL PROTECTED] wrote:

 You can make any argp-using program infloop simply by running it
 with --help and with something like ARGP_HELP_FMT=rmargin=a in the
 environment.  Or use a valid (but small) width: ARGP_HELP_FMT=rmargin=2

Yes, indeed. Thanks for reporting. I will fix it.

Regards,
Sergey


___
bug-gnulib mailing list
bug-gnulib@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-gnulib


Re: argp --help infloop bug

2005-12-09 Thread Jim Meyering
Sergey Poznyakoff [EMAIL PROTECTED] wrote:
 Jim Meyering [EMAIL PROTECTED] wrote:

 You can make any argp-using program infloop simply by running it
 with --help and with something like ARGP_HELP_FMT=rmargin=a in the
 environment.  Or use a valid (but small) width: ARGP_HELP_FMT=rmargin=2

 Yes, indeed. Thanks for reporting. I will fix it.

FYI, I've also filed it against glibc:

  http://sourceware.org/bugzilla/show_bug.cgi?id=2016


___
bug-gnulib mailing list
bug-gnulib@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-gnulib