Coverity reported some bugs in man-db which are in fact gnulib bugs. I'd
like to clear these up. This is the most obvious installment, mainly
representing real bugs; I still need to investigate several items which
are essentially false positives and see if it's worth adjusting code to
avoid tripping source code checkers.

2008-08-06  Colin Watson  <[EMAIL PROTECTED]>

        Merge some glibc changes into lib/argp-help.c.

        * lib/argp-help.c: Include <stdint.h> for uint8_t, required by
        changes below.

        2006-05-09  Ulrich Drepper  <[EMAIL PROTECTED]>

        * lib/argp-help.c (hol_entry_help): Handle STATE==NULL in ARG
        and DGETTEXT calls.
        (hol_help): Likewise.  [Coverity CID 226, 227]

        * lib/argp-help.c (hol_entry_cmp): Don't call canon_doc_option if
        string is NULL.  [Coverity CID 212]

        * lib/argp-help.c (fill_in_uparams): Handle STATE==NULL in
        dgettext calls. [Coverity CID 204]

        * lib/argp-help.c (uparam_names): Reduce size.  Avoid relative
        relocations.  Moved to read-only segment.
        (fill_in_uparams): Update for new layout.

        * lib/argp-help.c (hol_entry_help): Remove some dead code
        [Coverity CID 200].

        2007-03-15  Jakub Jelinek  <[EMAIL PROTECTED]>

        * lib/argp-help.c (filter_doc): Don't crash if argp is NULL.

Thanks,

-- 
Colin Watson                                       [EMAIL PROTECTED]
diff --git a/lib/argp-help.c b/lib/argp-help.c
index a9843c0..f9a6243 100644
--- a/lib/argp-help.c
+++ b/lib/argp-help.c
@@ -1,5 +1,6 @@
 /* Hierarchial argument parsing help output
-   Copyright (C) 1995-2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1995-2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <[EMAIL PROTECTED]>.
 
@@ -33,6 +34,7 @@
 #include <stdarg.h>
 #include <ctype.h>
 #include <limits.h>
+#include <stdint.h>
 #ifdef USE_IN_LIBIO
 # include <wchar.h>
 #endif
@@ -110,25 +112,25 @@ static struct uparams uparams = {
 /* A particular uparam, and what the user name is.  */
 struct uparam_name
 {
-  const char *name;		/* User name.  */
-  int is_bool;			/* Whether it's `boolean'.  */
-  size_t uparams_offs;		/* Location of the (int) field in UPARAMS.  */
+  const char name[14];		/* User name.  */
+  bool is_bool;			/* Whether it's `boolean'.  */
+  uint8_t uparams_offs;		/* Location of the (int) field in UPARAMS.  */
 };
 
 /* The name-field mappings we know about.  */
 static const struct uparam_name uparam_names[] =
 {
-  { "dup-args",       1, offsetof (struct uparams, dup_args) },
-  { "dup-args-note",  1, offsetof (struct uparams, dup_args_note) },
-  { "short-opt-col",  0, offsetof (struct uparams, short_opt_col) },
-  { "long-opt-col",   0, offsetof (struct uparams, long_opt_col) },
-  { "doc-opt-col",    0, offsetof (struct uparams, doc_opt_col) },
-  { "opt-doc-col",    0, offsetof (struct uparams, opt_doc_col) },
-  { "header-col",     0, offsetof (struct uparams, header_col) },
-  { "usage-indent",   0, offsetof (struct uparams, usage_indent) },
-  { "rmargin",        0, offsetof (struct uparams, rmargin) },
-  { 0 }
+  { "dup-args",       true, offsetof (struct uparams, dup_args) },
+  { "dup-args-note",  true, offsetof (struct uparams, dup_args_note) },
+  { "short-opt-col",  false, offsetof (struct uparams, short_opt_col) },
+  { "long-opt-col",   false, offsetof (struct uparams, long_opt_col) },
+  { "doc-opt-col",    false, offsetof (struct uparams, doc_opt_col) },
+  { "opt-doc-col",    false, offsetof (struct uparams, opt_doc_col) },
+  { "header-col",     false, offsetof (struct uparams, header_col) },
+  { "usage-indent",   false, offsetof (struct uparams, usage_indent) },
+  { "rmargin",        false, offsetof (struct uparams, rmargin) }
 };
+#define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
 
 static void
 validate_uparams (const struct argp_state *state, struct uparams *upptr)
