Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: Re: zsh 4.2.5 segfaults when substituting on $match
- X-seq: zsh-workers 21655
- From: Peter Stephenson <pws@xxxxxxxxxxxxxxxxxxxxxxxx>
- To: Zsh Workers <zsh-workers@xxxxxxxxxx>
- Subject: PATCH: Re: zsh 4.2.5 segfaults when substituting on $match
- Date: Thu, 18 Aug 2005 00:42:57 +0100
- In-reply-to: <20050815203800.GA144@DervishD>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <20050815203800.GA144@DervishD>
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 <pws@xxxxxxxxxxxxxxxxxxxxxxxx>
Work: pws@xxxxxxx
Web: http://www.pwstephenson.fsnet.co.uk
Messages sorted by:
Reverse Date,
Date,
Thread,
Author