From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23727 invoked from network); 17 Aug 2005 23:34:57 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 17 Aug 2005 23:34:57 -0000 Received: (qmail 73219 invoked from network); 17 Aug 2005 23:34:51 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 17 Aug 2005 23:34:51 -0000 Received: (qmail 26956 invoked by alias); 17 Aug 2005 23:34:48 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 21655 Received: (qmail 26916 invoked from network); 17 Aug 2005 23:34:47 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 17 Aug 2005 23:34:47 -0000 Received: (qmail 72869 invoked from network); 17 Aug 2005 23:34:47 -0000 Received: from cmailg1.svr.pol.co.uk (195.92.195.171) by a.mx.sunsite.dk with SMTP; 17 Aug 2005 23:34:42 -0000 Received: from modem-2558.parera.dialup.pol.co.uk ([81.78.185.254] helo=pwstephenson.fsnet.co.uk) by cmailg1.svr.pol.co.uk with esmtp (Exim 4.41) id 1E5XQe-000429-DY for zsh-workers@sunsite.dk; Thu, 18 Aug 2005 00:34:42 +0100 Received: by pwstephenson.fsnet.co.uk (Postfix, from userid 501) id AF914866A; Wed, 17 Aug 2005 19:42:59 -0400 (EDT) Received: from pwstephenson.fsnet.co.uk (localhost [127.0.0.1]) by pwstephenson.fsnet.co.uk (Postfix) with ESMTP id F25F28664 for ; Thu, 18 Aug 2005 00:42:58 +0100 (BST) To: Zsh Workers Subject: PATCH: Re: zsh 4.2.5 segfaults when substituting on $match In-reply-to: <20050815203800.GA144@DervishD> References: <20050815203800.GA144@DervishD> Date: Thu, 18 Aug 2005 00:42:57 +0100 From: Peter Stephenson Message-Id: <20050817234259.AF914866A@pwstephenson.fsnet.co.uk> X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.0.4 DervishD wrote: > Hi all :) > > zsh segfaults with this: > > $ zsh -f > $ emulate -L zsh > $ setopt extendedglob > $ file="a" > $ print ${file//(#b)(*)/${match//a/}} [I've been away for a couple of days. For future reference, I am away again the second half of next week.] Yes, this looks like being a result of one of the zillions of places where the code, instead of passing an argument like real programmes do, declares a global or static variable and vaguely hopes it will come out right in the end. This one's been around for a long time; it may even be my fault. To other zsh programmers: *Please* don't. Index: Src/glob.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/glob.c,v retrieving revision 1.44 diff -u -r1.44 glob.c --- Src/glob.c 15 Aug 2005 16:04:32 -0000 1.44 +++ Src/glob.c 17 Aug 2005 23:32:56 -0000 @@ -2000,15 +2000,6 @@ }; typedef struct repldata *Repldata; -/* - * List of bits of matches to concatenate with replacement string. - * The data is a struct repldata. It is not used in cases like - * ${...//#foo/bar} even though SUB_GLOBAL is set, since the match - * is anchored. It goes on the heap. - */ - -static LinkList repllist; - /* Having found a match in getmatch, decide what part of string * to return. The matched part starts b characters into string s * and finishes e characters in: 0 <= b <= e <= strlen(s) @@ -2020,7 +2011,8 @@ /**/ static char * -get_match_ret(char *s, int b, int e, int fl, char *replstr) +get_match_ret(char *s, int b, int e, int fl, char *replstr, + LinkList repllist) { char buf[80], *r, *p, *rr; int ll = 0, l = strlen(s), bl = 0, t = 0, i; @@ -2230,8 +2222,13 @@ * lengths. */ int ioff, l = strlen(*sp), uml = ztrlen(*sp), matched = 1, umlen; - - repllist = NULL; + /* + * List of bits of matches to concatenate with replacement string. + * The data is a struct repldata. It is not used in cases like + * ${...//#foo/bar} even though SUB_GLOBAL is set, since the match + * is anchored. It goes on the heap. + */ + static LinkList repllist = NULL; /* perform must-match test for complex closures */ if (p->mustoff) @@ -2254,7 +2251,7 @@ if (fl & SUB_ALL) { int i = matched && pattry(p, s); - *sp = get_match_ret(*sp, 0, i ? l : 0, fl, i ? replstr : 0); + *sp = get_match_ret(*sp, 0, i ? l : 0, fl, i ? replstr : 0, repllist); if (! **sp && (((fl & SUB_MATCH) && !i) || ((fl & SUB_REST) && i))) return 0; return 1; @@ -2283,7 +2280,7 @@ } } } - *sp = get_match_ret(*sp, 0, mlen, fl, replstr); + *sp = get_match_ret(*sp, 0, mlen, fl, replstr, repllist); return 1; } break; @@ -2298,7 +2295,7 @@ t--; set_pat_start(p, t-s); if (pattrylen(p, t, s + l - t, umlen, ioff)) { - *sp = get_match_ret(*sp, t - s, l, fl, replstr); + *sp = get_match_ret(*sp, t - s, l, fl, replstr, repllist); return 1; } if (t > s+1 && t[-2] == Meta) @@ -2314,7 +2311,7 @@ ioff++, METAINC(t), umlen--) { set_pat_start(p, t-s); if (pattrylen(p, t, s + l - t, umlen, ioff)) { - *sp = get_match_ret(*sp, t-s, l, fl, replstr); + *sp = get_match_ret(*sp, t-s, l, fl, replstr, repllist); return 1; } if (*t == Meta) @@ -2326,7 +2323,7 @@ /* Smallest at start, but matching substrings. */ set_pat_start(p, l); if (!(fl & SUB_GLOBAL) && pattry(p, s + l) && !--n) { - *sp = get_match_ret(*sp, 0, 0, fl, replstr); + *sp = get_match_ret(*sp, 0, 0, fl, replstr, repllist); return 1; } /* fall through */ case (SUB_SUBSTR|SUB_LONG): @@ -2357,7 +2354,8 @@ } } if (!--n || (n <= 0 && (fl & SUB_GLOBAL))) { - *sp = get_match_ret(*sp, t-s, mpos-s, fl, replstr); + *sp = get_match_ret(*sp, t-s, mpos-s, fl, + replstr, repllist); if (mpos == t) METAINC(mpos); } @@ -2396,7 +2394,7 @@ set_pat_start(p, l); if ((fl & (SUB_LONG|SUB_GLOBAL)) == SUB_LONG && pattry(p, s + l) && !--n) { - *sp = get_match_ret(*sp, 0, 0, fl, replstr); + *sp = get_match_ret(*sp, 0, 0, fl, replstr, repllist); return 1; } break; @@ -2407,7 +2405,7 @@ if (!(fl & SUB_LONG)) { set_pat_start(p, l); if (pattrylen(p, s + l, 0, 0, uml) && !--n) { - *sp = get_match_ret(*sp, l, l, fl, replstr); + *sp = get_match_ret(*sp, l, l, fl, replstr, repllist); return 1; } } @@ -2431,13 +2429,14 @@ } } } - *sp = get_match_ret(*sp, t-s, mpos-s, fl, replstr); + *sp = get_match_ret(*sp, t-s, mpos-s, fl, + replstr, repllist); return 1; } } set_pat_start(p, l); if ((fl & SUB_LONG) && pattrylen(p, s + l, 0, 0, uml) && !--n) { - *sp = get_match_ret(*sp, l, l, fl, replstr); + *sp = get_match_ret(*sp, l, l, fl, replstr, repllist); return 1; } break; @@ -2478,7 +2477,7 @@ } /* munge the whole string: no match, so no replstr */ - *sp = get_match_ret(*sp, 0, 0, fl, 0); + *sp = get_match_ret(*sp, 0, 0, fl, 0, 0); return 1; } Index: Test/D04parameter.ztst =================================================================== RCS file: /cvsroot/zsh/zsh/Test/D04parameter.ztst,v retrieving revision 1.10 diff -u -r1.10 D04parameter.ztst --- Test/D04parameter.ztst 26 Apr 2005 09:51:30 -0000 1.10 +++ Test/D04parameter.ztst 17 Aug 2005 23:33:03 -0000 @@ -604,3 +604,11 @@ print "${${foo}/?*/replacement}" 0:Quoted zero-length strings are handled properly > + + file=aleftkept + print ${file//(#b)(*)left/${match/a/andsome}} + print ${file//(#b)(*)left/${match//a/andsome}} +0:Substitutions where $match is itself substituted in the replacement +>andsomekept +>andsomekept + -- Peter Stephenson Work: pws@csr.com Web: http://www.pwstephenson.fsnet.co.uk