1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

Honour attribs for assignments preceding sp. builtins, POSIX functs

After the previous commit, one inconsistency was left. Assignments
preceding special built-ins and POSIX functions (which persist past
the command :-/) caused pre-existing attributes of the respective
variables to be cleared.

$ (f() { typeset -p n; }; typeset -i n; n=3+4 f)
n=3+4

(expected output: 'typeset -i n=7')

This problem was introduced shortly before the release of ksh 93u+,
in version 2012-05-04, by adding these lines of code to the code
for processing preceding assignments in sh_exec():

src/cmd/ksh93/sh/xec.c:
1055:	if(np)
1056:		flgs |= NV_UNJUST;

So, for special and declaration commands and POSIX functions, the
NV_UNJUST flag is passed to nv_open(). In older ksh versions, this
flag cleared justify attributes only, but in early 2012 it was
repurposed to clear *all* attributes -- without changing the name
or the relevant comment in name.h, which are now both misleading.

The reason for setting this flag in xec.c was to deal with some
bugs in 'typeset'. Removing those two lines causes regressions:

  attributes.sh[316]: FAIL: typeset -L should not preserve old attributes
  attributes.sh[322]: FAIL: typeset -R should not preserve old attributes
  attributes.sh[483]: FAIL: typeset -F after typeset -L fails
  attributes.sh[488]: FAIL: integer attribute not cleared for subsequent typeset

Those are all typeset regressions, which suggests this fix was
relevant to typeset only. This is corroborated by the relevant
AT&T ksh93/RELEASE entry:

12-04-27  A bug in which old attributes were not cleared when
	  assigning a value using typeset has been fixed.

So, to fix this 2012 regression without reintroducing the typeset
regressions, we need to set the NV_UNJUST flag for invocations of
the typeset family of commands only. This is changed in xec.c.

While we're at it, we might as well rename that little-used flag to
something that reflects its current purpose: NV_UNATTR.
This commit is contained in:
Martijn Dekker 2022-06-03 22:51:35 +01:00
parent 75b247cce2
commit 1184b2ade9
6 changed files with 21 additions and 6 deletions

2
NEWS
View file

@ -9,7 +9,7 @@ Any uppercase BUG_* names are modernish shell bug IDs.
a parent ksh through the environment to be corrupted.
- Fixed a bug where invocation-local assignments preceding a built-in or
external command or ksh function call did not honour their pre-existing
external command or function call did not honour their pre-existing
attributes set by typeset (such as -i or -F) in certain cases.
2022-06-01:

View file

@ -128,7 +128,7 @@ struct Ufunction
#define NV_TYPE 0x1000000
#define NV_STATIC 0x2000000
#define NV_COMVAR 0x4000000
#define NV_UNJUST 0x800000 /* clear justify attributes */
#define NV_UNATTR 0x800000 /* unset attributes before assignment */
#define NV_FUNCTION (NV_RJUST|NV_FUNCT) /* value is shell function */
#define NV_FPOSIX NV_LJUST /* POSIX function semantics */
#define NV_FTMP NV_ZFILL /* function source in tmpfile */

View file

@ -1300,7 +1300,7 @@ void nv_delete(Namval_t* np, Dt_t *root, int flags)
* If <flags> & NV_NOREF then don't follow reference
* If <flags> & NV_NOFAIL then don't generate an error message on failure
* If <flags> & NV_STATIC then unset before an assignment
* If <flags> & NV_UNJUST then unset attributes before assignment
* If <flags> & NV_UNATTR then unset attributes before assignment
* SH_INIT is only set while initializing the environment
*/
Namval_t *nv_open(const char *name, Dt_t *root, int flags)
@ -1499,7 +1499,7 @@ skip:
c = msg==e_aliname? 0: (append | (flags&NV_EXPORT));
if(isref)
nv_offattr(np,NV_REF);
if(!append && (flags&NV_UNJUST))
if(!append && (flags&NV_UNATTR))
{
if(!np->nvfun)
_nv_unset(np,NV_EXPORT);

View file

@ -1052,11 +1052,10 @@ int sh_exec(register const Shnode_t *t, int flags)
else if(checkopt(com,'a'))
flgs |= NV_IARRAY;
}
if(np)
flgs |= NV_UNJUST;
if(np && np->nvalue.bfp==SYSTYPESET->nvalue.bfp)
{
/* command calls b_typeset(); treat as a typeset variant */
flgs |= NV_UNATTR; /* unset previous attributes before assigning */
if(np < SYSTYPESET || np > SYSTYPESET_END)
{
sh.typeinit = np;

View file

@ -809,6 +809,10 @@ got=$(typeset -F5 num; num=3.25+4.5 "$SHELL" -c 'typeset -p num')
got=$(typeset -F5 num; num=3.25+4.5 command eval 'typeset -p num')
[[ $got == "$exp" ]] || err_exit 'assignment preceding built-in command call does not honour pre-set attributes' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
exp='typeset -F 5 num=7.75000'
got=$(typeset -F5 num; num=3.25+4.5 eval 'typeset -p num')
[[ $got == "$exp" ]] || err_exit 'assignment preceding special built-in command call does not honour pre-set attributes' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ======
exit $((Errors<125?Errors:125))

View file

@ -1287,6 +1287,18 @@ got=$(
[[ $got == "$exp" ]] || err_exit 'assignment preceding ksh function call is not correctly exported or propagated' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
exp='typeset -F 5 num=7.75000'
exp=$exp$'\n'$exp$'\n'$exp
got=$(
f1() { typeset -p num; f2; }
f2() { typeset -p num; }
typeset -F5 num
num=3.25+4.5 f1
typeset -p num
)
[[ $got == "$exp" ]] || echo 'assignment preceding POSIX function call is not correctly exported or propagated' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ======
# Over-shifting in a POSIX function should terminate the script
$SHELL <<- \EOF