From e7c8359e431ef305fbc61e4b86af6353b4f39879 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 10 May 2006 00:03:41 +0000 Subject: * posix/wordexp.c (w_addword): Free word if realloc fails and it was allocated here. [Coverity CID 219] * posix/getconf.c (print_all): Free confstr data after printing. [Coverity CID 218] * sysdeps/posix/getaddrinfo.c (gaih_inet): Free canon string if list allocation fails. [Coverity CID 215] * nss/nsswitch.c (__nss_configure_lookup): Fix loop end condition. [Coverity CID 213] * argp/argp-help.c (hol_entry_cmp): Don't call canon_doc_option if string is NULL. [Coverity CID 212] * argp/Makefile: Add rules to build and run bug-argp1. * argp/bug-argp1.c: New file. * io/ftw.c (ftw_dir): Use __rawmemchr instead of strchr to find end of string. * stdlib/canonicalize.c (__realpath): Likewise. * locale/programs/ld-time.c (time_finish): Don't dereference NULL pointer. [Coverity CID 206] * elf/dl-dst.h (DL_DST_REQUIRED): Be prepared for missing link map in statically linked code. * elf/dl-load.c (_dl_dst_substitute): When replacing ORIGIN in statically built code, be prepared to have no link map. [Coverity CID 205] * argp/argp-help.c (fill_in_uparams): Handle STATE==NULL in dgettext calls. [Coverity CID 204] * argp/argp-help.c (struct uparams): Remove valid member. Change the one user. (uparam_names): Reduce size. Avoid relative relocations. Moved to read-only segment. (fill_in_uparams): Update for new layout. * sysdeps/unix/sysv/linux/ifaddrs.c (getifaddrs): Parameter can be assumed to always be != NULL. [Coverity CID 202] * argp/argp-help.c (hol_entry_help): Remove some dead code [Coverity CID 200]. * nis/nss_nis/nis-service.c (_nss_nis_getservbyport_r): Optimize away a few more unconditional yperr2nss calls. (_nss_nis_getservbyname_r): Likewise. --- argp/Makefile | 6 ++++-- argp/argp-help.c | 64 ++++++++++++++++++++++++++------------------------------ argp/bug-argp1.c | 26 +++++++++++++++++++++++ 3 files changed, 60 insertions(+), 36 deletions(-) create mode 100644 argp/bug-argp1.c (limited to 'argp') diff --git a/argp/Makefile b/argp/Makefile index a68ca1bee3..5ade517476 100644 --- a/argp/Makefile +++ b/argp/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1997, 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 1997, 2002, 2003, 2006 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -26,10 +26,12 @@ distribute = argp-fmtstream.h argp-namefrob.h routines = $(addprefix argp-, ba fmtstream fs-xinl help parse pv \ pvh xinl eexst) -tests = argp-test tst-argp1 +tests = argp-test tst-argp1 bug-argp1 CFLAGS-argp-help.c = $(uses-callbacks) -fexceptions CFLAGS-argp-parse.c = $(uses-callbacks) CFLAGS-argp-fmtstream.c = -fexceptions +bug-argp1-ARGS = -- --help + include ../Rules diff --git a/argp/argp-help.c b/argp/argp-help.c index 4bc4d07b15..7ba621b735 100644 --- a/argp/argp-help.c +++ b/argp/argp-help.c @@ -1,5 +1,5 @@ /* Hierarchial argument parsing help output - Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . @@ -128,40 +128,37 @@ struct uparams int header_col; int usage_indent; int rmargin; - - int valid; /* True when the values in here are valid. */ }; /* This is a global variable, as user options are only ever read once. */ static struct uparams uparams = { DUP_ARGS, DUP_ARGS_NOTE, SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL, - USAGE_INDENT, RMARGIN, - 0 + USAGE_INDENT, RMARGIN }; /* 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])) /* Read user options from the environment, and fill in UPARAMS appropiately. */ static void @@ -217,22 +214,27 @@ fill_in_uparams (const struct argp_state *state) SKIPWS (arg); } - for (un = uparam_names; un->name; un++) + un = uparam_names; + size_t u; + 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 *(int *)((char *)&uparams + 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 +245,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; } @@ -759,9 +762,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 @@ -1129,19 +1132,13 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state, 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->root_argp->argp_domain, stream); } } @@ -1555,8 +1552,7 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream, __flockfile (stream); #endif - if (! uparams.valid) - fill_in_uparams (state); + fill_in_uparams (state); fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0); if (! fs) diff --git a/argp/bug-argp1.c b/argp/bug-argp1.c new file mode 100644 index 0000000000..a28cf4b9c7 --- /dev/null +++ b/argp/bug-argp1.c @@ -0,0 +1,26 @@ +#include + + +static const struct argp_option test_options[] = +{ + { NULL, 'a', NULL, OPTION_DOC, NULL }, + { NULL, 'b', NULL, OPTION_DOC, NULL }, + { NULL, 0, NULL, 0, NULL } +}; + +static struct argp test_argp = +{ + test_options +}; + + +static int +do_test (int argc, char *argv[]) +{ + int i; + argp_parse (&test_argp, argc, argv, 0, &i, NULL); + return 0; +} + +#define TEST_FUNCTION do_test (argc, argv) +#include "../test-skeleton.c" -- cgit 1.4.1