From e7c86f7d79f641ab8a0e542d32e857494e943389 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 13 Jan 2021 06:21:53 -0600 Subject: Fix "date -I" segfault and teach lib/args.c that "I(opt):;" short opt with no argument returns NULL same as --opt without = --- lib/args.c | 11 ++++++----- toys/posix/date.c | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/args.c b/lib/args.c index ac83a0fe..f5d3dc24 100644 --- a/lib/args.c +++ b/lib/args.c @@ -131,7 +131,7 @@ struct getoptflagstate }; // Use getoptflagstate to parse one command line option from argv -static int gotflag(struct getoptflagstate *gof, struct opts *opt) +static int gotflag(struct getoptflagstate *gof, struct opts *opt, int shrt) { unsigned long long i; int type; @@ -168,7 +168,8 @@ static int gotflag(struct getoptflagstate *gof, struct opts *opt) } // Does this option take an argument? - if (!gof->arg) { + if (!gof->arg || (shrt && !gof->arg[1])) { + gof->arg = 0; if (opt->flags & 8) return 0; gof->arg = ""; } else gof->arg++; @@ -445,7 +446,7 @@ void get_optflags(void) } // Long option parsed, handle option. - gotflag(&gof, catch); + gotflag(&gof, catch, 0); continue; } @@ -458,7 +459,7 @@ void get_optflags(void) // At this point, we have the args part of -args. Loop through // each entry (could be -abc meaning -a -b -c) saveflags = toys.optflags; - while (*gof.arg) { + while (gof.arg && *gof.arg) { // Identify next option char. for (catch = gof.opts; catch; catch = catch->next) @@ -466,7 +467,7 @@ void get_optflags(void) if (!((catch->flags&4) && gof.arg[1])) break; // Handle option char (advancing past what was used) - if (gotflag(&gof, catch) ) { + if (gotflag(&gof, catch, 1) ) { toys.optflags = saveflags; gof.arg = toys.argv[gof.argc]; goto notflag; diff --git a/toys/posix/date.c b/toys/posix/date.c index ead72e15..86c2d343 100644 --- a/toys/posix/date.c +++ b/toys/posix/date.c @@ -138,7 +138,7 @@ void date_main(void) if (FLAG(I)) { char *iso_formats[] = {"%F","%FT%H%:z","%FT%R%:z","%FT%T%:z","%FT%T,%N%:z"}; - int i = stridx("dhmsn", *TT.I ? *TT.I : 'd'); + int i = stridx("dhmsn", (TT.I && *TT.I) ? *TT.I : 'd'); if (i<0) help_exit("bad -I: %s", TT.I); format_string = xstrdup(iso_formats[i]); -- cgit v1.2.3