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

Philippe Altherr <[email protected]> Thu, 23 Jul 2026 00:29:11 +0200
Newsgroups gmane.comp.shells.zsh.devel
Message-ID <CAGdYchv8w4Kv9qjtcmCJx4apPtfcPwc_dNvtecTjDmwMMw+YMw@mail.gmail.com>
--000000000000dc872106573aab44
Content-Type: multipart/alternative; boundary="000000000000dc871f06573aab42"

--000000000000dc871f06573aab42
Content-Type: text/plain; charset="UTF-8"

> > 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
<https://zsh.org/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
<https://zsh.org/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
<https://github.com/paltherr/zsh/compare/dont-segfault-when-uniquifying-hidden-tied-arrays-start...paltherr:zsh:dont-segfault-when-uniquifying-hidden-tied-arrays>

Philippe

--000000000000dc871f06573aab42
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><br></div><div class=3D"gmail_quote gmail=
_quote_container"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">&gt; Wh=
ile pm-&gt;u.data is never NULL, the value assigned to x may be NULL but th=
at&#39;s fine, then the code that follows simply does nothing; the function=
 uniqarray immediately returns if its parameter is NULL.<br>
<br>
The test case that fails if &amp;nullarray is NOT returned by gsu.a-&gt;get=
fn is<br>
=C2=A0 Running test: add array to empty parameter<br></blockquote><div><br>=
</div><div>Strange, I can&#39;t reproduce this. My patch was built on top o=
f=C2=A0<a href=3D"https://zsh.org/workers/54987" target=3D"_blank" style=3D=
"background-color:transparent">workers/54987</a>=C2=A0but=C2=A0A06assign.ze=
st=C2=A0fails neither with my original patch nor when I rebase it onto HEAD=
.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
With your patch:<br>
<br>
Src/zsh -f<br>
% setopt typesettounset<br>
% typeset -T VAR var<br>
% () { typeset -i var; typeset -g -U VAR }<br>
% echo $VAR<br>
<br>
% echo $+VAR<br>
0<br>
% () { typeset -i var; typeset -g -U VAR=3D&#39;a:a:b&#39; }<br>
% () { typeset -i var; typeset -g -U VAR=3D&#39;a:a:b&#39;; typeset -p VAR =
}<br>
zsh: bus error=C2=A0 Src/zsh -f<br>
<br>
It crashes on &quot;typeset -p&quot; rather than on the assignment itself.<=
br>
Without your patch, the above does not crash (but your original<br>
example does).<br></blockquote><div><br></div><div>I don&#39;t get a bus er=
ror but a segmentation fault and it&#39;s not caused by the last &quot;type=
set -p VAR&quot; but by the &quot;typeset -g -U VAR=3D&#39;a:a:b&#39;&quot;=
 that precedes=C2=A0it. In fact the following is enough to trigger the=C2=
=A0<span style=3D"background-color:transparent">segmentation fault:</span><=
/div><div><br></div><div><font face=3D"monospace">% setopt typesettounset<b=
r>% typeset -T VAR var<br>% typeset -U VAR=3D&#39;a:a:b&#39;<br>% typeset -=
U VAR=3D&#39;a:a:b&#39;<br></font></div><div><font face=3D"monospace">zsh: =
segmentation fault</font></div><div><br></div><div>I figured that the issue=
, or at least one of the issues, was <a href=3D"https://zsh.org/workers/550=
20">workers/55020</a>. After rebasing this patch onto that one (see updated=
 patch below), the problem goes away.</div><div><br></div><div>-=C2=A0<a hr=
ef=3D"https://github.com/paltherr/zsh/compare/dont-segfault-when-uniquifyin=
g-hidden-tied-arrays-start...paltherr:zsh:dont-segfault-when-uniquifying-hi=
dden-tied-arrays" target=3D"_blank">Don&#39;t segfault when uniquifying hid=
den tied arrays</a></div><br></div><div class=3D"gmail_quote gmail_quote_co=
ntainer">Philippe</div><div class=3D"gmail_quote gmail_quote_container"><br=
></div></div>

--000000000000dc871f06573aab42--
--000000000000dc872106573aab44
Content-Type: text/plain; charset="US-ASCII"; 
	name="dont-segfault-when-uniquifying-hidden-tied-arrays.txt"
Content-Disposition: attachment; 
	filename="dont-segfault-when-uniquifying-hidden-tied-arrays.txt"
Content-Transfer-Encoding: base64
Content-ID: <f_mrwnme3c0>
X-Attachment-Id: f_mrwnme3c0

