[-- Attachment #1: Type: text/plain, Size: 242 bytes --] I have included the file that reproduces the bug with `zsh -f` and the result of running it in https://gist.github.com/NightMachinary/32689e786a3b7f5865a042d49b884b57 <https://gist.github.com/NightMachinary/32689e786a3b7f5865a042d49b884b57>.
2019-08-08 20:38:05 +0430, Aryn Starr:
> I have included the file that reproduces the bug with `zsh -f` and the result of running it in https://gist.github.com/NightMachinary/32689e786a3b7f5865a042d49b884b57 <https://gist.github.com/NightMachinary/32689e786a3b7f5865a042d49b884b57>.
Please try and make sure your bug reports are self-contained.
The zsh ML has been around for decades and along with its
archives will probably be around for several more decades, but
we can't tell much about github (that link may become invalid
at any time).
We should also not have to fire up a web browser to figure out
what the bug is about.
Now, that being said, as discussed on U&L it looks like a bug
indeed and a shorter reproducer is:
$ zsh -xc 'v=1; f() { local v; v=2 true; }; f; typeset -p v'
+zsh:1> v=1
+zsh:1> f
+f:0> local v
+f:0> v=2 +f:0> true
+zsh:1> typeset -p v
zsh:typeset:1: no such variable: v
Most likely, that's the "v=2 true" (where "true" is a builtin) that ends up
unsetting the "v" from the global scope.
--
Stephane
[-- Attachment #1: Type: text/plain, Size: 1577 bytes --] I’ll keep that in mind. I’m very new to mailing lists, and I haven’t found any resource on properly using mailing lists, unfortunately. And yes, if we use an external program (or even just `command true`), the bug won’t appear. Though it does with function calls, too: zsh -c 'v=1; ff() command true ; f() { local v; v=2 ff; }; f; typeset -p v' > On Aug 14, 2019, at 2:07 PM, Stephane Chazelas <stephane.chazelas@gmail.com> wrote: > > 2019-08-08 20:38:05 +0430, Aryn Starr: >> I have included the file that reproduces the bug with `zsh -f` and the result of running it in https://gist.github.com/NightMachinary/32689e786a3b7f5865a042d49b884b57 <https://gist.github.com/NightMachinary/32689e786a3b7f5865a042d49b884b57>. > > Please try and make sure your bug reports are self-contained. > The zsh ML has been around for decades and along with its > archives will probably be around for several more decades, but > we can't tell much about github (that link may become invalid > at any time). > > We should also not have to fire up a web browser to figure out > what the bug is about. > > Now, that being said, as discussed on U&L it looks like a bug > indeed and a shorter reproducer is: > > $ zsh -xc 'v=1; f() { local v; v=2 true; }; f; typeset -p v' > +zsh:1> v=1 > +zsh:1> f > +f:0> local v > +f:0> v=2 +f:0> true > +zsh:1> typeset -p v > zsh:typeset:1: no such variable: v > > Most likely, that's the "v=2 true" (where "true" is a builtin) that ends up > unsetting the "v" from the global scope. > > -- > Stephane
On Wed, 2019-08-14 at 10:37 +0100, Stephane Chazelas wrote: > 2019-08-08 20:38:05 +0430, Aryn Starr: > Now, that being said, as discussed on U&L it looks like a bug > indeed and a shorter reproducer is: > > $ zsh -xc 'v=1; f() { local v; v=2 true; }; f; typeset -p v' > +zsh:1> v=1 > +zsh:1> f > +f:0> local v > +f:0> v=2 +f:0> true > +zsh:1> typeset -p v > zsh:typeset:1: no such variable: v > > Most likely, that's the "v=2 true" (where "true" is a builtin) that ends up > unsetting the "v" from the global scope. Yes, the saved version of "v" that we restore after the builtin is missing the pointer back to the version of v in the enclosing scope. So it's not only not shown as set, it will leak memory. This simply preserves that pointer in the copy, but this assumes we've correctly blocked off the old parameter from being altered inside the function scope --- if we haven't that preserved old pointer is going to get us into trouble. However, if we haven't that's already a bug, so this shouldn't make things worse. pws diff --git a/Src/params.c b/Src/params.c index 1499e3a40..a253a9d8e 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1124,8 +1124,10 @@ copyparam(Param tpm, Param pm, int fakecopy) tpm->base = pm->base; tpm->width = pm->width; tpm->level = pm->level; - if (!fakecopy) + if (!fakecopy) { + tpm->old = pm->old; tpm->node.flags &= ~PM_SPECIAL; + } switch (PM_TYPE(pm->node.flags)) { case PM_SCALAR: tpm->u.str = ztrdup(pm->gsu.s->getfn(pm)); diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 194c3e287..b6e85a9fe 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -2522,3 +2522,15 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888 >trailing/slashes >removed >are/removed + + foo=global-value + fn() { + local foo=function-value + foo=export-value true + print $foo + } + fn + print $foo +0:Global variables are not trashed by "foo=bar builtin" (regression test) +>function-value +>global-value
On 8/14/19, Peter Stephenson <p.stephenson@samsung.com> wrote:
> On Wed, 2019-08-14 at 10:37 +0100, Stephane Chazelas wrote:
>> 2019-08-08 20:38:05 +0430, Aryn Starr:
>> Now, that being said, as discussed on U&L it looks like a bug
>> indeed and a shorter reproducer is:
>>
>> $ zsh -xc 'v=1; f() { local v; v=2 true; }; f; typeset -p v'
>> +zsh:1> v=1
>> +zsh:1> f
>> +f:0> local v
>> +f:0> v=2 +f:0> true
>> +zsh:1> typeset -p v
>> zsh:typeset:1: no such variable: v
>>
>> Most likely, that's the "v=2 true" (where "true" is a builtin) that ends
>> up
>> unsetting the "v" from the global scope.
>
> Yes, the saved version of "v" that we restore after the builtin is
> missing the pointer back to the version of v in the enclosing scope. So
> it's not only not shown as set, it will leak memory.
>
> This simply preserves that pointer in the copy, but this assumes we've
> correctly blocked off the old parameter from being altered inside the
> function scope --- if we haven't that preserved old pointer is going to
> get us into trouble. However, if we haven't that's already a bug, so
> this shouldn't make things worse.
This got me thinking about related stuff. I guess these results are
expected, maybe even at best unspecified?
% foo=initial; foo=bar printf -v foo hello; echo $foo
initial
% set hi; argv= set hello; echo $1
hi
% set a b c; argv= shift; echo $@
a b c
% a=1; a=5 typeset a=3 b=7; echo $a$b
17
--
Mikael Magnusson