From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5432 invoked by alias); 10 Jan 2015 17:25:50 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 34212 Received: (qmail 27687 invoked from network); 10 Jan 2015 17:25:48 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=Kc1larcG c=1 sm=1 tr=0 a=FT8er97JFeGWzr5TCOCO5w==:117 a=kj9zAlcOel0A:10 a=q2GGsy2AAAAA:8 a=oR5dmqMzAAAA:8 a=-9mUelKeXuEA:10 a=YNv0rlydsVwA:10 a=hfkJEQsuzPRffxSpPjsA:9 a=CjuIK1q_8ugA:10 From: Bart Schaefer Message-id: <150110092530.ZM28263@torch.brasslantern.com> Date: Sat, 10 Jan 2015 09:25:30 -0800 In-reply-to: Comments: In reply to Mikael Magnusson "Re: Crash when exporting scalar without value and getsparam fails" (Jan 10, 9:09am) References: <150109225231.ZM24510@torch.brasslantern.com> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh workers Subject: Re: Crash when exporting scalar without value and getsparam fails MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Jan 10, 9:09am, Mikael Magnusson wrote: } Subject: Re: Crash when exporting scalar without value and getsparam fails } } So just to check, I tried both of the things anyway. With setting it } to "" on failure, it gets exported as the empty string, and this } if (!(pm->node.flags & PM_UNSET) && !pm->env && !value) { } void *foo = getsparam(pname); } if (foo) } addenv(pm, foo); } } } } results in almost the correct behaviour, except that after unsetting } the parameter and setting it again, it still gets exported. (This } doesn't happen for other parameters). Maybe bin_unset or unsetparam_pm } has some special code that needs changing too? I think the whole problem is that the PM_UNSET flag is for some reason not set, even though the parameter is in fact unset. This is happening at line 2075: pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET); That line is never executed for e.g. "export FOO", because of this up at line 1937: /* * We need to compare types with an existing pm if special, * even if that's unset */ if (pm && (pm->node.flags & PM_SPECIAL)) usepm = 1; Consequently ... diff --git a/Src/builtin.c b/Src/builtin.c index 8abe728..8dee8f9 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1935,7 +1935,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), * even if that's unset */ if (pm && (pm->node.flags & PM_SPECIAL)) - usepm = 1; + usepm = 2; /* indicate that we preserve the PM_UNSET flag */ /* * Don't use an existing param if @@ -2072,7 +2072,11 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), arrfixenv(pm->node.nam, x); } } - pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET); + if (usepm == 2) /* do not change the PM_UNSET flag */ + pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~off; + else + pm->node.flags = (pm->node.flags | + (on & ~PM_READONLY)) & ~(off | PM_UNSET); if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) { if (typeset_setwidth(cname, pm, ops, on, 0)) return NULL;