From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from newton.hartwick.edu ([147.205.85.10]) by hawkwind.utcs.toronto.edu with SMTP id <25579>; Mon, 17 Apr 2000 16:22:39 -0400 Received: from c26469-a.clnvl1.ct.home.com (147.205.111.20 [147.205.111.20]) by newton.hartwick.edu with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2448.0) id HRZAWDWM; Mon, 17 Apr 2000 15:57:40 -0400 Received: by c26469-a.clnvl1.ct.home.com (sSMTP sendmail emulation); Mon, 17 Apr 2000 15:59:37 -0400 Date: Mon, 17 Apr 2000 15:59:37 -0400 From: Decklin Foster To: Tim Goodwin Cc: rc@hawkwind.utcs.toronto.edu Subject: Re: Bug#62339: rc bug Message-ID: <20000417155937.A29462@photek.dhs.org> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="82I3+IH0IqGh5yIs" User-Agent: Mutt/1.0.1i In-Reply-To: ; from tjg@star.le.ac.uk on Mon, Apr 17, 2000 at 10:25:46AM +0100 Organization: Society for the Prevention of Cruelty to Vermin --82I3+IH0IqGh5yIs Content-Type: text/plain; charset=us-ascii Tim Goodwin writes: > Thanks for the report. I can reproduce this. > > It's not been reported before, so I don't know what's going on, but I'll > let you know as soon as I have a fix. I did send something to to mailing list on Saturday, but it hasn't gotten through yet. I seem to have figured out the use of m in a List structure: if there are no metacharacters, NULL, and if there are, we put a \0 where there's a non-metacharacter in the corresponding part of n, and a \001 where there is. Now in lmatch() when we go through looking for '*'s, we have this loop: for (i = 0; p->w[i] != '\0'; i++) if (p->w[i] != '*' || p->m[i] != 1) { Which assumes that m is as big as w (i.e, not NULL). I came up with this replacement, which works for all the test cases I can think of: if (s == NULL) { if (p == NULL) /* null matches null */ return TRUE; for (; p != NULL; p = p->n) /* one or more stars match null */ if (p->w && strspn(p->w, "*") == strlen(p->w) && p->m && strspn(p->m, "\001") == strlen(p->m)) return TRUE; return FALSE; } I was also able to get rid of 'okay', which i found hard to follow. The comment about the null string is gone too, because IMO the null string fails for the same reason 'foo' fails. There's really no need for an explicit check. A patch is attached. Out of curiosity, why was the decision made to use '\000' and '\001' instead of, say, '0' and '1'? For example in the old code, we have "p->m[i] != 1", and it wouldn't be that hard to write "p->m[i] != '1'" instead. I'm sure there's a reason, but I can't guess it. -- Written with 100% free software. Please support the following websites: www.debian.org www.noamazon.com www.gnu.org www.opendvd.org lpf.ai.mit.edu --82I3+IH0IqGh5yIs Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="rc.patch" --- glob.c.old Wed Oct 21 07:01:46 1998 +++ glob.c Mon Apr 17 15:55:30 2000 @@ -34,23 +34,13 @@ extern bool lmatch(List *s, List *p) { List *q; - int i; - bool okay; if (s == NULL) { if (p == NULL) /* null matches null */ return TRUE; - for (; p != NULL; p = p->n) { /* one or more stars match null */ - if (*p->w != '\0') { /* the null string is a special case; it does *not* match () */ - okay = TRUE; - for (i = 0; p->w[i] != '\0'; i++) - if (p->w[i] != '*' || p->m[i] != 1) { - okay = FALSE; - break; - } - if (okay) - return TRUE; - } - } + for (; p != NULL; p = p->n) /* one or more stars match null */ + if (p->w && strspn(p->w, "*") == strlen(p->w) && + p->m && strspn(p->m, "\001") == strlen(p->m)) + return TRUE; return FALSE; } for (; s != NULL; s = s->n) --82I3+IH0IqGh5yIs--