@@ -143,7 +145,8 @@ validate_uparams (const struct argp_state *state, struct uparams *upptr)
       if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
 	{
 	  __argp_failure (state, 0, 0,
-			  dgettext (state->root_argp->argp_domain,
+			  dgettext (state == NULL ? NULL
+				    : state->root_argp->argp_domain,
 				    "\
 ARGP_HELP_FMT: %s value is less than or equal to %s"),
 			  "rmargin", up->name);
@@ -174,6 +177,7 @@ fill_in_uparams (const struct argp_state *state)
 	    {
 	      size_t var_len;
 	      const struct uparam_name *un;
+	      size_t u;
 	      int unspec = 0, val = 0;
 	      const char *arg = var;
 
@@ -210,19 +214,22 @@ fill_in_uparams (const struct argp_state *state)
 		  SKIPWS (arg);
 		}
 
-	      for (un = uparam_names; un->name; un++)
+	      un = uparam_names;
+	      for (u = 0; u < nuparam_names; ++un, ++u)
 		if (strlen (un->name) == var_len
 		    && strncmp (var, un->name, var_len) == 0)
 		  {
 		    if (unspec && !un->is_bool)
 		      __argp_failure (state, 0, 0,
-				      dgettext (state->root_argp->argp_domain,
+				      dgettext (state == NULL ? NULL
+						: state->root_argp->argp_domain,
 						"\
 %.*s: ARGP_HELP_FMT parameter requires a value"),
 				      (int) var_len, var);
 		    else if (val < 0)
 		      __argp_failure (state, 0, 0,
-				      dgettext (state->root_argp->argp_domain,
+				      dgettext (state == NULL ? NULL
+						: state->root_argp->argp_domain,
 						"\
 %.*s: ARGP_HELP_FMT parameter must be positive"),
 				      (int) var_len, var);
@@ -230,9 +237,10 @@ fill_in_uparams (const struct argp_state *state)
 		      *(int *)((char *)&new_params + un->uparams_offs) = val;
 		    break;
 		  }
-	      if (! un->name)
+	      if (u == nuparam_names)
 		__argp_failure (state, 0, 0,
-				dgettext (state->root_argp->argp_domain, "\
+				dgettext (state == NULL ? NULL
+					  : state->root_argp->argp_domain, "\
 %.*s: Unknown ARGP_HELP_FMT parameter"),
 				(int) var_len, var);
 
@@ -243,7 +251,8 @@ fill_in_uparams (const struct argp_state *state)
 	  else if (*var)
 	    {
 	      __argp_failure (state, 0, 0,
-			      dgettext (state->root_argp->argp_domain,
+			      dgettext (state == NULL ? NULL
+					: state->root_argp->argp_domain,
 					"Garbage in ARGP_HELP_FMT: %s"), var);
 	      break;
 	    }
@@ -778,9 +787,9 @@ hol_entry_cmp (const struct hol_entry *entry1,
       const char *long2 = hol_entry_first_long (entry2);
 
       if (doc1)
-	doc1 = canon_doc_option (&long1);
+	doc1 = long1 != NULL && canon_doc_option (&long1);
       if (doc2)
-	doc2 = canon_doc_option (&long2);
+	doc2 = long2 != NULL && canon_doc_option (&long2);
 
       if (doc1 != doc2)
 	/* `documentation' options always follow normal options (or
@@ -1011,7 +1020,7 @@ static const char *
 filter_doc (const char *doc, int key, const struct argp *argp,
 	    const struct argp_state *state)
 {
-  if (argp->help_filter)
+  if (argp && argp->help_filter)
     /* We must apply a user filter to this output.  */
     {
       void *input = __argp_input (argp, state);
@@ -1135,7 +1144,9 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
 	    __argp_fmtstream_putc (stream, '-');
 	    __argp_fmtstream_putc (stream, *so);
 	    if (!have_long_opt || uparams.dup_args)
-	      arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
+	      arg (real, " %s", "[%s]",
+		   state == NULL ? NULL : state->root_argp->argp_domain,
+		   stream);
 	    else if (real->arg)
 	      hhstate->suppressed_dup_arg = 1;
 	  }
@@ -1157,26 +1168,22 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
 	    __argp_fmtstream_puts (stream,
 				   onotrans (opt) ?
 				             opt->name :
-				   dgettext (state->root_argp->argp_domain,
+				   dgettext (state == NULL ? NULL
+					     : state->root_argp->argp_domain,
 					     opt->name));
 	  }
     }
   else
     /* A real long option.  */
     {
-      int first_long_opt = 1;
-
       __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
       for (opt = real, num = entry->num; num > 0; opt++, num--)
 	if (opt->name && ovisible (opt))
 	  {
 	    comma (uparams.long_opt_col, &pest);
 	    __argp_fmtstream_printf (stream, "--%s", opt->name);
-	    if (first_long_opt || uparams.dup_args)
-	      arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
-		   stream);
-	    else if (real->arg)
-	      hhstate->suppressed_dup_arg = 1;
+	    arg (real, "=%s", "[=%s]",
+		 state == NULL ? NULL : state->root_argp->argp_domain, stream);
 	  }
     }
 
@@ -1195,7 +1202,8 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
     }
   else
     {
-      const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
+      const char *tstr = real->doc ? dgettext (state == NULL ? NULL
+					       : state->root_argp->argp_domain,
 					       real->doc) : 0;
       const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
       if (fstr && *fstr)
@@ -1243,7 +1251,8 @@ hol_help (struct hol *hol, const struct argp_state *state,
 
   if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
     {
-      const char *tstr = dgettext (state->root_argp->argp_domain, "\
+      const char *tstr = dgettext (state == NULL ? NULL
+				   : state->root_argp->argp_domain, "\
 Mandatory or optional arguments to long options are also mandatory or \
 optional for any corresponding short options.");
       const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
@@ -1925,7 +1934,8 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
 #endif
 #if !_LIBC
 		  if (! s && ! (s = strerror (errnum)))
-		    s = dgettext (state->root_argp->argp_domain,
+		    s = dgettext (state == NULL ? NULL
+				  : state->root_argp->argp_domain,
 				  "Unknown system error");
 #endif
 		  fputs (s, stream);

Reply via email to