<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>