[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Check malloc result in getopt_long
From: |
Tobias Stoeckmann |
Subject: |
[PATCH] Check malloc result in getopt_long |
Date: |
Mon, 16 Feb 2015 21:06:22 +0100 |
In contrast to glibc's getopt implementation, this one uses malloc instead
of alloca. While in general this is a good idea, malloc returns NULL in
case of error, therefore the return value should be checked.
The fprintf statements are copied from the same source file; I am rather
indifferent about the error message.
Using coreutils' ls (I verified that gnulib's getopt is used on my system):
tobias:~/git/coreutils$ ulimit -Sv 4226
tobias:~/git/coreutils$ ./src/ls --t
Segmentation fault
With this patch:
tobias:~/git/coreutils$ ./src/ls --t
./src/ls: out of memory, dropping option 'time' while resolving ambiguity
./src/ls: out of memory, dropping option 'time-style' while resolving ambiguity
./src/ls: option '--tabsize' requires an argument
Try './src/ls --help' for more information.
With enough memory:
tobias:~/git/coreutils$ ./src/ls --t
./src/ls: option '--t' is ambiguous; possibilities: '--tabsize' '--time-style'
'--time'
Try './src/ls --help' for more information.
---
lib/getopt.c | 43 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 40 insertions(+), 3 deletions(-)
diff --git a/lib/getopt.c b/lib/getopt.c
index 3b9c585..c3eb7ad 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -521,9 +521,46 @@ _getopt_internal_r (int argc, char **argv, const char
*optstring,
{
/* Second or later nonexact match found. */
struct option_list *newp = malloc (sizeof (*newp));
- newp->p = p;
- newp->next = ambig_list;
- ambig_list = newp;
+ if (newp == NULL)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf = NULL;
+ size_t buflen = 0;
+
+ FILE *fp = open_memstream (&buf, &buflen);
+ if (fp != NULL)
+ {
+ fprintf (fp, _("\
+%s: out of memory, dropping option '%s' while resolving ambiguity\n"),
+ argv[0], p->name);
+
+ if (__builtin_expect (fclose (fp) != EOF, 1))
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |=
_IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+ }
+#else
+ fprintf (stderr, _("\
+%s: out of memory, dropping option '%s' while resolving ambiguity\n"),
+ argv[0], p->name);
+#endif
+ }
+ else
+ {
+ newp->p = p;
+ newp->next = ambig_list;
+ ambig_list = newp;
+ }
}
}
--
2.3.0
- [PATCH] Check malloc result in getopt_long,
Tobias Stoeckmann <=