Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Patch: getopts (zsh-3.1.2-zefram3)



The attached patch corrects some minor bugs and a major one in function
bin_getopts() in builtin.c.

The minor bugs are: 
- optbuf is unitialized, but optbuf[1] is checked for ':'.
- The check for required arguments is incorrect.
- If an optional argument is missing, OPTARG keeps the old value instead
of    being reset to empty.

The major bug, which didn't exist in zsh-3.1.2: 
If an an empty string is used as an optional argument, getopts returns
1, leaving all remaining options unprocessed. 

I'm also not sure about the statement starting in line 2537:
  if (zoptind < 1) ...
Actually zoptind is NEVER set to 0 in the sources. I left it, though,
because the user might set OPTIND=0 deliberately, although I'm in doubt
whether that should be considered legal. 

Regards,
  Bernd

-- 
Bernd Eggink
Regionales Rechenzentrum der Universitaet Hamburg
eggink@xxxxxxxxxxxxxxxxxx
http://www.rrz.uni-hamburg.de/eggink/BEggink.html
--- builtin.c.old	Sun Jan 11 20:23:15 1998
+++ builtin.c	Sat Mar  7 15:27:15 1998
@@ -2531,7 +2531,7 @@
     char *optstr = unmetafy(*argv++, &lenoptstr), *var = *argv++;
     char **args = (*argv) ? argv : pparams;
     static int optcind = 0;
-    char *str, optbuf[2], *p, opch;
+    char *str, optbuf[2] = " ", *p, opch;
 
     /* zoptind keeps count of the current argument number */
     if (zoptind < 1) {
@@ -2550,11 +2550,11 @@
 
     /* find place in relevant argument */
     str = unmetafy(dupstring(args[zoptind - 1]), &lenstr);
-    if(optcind && optcind >= lenstr) {
+    if(optcind >= lenstr) {
+	optcind = 0;
 	if(!args[zoptind++])
 	    return 1;
 	str = unmetafy(dupstring(args[zoptind - 1]), &lenstr);
-	optcind = 0;
     }
     if(!optcind) {
 	if(lenstr < 2 || (*str != '-' && *str != '+'))
@@ -2577,20 +2577,21 @@
     if(optbuf[1] == ':' || !(p = memchr(optstr, opch, lenoptstr))) {
 	p = "?";
 err:
+    zsfree(zoptarg);
 	if(quiet) {
 	    setsparam(var, ztrdup(p));
-	    zsfree(zoptarg);
 	    zoptarg = metafy(optbuf, lenoptbuf, META_DUP);
 	} else {
 	    zerr(*p == '?' ? "bad option: -%c" :
 		"argument expected after -%c option", NULL, opch);
+        zoptarg=ztrdup("");
 	    errflag = 0;
 	}
 	return 0;
     }
 
     /* check for required argument */
-    if(p != optstr+lenoptstr && p[1] == ':') {
+    if(p != optstr+lenoptstr-1 && p[1] == ':') {
 	if(optcind == lenstr) {
 	    if(!args[zoptind]) {
 		p = ":";


Messages sorted by: Reverse Date, Date, Thread, Author