From 014275b547e3059db5c45986408757c250e8198d Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 4 Dec 2014 10:23:33 -0500 Subject: fix getopt handling of ':' modifier for multibyte option characters the previous hard-coded offsets of +1 and +2 contained a hidden assumption that the option character matched was single-byte, despite this implementation of getopt attempting to support multibyte option characters. this patch reworks the matching logic to leave the final index pointing just past the matched character so that fixed offsets can be used to check for ':'. --- src/misc/getopt.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/misc/getopt.c b/src/misc/getopt.c index a698c8d4..52aa7a3a 100644 --- a/src/misc/getopt.c +++ b/src/misc/getopt.c @@ -58,7 +58,12 @@ int getopt(int argc, char * const argv[], const char *optstring) if (optstring[0] == '-') optstring++; - for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1); + i = 0; + d = 0; + do { + l = mbtowc(&d, optstring+i, MB_LEN_MAX); + if (l>0) i+=l; else i++; + } while (l && d != c); if (d != c) { if (optstring[0] != ':' && opterr) { @@ -69,8 +74,8 @@ int getopt(int argc, char * const argv[], const char *optstring) } return '?'; } - if (optstring[i+1] == ':') { - if (optstring[i+2] == ':') optarg = 0; + if (optstring[i] == ':') { + if (optstring[i+1] == ':') optarg = 0; else if (optind >= argc) { if (optstring[0] == ':') return ':'; if (opterr) { @@ -81,7 +86,7 @@ int getopt(int argc, char * const argv[], const char *optstring) } return '?'; } - if (optstring[i+2] != ':' || optpos) { + if (optstring[i+1] != ':' || optpos) { optarg = argv[optind++] + optpos; optpos = 0; } -- cgit v1.2.1