Date: Sun, 23 Feb 2003 15:52:18 -0500 From: John Stalker <stalker@Math.Princeton.EDU> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/48603: Getopt(1) is broken. Patch included. Message-ID: <200302232052.h1NKqIG09316@math.Princeton.EDU>
next in thread | raw e-mail | index | archive | help
>Number: 48603 >Category: bin >Synopsis: Getopt is broken. Patch included. >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Feb 23 13:00:20 PST 2003 >Closed-Date: >Last-Modified: >Originator: John Stalker >Release: FreeBSD 4.7-STABLE i386 >Organization: Princeton University >Environment: System: FreeBSD bilbo.dev.null 4.7-STABLE FreeBSD 4.7-STABLE #1: Fri Dec 27 23:0 0:21 EST 2002 root@rockhopper.dev.null:/usr/obj/usr/src/sys/BILBO i386 >Description: Getopt(1) does not handle arguments with spaces or shell wildcards intelligently, as its manpage admits. The main problem is that the manpage says to pass it arguments as $* rather than as "$@". This needs to be corrected, but that requires two other changes. getopt has to be changed so that its output is ready for reinterpretation by the shell and the set command needs to by preceded by an eval so that this interpretation is done correctly. >How-To-Repeat: Use the getopt(1) example, which has arguments "abo:", with arguments -ab -o "this option argument has spaces in it" or with -ab -o '/*'. >Fix: There are two possible fixes. The simpler of the two is given as a patch below. This patches both getopt and its manpage. It simply modifies getopt to single-quote option arguments--handling embedded single quotes correctly--and modifies the manpage accordingly. One can also modify getopt to escape anything which could confuse the shell rather than quoting. This is more complicated, but it might be helpful for shell scripts written according to the onld manpage. They can never be fixed properly, but they would cope better with escape sequences than single quotes. Let me know if you would like a patch for that as well. diff -Naur getopt.orig/getopt.1 getopt.fix1/getopt.1 --- getopt.orig/getopt.1 Sun Feb 23 10:47:37 2003 +++ getopt.fix1/getopt.1 Sun Feb 23 11:01:46 2003 @@ -7,7 +7,7 @@ .Nm getopt .Nd parse command options .Sh SYNOPSIS -.Nm args=\`getopt Ar optstring $*\` +.Nm args=\`getopt Ar optstring "$@"\` ; errcode=$?; set \-\- $args .Sh DESCRIPTION The @@ -46,18 +46,18 @@ which requires an argument. .Pp .Bd -literal -offset indent -args=\`getopt abo: $*\` -# you should not use \`getopt abo: "$@"\` since that would parse -# the arguments differently from what the set command below does. +args=\`getopt abo: "$@"\` if [ $? != 0 ] then echo 'Usage: ...' exit 2 fi -set \-\- $args +eval set \-\- $args # You cannot use the set command with a backquoted getopt directly, # since the exit code from getopt would be shadowed by those of set, # which is zero by definition. +# Eval is needed because set will otherwise break arguments at $IFS +# even when they are single-quoted. for i do case "$i" @@ -66,8 +66,7 @@ echo flag $i set; sflags="${i#-}$sflags"; shift;; \-o) - echo oarg is "'"$2"'"; oarg="$2"; shift; - shift;; + echo oarg is "'"$2"'"; oarg="$2"; shift 2;; \-\-) shift; break;; esac @@ -102,18 +101,13 @@ Example changed in .Fx version 3.2 and 4.0. +Modified by +.An John Stalker. .Sh BUGS Whatever .Xr getopt 3 has. .Pp -Arguments containing white space or embedded shell metacharacters -generally will not survive intact; this looks easy to fix but -isn't. People trying to fix -.Nm -or the example in this manpage should check the history of this file -in -.Fx . .Pp The error message for an invalid option is identified as coming from @@ -121,7 +115,7 @@ rather than from the shell procedure containing the invocation of .Nm ; -this again is hard to fix. +this is hard to fix. .Pp The precise best way to use the .Nm set diff -Naur getopt.orig/getopt.c getopt.fix1/getopt.c --- getopt.orig/getopt.c Sun Feb 23 10:47:37 2003 +++ getopt.fix1/getopt.c Sun Feb 23 09:56:22 2003 @@ -18,10 +18,18 @@ status = 1; /* getopt routine gave message */ break; default: - if (optarg != NULL) - printf(" -%c %s", c, optarg); - else - printf(" -%c", c); + printf(" -%c", c); + if (optarg != NULL) { /* quote argument for shell */ + printf(" '"); + while (*optarg != '\0') { + if (optarg[0] == '\'') + printf("'\''"); + else + printf("%c", optarg[0]); + optarg++; + } + printf("'"); + } break; } printf(" --"); -- John Stalker Department of Mathematics Princeton University (609)258-6469 >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200302232052.h1NKqIG09316>