diff --git a/NEWS b/NEWS index ae9fc62e4..598b10de6 100644 --- a/NEWS +++ b/NEWS @@ -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: diff --git a/src/cmd/ksh93/include/name.h b/src/cmd/ksh93/include/name.h index 3dc73694d..7bc504edf 100644 --- a/src/cmd/ksh93/include/name.h +++ b/src/cmd/ksh93/include/name.h @@ -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 */ diff --git a/src/cmd/ksh93/sh/name.c b/src/cmd/ksh93/sh/name.c index 780fc6aa9..29dcd9c98 100644 --- a/src/cmd/ksh93/sh/name.c +++ b/src/cmd/ksh93/sh/name.c @@ -1300,7 +1300,7 @@ void nv_delete(Namval_t* np, Dt_t *root, int flags) * If & NV_NOREF then don't follow reference * If & NV_NOFAIL then don't generate an error message on failure * If & NV_STATIC then unset before an assignment - * If & NV_UNJUST then unset attributes before assignment + * If & 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); diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index 6f93055bf..cf9ca676d 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -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; diff --git a/src/cmd/ksh93/tests/attributes.sh b/src/cmd/ksh93/tests/attributes.sh index 37bcbc1ce..222ded73d 100755 --- a/src/cmd/ksh93/tests/attributes.sh +++ b/src/cmd/ksh93/tests/attributes.sh @@ -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)) diff --git a/src/cmd/ksh93/tests/functions.sh b/src/cmd/ksh93/tests/functions.sh index f8addf51e..1cffed0b3 100755 --- a/src/cmd/ksh93/tests/functions.sh +++ b/src/cmd/ksh93/tests/functions.sh @@ -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