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

Re: [PATCH] Don't segfault when uniquifying hidden tied arrays




> While pm->u.data is never NULL, the value assigned to x may be NULL but that's fine, then the code that follows simply does nothing; the function uniqarray immediately returns if its parameter is NULL.

The test case that fails if &nullarray is NOT returned by gsu.a->getfn is
  Running test: add array to empty parameter

Strange, I can't reproduce this. My patch was built on top of workers/54987 but A06assign.zest fails neither with my original patch nor when I rebase it onto HEAD.

With your patch:

Src/zsh -f
% setopt typesettounset
% typeset -T VAR var
% () { typeset -i var; typeset -g -U VAR }
% echo $VAR

% echo $+VAR
0
% () { typeset -i var; typeset -g -U VAR='a:a:b' }
% () { typeset -i var; typeset -g -U VAR='a:a:b'; typeset -p VAR }
zsh: bus error  Src/zsh -f

It crashes on "typeset -p" rather than on the assignment itself.
Without your patch, the above does not crash (but your original
example does).

I don't get a bus error but a segmentation fault and it's not caused by the last "typeset -p VAR" but by the "typeset -g -U VAR='a:a:b'" that precedes it. In fact the following is enough to trigger the segmentation fault:

% setopt typesettounset
% typeset -T VAR var
% typeset -U VAR='a:a:b'
% typeset -U VAR='a:a:b'
zsh: segmentation fault

I figured that the issue, or at least one of the issues, was workers/55020. After rebasing this patch onto that one (see updated patch below), the problem goes away.

Don't segfault when uniquifying hidden tied arrays

Philippe

diff --git a/Src/builtin.c b/Src/builtin.c
index 61d2a2730..4a0eba671 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2253,7 +2253,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
 	    return NULL;
 	}
 	if ((on & PM_UNIQUE) && !(pm->node.flags & PM_READONLY & ~off)) {
-	    Param apm;
 	    char **x;
 	    if (PM_TYPE(pm->node.flags) == PM_ARRAY) {
 		x = (*pm->gsu.a->getfn)(pm);
@@ -2264,10 +2263,10 @@ typeset_single(char *cname, char *pname, Param pm, int func,
 		    (*pm->gsu.a->setfn)(pm, x);
 		} else if (pm->ename && x)
 		    arrfixenv(pm->ename, x);
-	    } else if (PM_TYPE(pm->node.flags) == PM_SCALAR && pm->ename &&
-		       (apm =
-			(Param) paramtab->getnode(paramtab, pm->ename))) {
-		x = (*apm->gsu.a->getfn)(apm);
+	    } else if (PM_TYPE(pm->node.flags) == PM_SCALAR && pm->ename) {
+		x = *(pm->node.flags & PM_SPECIAL
+		      ? (char ***)pm->u.data
+		      : ((struct tieddata *)pm->u.data)->arrptr);
 		uniqarray(x);
 		if (x)
 		    arrfixenv(pm->node.nam, x);
diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst
index 7bc44dbdc..3bdd36b32 100644
--- a/Test/B02typeset.ztst
+++ b/Test/B02typeset.ztst
@@ -329,6 +329,20 @@
 >local unique tied array SCALAR
 >array local tied SCALAR array
 
+ typeset -T VAR var=(a b c b a)
+ () {
+   typeset -i var=1
+   typeset -g -U VAR
+   typeset -p VAR var
+ }
+ typeset -p VAR var
+0:Regression test for not segfaulting when uniquifying a hidden tied array
+F:BUG:The inner "typeset -p VAR" should contain the value of the outer "var"
+>typeset -g -UT VAR var=1
+>typeset -i var=1
+>typeset -UT VAR var=( a b c )
+>typeset -aT VAR var=( a b c )
+
  typeset -T SCALAR array
  typeset +T SCALAR
 1:Untying is prohibited


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