From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/12768 Path: news.gmane.org!.POSTED!not-for-mail From: Szabolcs Nagy Newsgroups: gmane.linux.lib.musl.general Subject: Re: getopt_long_only bug Date: Thu, 26 Apr 2018 22:17:13 +0200 Message-ID: <20180426201713.GS4418@port70.net> References: <20180426104630.GR4418@port70.net> <20180426145037.GG3094@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: blaine.gmane.org 1524773723 32472 195.159.176.226 (26 Apr 2018 20:15:23 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 26 Apr 2018 20:15:23 +0000 (UTC) User-Agent: Mutt/1.9.1 (2017-09-22) To: musl@lists.openwall.com Original-X-From: musl-return-12784-gllmg-musl=m.gmane.org@lists.openwall.com Thu Apr 26 22:15:18 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1fBnIT-0008Ky-R6 for gllmg-musl@m.gmane.org; Thu, 26 Apr 2018 22:15:17 +0200 Original-Received: (qmail 26591 invoked by uid 550); 26 Apr 2018 20:17:26 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 26567 invoked from network); 26 Apr 2018 20:17:26 -0000 Mail-Followup-To: musl@lists.openwall.com Content-Disposition: inline In-Reply-To: <20180426145037.GG3094@brightrain.aerifal.cx> Xref: news.gmane.org gmane.linux.lib.musl.general:12768 Archived-At: * Rich Felker [2018-04-26 10:50:37 -0400]: > OK, this is a weird corner case. Apparently when in longonly mode, > short options need to be counted in addition to long ones for > determining if a partial match is unique. > > The attached patch should solve the problem. Any review/comments would > be helpful. It uses an ugly inline strstr of sorts, because to use > strstr we'd need to copy to a temp buffer, and we wouldn't even > benefit since the string being searched is so short (usually 1 byte, > at most 4). The only reason it's there at all is because we committed > to supporting multibyte option chars in getopt.c so getopt_long_only > needs to handle them consistently. looks ok to me. > diff --git a/src/misc/getopt_long.c b/src/misc/getopt_long.c > index 008b747..ddcef94 100644 > --- a/src/misc/getopt_long.c > +++ b/src/misc/getopt_long.c > @@ -1,5 +1,7 @@ > #define _GNU_SOURCE > #include > +#include > +#include > #include > #include > #include > @@ -58,10 +60,10 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring > { > int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':'; > int i, cnt, match; > - char *arg, *opt; > + char *arg, *opt, *start = argv[optind]+1; > for (cnt=i=0; longopts[i].name; i++) { > const char *name = longopts[i].name; > - opt = argv[optind]+1; > + opt = start; > if (*opt == '-') opt++; > while (*opt && *opt != '=' && *opt == *name) > name++, opt++; > @@ -74,6 +76,17 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring > } > cnt++; > } > + if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) { > + int l = arg-start; > + for (i=0; optstring[i]; i++) { > + int j; > + for (j=0; j + if (j==l) { > + cnt++; > + break; > + } > + } > + } > if (cnt==1) { > i = match; > opt = arg;