tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bug in sh, probably, with test case



On Thu, Dec 20, 2012 at 10:08:15PM +0000, David Laight wrote:
> On Thu, Dec 20, 2012 at 03:20:42PM -0500, Richard Hansen wrote:
> > 
> >   "a${PWD+"*"}" also expands to the string a*, but interestingly it was 
> > the string "a"*"" before the quote removal step (none of those double 
> > quotes are themselves quoted according to the quoting rules, so they are 
> > all eliminated during the quote removal step)
> 
> I'm fairly sure netbsd's sh doesn't expand that like that.
> IIRC the inner string is expanded separately with its own quoting (starting
> with no quotes). The unwanted 'ability' to generate multiple tokens
> probably comes from the necessity of expanding "$@".
> 
> I think expanding "a${PWD+'*'}" should give a*, not the a'*' you'd get
> from quote removal of "a'*'".
> 
> There is probably a nice simple apparrant 'fix' that makes something
> else break 'big time'.

I think I've worked out why it is fubar.
expand.c contains two relevant (mutually recursive) functions argstr()
and evalvar().
The EXP_IFS_SPLIT flag to both controls IFS splitting.
It is clear on the initial call to argstr() (reading the input file), so 
is conditionally set when argstr() calls evalvar().

evalvar() passes its current state back into argstr() when evaluating
${foo+string} - since 'string' is subject to IFS splitting.

However is 'string' contains variables, evalvar() must not set EXP_IFS_SPLIT
when it calls back into argstr() unless it was set on entry - this differs
from the original call.

Fixing needs an extra flag that controls whether evalvar() is allowed
to set EXP_IFS_SPLIT.
The least obtrusive would be an EXT_DISABLE_IFS_SPLIT set by evalvar()
on the calls back to argstr().

Might be worth looking at how it has been fixed in other versions of ash.
Not sure I've got time until sunday week.

        David

-- 
David Laight: david%l8s.co.uk@localhost


Home | Main Index | Thread Index | Old Index