ZGlmZiAtLWdpdCBhL1NyYy9idWlsdGluLmMgYi9TcmMvYnVpbHRpbi5jCmluZGV4IDYxZDJhMjcz
MC4uNGEwZWJhNjcxIDEwMDY0NAotLS0gYS9TcmMvYnVpbHRpbi5jCisrKyBiL1NyYy9idWlsdGlu
LmMKQEAgLTIyNTMsNyArMjI1Myw2IEBAIHR5cGVzZXRfc2luZ2xlKGNoYXIgKmNuYW1lLCBjaGFy
ICpwbmFtZSwgUGFyYW0gcG0sIGludCBmdW5jLAogCSAgICByZXR1cm4gTlVMTDsKIAl9CiAJaWYg
KChvbiAmIFBNX1VOSVFVRSkgJiYgIShwbS0+bm9kZS5mbGFncyAmIFBNX1JFQURPTkxZICYgfm9m
ZikpIHsKLQkgICAgUGFyYW0gYXBtOwogCSAgICBjaGFyICoqeDsKIAkgICAgaWYgKFBNX1RZUEUo
cG0tPm5vZGUuZmxhZ3MpID09IFBNX0FSUkFZKSB7CiAJCXggPSAoKnBtLT5nc3UuYS0+Z2V0Zm4p
KHBtKTsKQEAgLTIyNjQsMTAgKzIyNjMsMTAgQEAgdHlwZXNldF9zaW5nbGUoY2hhciAqY25hbWUs
IGNoYXIgKnBuYW1lLCBQYXJhbSBwbSwgaW50IGZ1bmMsCiAJCSAgICAoKnBtLT5nc3UuYS0+c2V0
Zm4pKHBtLCB4KTsKIAkJfSBlbHNlIGlmIChwbS0+ZW5hbWUgJiYgeCkKIAkJICAgIGFycmZpeGVu
dihwbS0+ZW5hbWUsIHgpOwotCSAgICB9IGVsc2UgaWYgKFBNX1RZUEUocG0tPm5vZGUuZmxhZ3Mp
ID09IFBNX1NDQUxBUiAmJiBwbS0+ZW5hbWUgJiYKLQkJICAgICAgIChhcG0gPQotCQkJKFBhcmFt
KSBwYXJhbXRhYi0+Z2V0bm9kZShwYXJhbXRhYiwgcG0tPmVuYW1lKSkpIHsKLQkJeCA9ICgqYXBt
LT5nc3UuYS0+Z2V0Zm4pKGFwbSk7CisJICAgIH0gZWxzZSBpZiAoUE1fVFlQRShwbS0+bm9kZS5m
bGFncykgPT0gUE1fU0NBTEFSICYmIHBtLT5lbmFtZSkgeworCQl4ID0gKihwbS0+bm9kZS5mbGFn
cyAmIFBNX1NQRUNJQUwKKwkJICAgICAgPyAoY2hhciAqKiopcG0tPnUuZGF0YQorCQkgICAgICA6
ICgoc3RydWN0IHRpZWRkYXRhICopcG0tPnUuZGF0YSktPmFycnB0cik7CiAJCXVuaXFhcnJheSh4
KTsKIAkJaWYgKHgpCiAJCSAgICBhcnJmaXhlbnYocG0tPm5vZGUubmFtLCB4KTsKZGlmZiAtLWdp
dCBhL1Rlc3QvQjAydHlwZXNldC56dHN0IGIvVGVzdC9CMDJ0eXBlc2V0Lnp0c3QKaW5kZXggN2Jj
NDRkYmRjLi4zYmRkMzZiMzIgMTAwNjQ0Ci0tLSBhL1Rlc3QvQjAydHlwZXNldC56dHN0CisrKyBi
L1Rlc3QvQjAydHlwZXNldC56dHN0CkBAIC0zMjksNiArMzI5LDIwIEBACiA+bG9jYWwgdW5pcXVl
IHRpZWQgYXJyYXkgU0NBTEFSCiA+YXJyYXkgbG9jYWwgdGllZCBTQ0FMQVIgYXJyYXkKIAorIHR5
cGVzZXQgLVQgVkFSIHZhcj0oYSBiIGMgYiBhKQorICgpIHsKKyAgIHR5cGVzZXQgLWkgdmFyPTEK
KyAgIHR5cGVzZXQgLWcgLVUgVkFSCisgICB0eXBlc2V0IC1wIFZBUiB2YXIKKyB9CisgdHlwZXNl
dCAtcCBWQVIgdmFyCiswOlJlZ3Jlc3Npb24gdGVzdCBmb3Igbm90IHNlZ2ZhdWx0aW5nIHdoZW4g
dW5pcXVpZnlpbmcgYSBoaWRkZW4gdGllZCBhcnJheQorRjpCVUc6VGhlIGlubmVyICJ0eXBlc2V0
IC1wIFZBUiIgc2hvdWxkIGNvbnRhaW4gdGhlIHZhbHVlIG9mIHRoZSBvdXRlciAidmFyIgorPnR5
cGVzZXQgLWcgLVVUIFZBUiB2YXI9MQorPnR5cGVzZXQgLWkgdmFyPTEKKz50eXBlc2V0IC1VVCBW
QVIgdmFyPSggYSBiIGMgKQorPnR5cGVzZXQgLWFUIFZBUiB2YXI9KCBhIGIgYyApCisKICB0eXBl
c2V0IC1UIFNDQUxBUiBhcnJheQogIHR5cGVzZXQgK1QgU0NBTEFSCiAxOlVudHlpbmcgaXMgcHJv
aGliaXRlZAo=
--000000000000dc872106573aab44--