<p dir="ltr">Not done yet but it's being addressed.<br></p>
<p dir="ltr">Richard</p>
<p dir="ltr">Sent by mobile; excuse my brevity.</p>
<div class="gmail_quote">---------- Forwarded message ----------<br>From: "Bart Schaefer" <<a href="mailto:schaefer@brasslantern.com">schaefer@brasslantern.com</a>><br>Date: Jan 20, 2014 2:11 AM<br>Subject: Re: segfault with exceedingly long path<br>
To: <<a href="mailto:zsh-workers@zsh.org">zsh-workers@zsh.org</a>><br>Cc: <br><br type="attribution">On Jan 19, 4:02pm, Bart Schaefer wrote:<br>
}<br>
} I don't think we want to let this can of worms out of Pandora's box,<br>
} or we'll be chasing geese until the cows come home to roost.<br>
<br>
In spite of that ... we could at least not dump core in this specific<br>
case. There are probably many other core dumps waiting to be exposed.<br>
<br>
Behavior becomes undefined once the path gets too long, but:<br>
<br>
diff --git a/Src/utils.c b/Src/utils.c<br>
index c6d178c..705d2c4 100644<br>
--- a/Src/utils.c<br>
+++ b/Src/utils.c<br>
@@ -725,32 +725,36 @@ xsymlinks(char *s)<br>
char **pp, **opp;<br>
char xbuf2[PATH_MAX*2], xbuf3[PATH_MAX*2];<br>
int t0, ret = 0;<br>
+ zulong xbuflen = strlen(xbuf);<br>
<br>
opp = pp = slashsplit(s);<br>
- for (; *pp; pp++) {<br>
- if (!strcmp(*pp, ".")) {<br>
- zsfree(*pp);<br>
+ for (; xbuflen < sizeof(xbuf) && *pp; pp++) {<br>
+ if (!strcmp(*pp, "."))<br>
continue;<br>
- }<br>
if (!strcmp(*pp, "..")) {<br>
char *p;<br>
<br>
- zsfree(*pp);<br>
if (!strcmp(xbuf, "/"))<br>
continue;<br>
if (!*xbuf)<br>
continue;<br>
- p = xbuf + strlen(xbuf);<br>
- while (*--p != '/');<br>
+ p = xbuf + xbuflen;<br>
+ while (*--p != '/')<br>
+ xbuflen--;<br>
*p = '\0';<br>
continue;<br>
}<br>
sprintf(xbuf2, "%s/%s", xbuf, *pp);<br>
t0 = readlink(unmeta(xbuf2), xbuf3, PATH_MAX);<br>
if (t0 == -1) {<br>
- strcat(xbuf, "/");<br>
- strcat(xbuf, *pp);<br>
- zsfree(*pp);<br>
+ zulong pplen = strlen(pp) + 1;<br>
+ if ((xbuflen += pplen) < sizeof(xbuf)) {<br>
+ strcat(xbuf, "/");<br>
+ strcat(xbuf, *pp);<br>
+ } else {<br>
+ *xbuf = 0;<br>
+ break;<br>
+ }<br>
} else {<br>
ret = 1;<br>
metafy(xbuf3, t0, META_NOALLOC);<br>
@@ -759,10 +763,9 @@ xsymlinks(char *s)<br>
xsymlinks(xbuf3 + 1);<br>
} else<br>
xsymlinks(xbuf3);<br>
- zsfree(*pp);<br>
}<br>
}<br>
- free(opp);<br>
+ freearray(opp);<br>
return ret;<br>
}<br>
<br>
@@ -779,8 +782,10 @@ xsymlink(char *s)<br>
return NULL;<br>
*xbuf = '\0';<br>
xsymlinks(s + 1);<br>
- if (!*xbuf)<br>
+ if (!*xbuf) {<br>
+ zwarn("path expansion failed, using root directory");<br>
return ztrdup("/");<br>
+ }<br>
return ztrdup(xbuf);<br>
}<br>
<br>
<br>
--<br>
Barton E. Schaefer<br>
</div>