diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2005-07-01 02:11:56 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2005-07-01 02:11:56 +0000 |
commit | 64f9e6f06daae6d1e35da7f1a4f65887b99e4a10 (patch) | |
tree | 29b8975d2836fcb19547f96ee17ab34d9dfd6dea | |
parent | 90fddac1ecf803ca16f41612c08f58c63ef38720 (diff) |
More robust example of numeric argument handling. The old example
code would dereference NULL for mixed letter and number args.
OK deraadt@
-rw-r--r-- | lib/libc/stdlib/getopt.3 | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/lib/libc/stdlib/getopt.3 b/lib/libc/stdlib/getopt.3 index e0dc3701f90..52c902d6a54 100644 --- a/lib/libc/stdlib/getopt.3 +++ b/lib/libc/stdlib/getopt.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: getopt.3,v 1.31 2005/03/26 22:02:15 millert Exp $ +.\" $OpenBSD: getopt.3,v 1.32 2005/07/01 02:11:55 millert Exp $ .\" .Dd December 17, 2002 .Dt GETOPT 3 @@ -351,22 +351,34 @@ as an option. This practice is wrong, and should not be used in any current development. It is provided for backward compatibility .Em only . -The following code fragment works in most cases. +The following code fragment works in most cases and can handle mixed +number and letter arguments. + .Bd -literal -offset indent -int ch; -long length; -char *p; +int aflag = 0, bflag = 0, ch, lastch = '\e0'; +int length = -1, newarg = 1, prevoptind = 1; -while ((ch = getopt(argc, argv, "0123456789")) != -1) { +while ((ch = getopt(argc, argv, "0123456789ab")) != -1) { switch (ch) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - p = argv[optind - 1]; - if (p[0] == '-' && p[1] == ch && !p[2]) - length = ch - '0'; - else - length = strtol(argv[optind] + 1, NULL, 10); + if (newarg || !isdigit(lastch)) + length = 0; + else if (length > INT_MAX / 10) + usage(); + length = (length * 10) + (ch - '0'); + break; + case 'a': + aflag = 1; break; + case 'b': + bflag = 1; + break; + default: + usage(); } + lastch = ch; + newarg = optind != prevoptind; + prevoptind = optind; } .Ed |