On Sat, 13 Oct 2018, oleg_komashko(a)ukr.net wrote:
Dear all,
Below is a script illustrating the problem
# creates list of all global series
function list fun1(void)
list retlist = seq(1,$nvars-1)
return retlist
end function
# identity list function
function list fun2(list a_list)
return a_list
end function
# checking function
function void fu(string name)
catch eval @name
err = $error
if err
printf "Variable %s is not defined\n", name
endif
end function
#contaminating function
function void spoil(void)
list list1 = fun1()
list list2 = fun2(list1)
end function
###### example
nulldata 20
set seed 13
x1 = normal()
# before
fu("x1")
# looking at x1
print x1
# spoiling
spoil()
# after
fu("x1")
On the first run fu("x1") does not know
global series 'x1' but after running spoil()
fu("x1") knows and evaluates x1
Thanks for the report. The primary source of mischief here is the
ability, within a function, to create a list that includes series
that were not given as arguments in any shape or form (neither as
"pointer"-form series arguments nor as members of a list argument),
by the simple expedient of referring to the series by their ID
numbers -- with the $nvars accessor providing a handy upper bound!
I've been aware of this possibility for a while but I didn't think
it was a high priority for fixing, since it seemed excessively
"tricksy" and unlikely to arise in practice.
Now it has if fact arisen, the loophole is closed in git. You can
now put into a list by ID number only series that satisfy one of
these criteria:
1. the series was given to the function via a "pointer-to-series"
argument,
2. the series was given to the function as a member of a list
argument, or
3. the series was newly defined after the function began executing.
This means that the statement in fun1() above,
list retlist = seq(1,$nvars-1)
will fail right away (since fun1 is not passed any arguments, let
alone references to series), and therefore the mischief will not get
started.
Allin