summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-11 23:09:34 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-11 23:09:34 +0000
commite7067e38ea8c6e0e498270ee6e8cd6aa5e92796e (patch)
tree894e240578f41db098e5c78fc8d03df97156bd75
parentee1b3b1042c8077cda5027bc0ce317662a1d8feb (diff)
ash: fix segfault in "command -v"
-rw-r--r--shell/ash.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 77fe91a24..08bdfc3b3 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1575,14 +1575,14 @@ static char *optionarg; /* set by nextopt (like getopt) */
static char *optptr; /* used by nextopt */
/*
- * XXX - should get rid of. have all builtins use getopt(3). the
- * library getopt must have the BSD extension static variable "optreset"
- * otherwise it can't be used within the shell safely.
+ * XXX - should get rid of. Have all builtins use getopt(3).
+ * The library getopt must have the BSD extension static variable
+ * "optreset", otherwise it can't be used within the shell safely.
*
- * Standard option processing (a la getopt) for builtin routines. The
- * only argument that is passed to nextopt is the option string; the
- * other arguments are unnecessary. It return the character, or '\0' on
- * end of input.
+ * Standard option processing (a la getopt) for builtin routines.
+ * The only argument that is passed to nextopt is the option string;
+ * the other arguments are unnecessary. It returns the character,
+ * or '\0' on end of input.
*/
static int
nextopt(const char *optstring)
@@ -1593,13 +1593,20 @@ nextopt(const char *optstring)
p = optptr;
if (p == NULL || *p == '\0') {
+ /* We ate entire "-param", take next one */
p = *argptr;
- if (p == NULL || *p != '-' || *++p == '\0')
+ if (p == NULL)
+ return '\0';
+ if (*p != '-')
+ return '\0';
+ if (*++p == '\0') /* just "-" ? */
return '\0';
argptr++;
- if (LONE_DASH(p)) /* check for "--" */
+ if (LONE_DASH(p)) /* "--" ? */
return '\0';
+ /* p => next "-param" */
}
+ /* p => some option char in the middle of a "-param" */
c = *p++;
for (q = optstring; *q != c;) {
if (*q == '\0')
@@ -1608,8 +1615,11 @@ nextopt(const char *optstring)
q++;
}
if (*++q == ':') {
- if (*p == '\0' && (p = *argptr++) == NULL)
- ash_msg_and_raise_error("no arg for -%c option", c);
+ if (*p == '\0') {
+ p = *argptr++;
+ if (p == NULL)
+ ash_msg_and_raise_error("no arg for -%c option", c);
+ }
optionarg = p;
p = NULL;
}
@@ -7421,8 +7431,10 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
else if (c != 'p')
abort();
#endif
- if (verify)
+ /* Mimic bash: just "command -v" doesn't complain, it's a nop */
+ if (verify && (*argptr != NULL)) {
return describe_command(*argptr, verify - VERIFY_BRIEF);
+ }
return 0;
}