about summary refs log tree commit diff
path: root/src/misc
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-12-04 10:23:33 -0500
committerRich Felker <dalias@aerifal.cx>2014-12-04 10:23:33 -0500
commit014275b547e3059db5c45986408757c250e8198d (patch)
treec98cbdb623b6917b1206d2e18f38f6edc8c7a896 /src/misc
parentbe1f67ab6fde1989af7b2e2946804e9009931a8a (diff)
downloadmusl-014275b547e3059db5c45986408757c250e8198d.tar.gz
musl-014275b547e3059db5c45986408757c250e8198d.tar.xz
musl-014275b547e3059db5c45986408757c250e8198d.zip
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 ':'.
Diffstat (limited to 'src/misc')
-rw-r--r--src/misc/getopt.c13
1 files 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;
 		}