Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH v2] jp: fix segfaults during parameter expansion



Running `zsh -fc ': ${${(PAA)p[foo]}::=x}'` in current zsh versions causes:

> "segmentation fault (core dumped) zsh -fc ': ${${(PAA)p[foo]}::=x}'

Also happens when testing with machabot:

> 19:42 <jp> > : ${${(PAA)p[foo]}::=x}
> 19:42 <machabot> jp: zsh[248]: segfault at 0 ip b7dfcda3 sp bfeb9ebc
>       error 4 in libc-2.13.so[b7d84000+149000]

Add a simple `dupstring(s2)` fallback instead of pointlessly
trying to concatenate `s2` to NULL and segfaulting.

Also added indication of empty string using `(nil)`; the empty string
case should still provide a somewhat useful error message of

> zsh:1: not an identifier: (nil)

rather than

> zsh:1: not an identifier:

which is fairly confusing.

Signed-off-by: Joey Pabalinas <joeypabalinas@xxxxxxxxx>
Requested-by: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>

 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/Src/params.c b/Src/params.c
index de7730ae735a44963c..44a942296f23ddf88f 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -3004,6 +3004,8 @@ assignsparam(char *s, char *val, int flags)
     int sstart, created = 0;
 
     if (!isident(s)) {
+	if (!strcmp(s, ""))
+	    s = "(nil)";
 	zerr("not an identifier: %s", s);
 	zsfree(val);
 	errflag |= ERRFLAG_ERROR;
diff --git a/Src/string.c b/Src/string.c
index 9e14ef94919c3e8ec5..7c24ab3c45777f31e9 100644
--- a/Src/string.c
+++ b/Src/string.c
@@ -126,9 +126,17 @@ mod_export char *
 zhtricat(char const *s1, char const *s2, char const *s3)
 {
     char *ptr;
-    size_t l1 = strlen(s1);
-    size_t l2 = strlen(s2);
+    size_t l1;
+    size_t l2;
 
+    /* String duplicate fallback to prevent NULL derefs */
+    if (!s1 && !s2)
+	return dupstring(s3);
+    if (!s1)
+	l1 = 0, s1 = s2;
+    else
+	l1 = strlen(s1);
+    l2 = strlen(s2);
     ptr = (char *)zhalloc(l1 + l2 + strlen(s3) + 1);
     strcpy(ptr, s1);
     strcpy(ptr + l1, s2);
@@ -144,8 +152,12 @@ dyncat(const char *s1, const char *s2)
 {
     /* This version always uses space from the current heap. */
     char *ptr;
-    size_t l1 = strlen(s1);
+    size_t l1;
 
+    /* String duplicate fallback to prevent NULL derefs */
+    if (!s1)
+	return dupstring(s2);
+    l1 = strlen(s1);
     ptr = (char *)zhalloc(l1 + strlen(s2) + 1);
     strcpy(ptr, s1);
     strcpy(ptr + l1, s2);
@@ -158,8 +170,12 @@ bicat(const char *s1, const char *s2)
 {
     /* This version always uses permanently-allocated space. */
     char *ptr;
-    size_t l1 = strlen(s1);
+    size_t l1;
 
+    /* String duplicate fallback to prevent NULL derefs */
+    if (!s1)
+	return dupstring(s2);
+    l1 = strlen(s1);
     ptr = (char *)zalloc(l1 + strlen(s2) + 1);
     strcpy(ptr, s1);
     strcpy(ptr + l1, s2);
diff --git a/Src/subst.c b/Src/subst.c
index d027e3d83cadc631a7..9a8c635e313687d046 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -3150,6 +3150,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
 	}
 	if (*itype_end(s, IIDENT, 0)) {
 	    untokenize(s);
+	    if (!strcmp(s, " "))
+		s = "(nil)";
 	    zerr("not an identifier: %s", s);
 	    return NULL;
 	}
@@ -3210,6 +3212,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
 	++s;
 	if (*itype_end(s, IIDENT, 0)) {
 	    untokenize(s);
+	    if (!strcmp(s, ""))
+		s = "(nil)";
 	    zerr("not an identifier: %s", s);
 	    return NULL;
 	}
-- 
2.15.1

Attachment: signature.asc
Description: PGP signature



Messages sorted by: Reverse Date, Date, Thread, Author