diff --git a/NEWS b/NEWS index 862a7b6ea..ffb4176d8 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,11 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2021-03-01: + +- Fixed the retention of size attributes when 'readonly' or 'typeset -r' + was applied to an existing variable. + 2021-02-26: - Fixed three long-standing bugs with tab completion in the emacs editor: diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c index 709879eb0..316a6bb3c 100644 --- a/src/cmd/ksh93/bltins/typeset.c +++ b/src/cmd/ksh93/bltins/typeset.c @@ -835,7 +835,12 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp { if(np->nvfun && !nv_isarray(np) && name[strlen(name)-1]=='.') newflag |= NV_NODISC; - nv_newattr (np, newflag&~NV_ASSIGN,tp->argnum); + if(flag&NV_RDONLY && !tp->argnum && !(flag&(NV_INTEGER|NV_BINARY)) && !(flag&(NV_LJUST|NV_RJUST|NV_ZFILL))) + /* New requested attribute(s) are readonly, have a provided or defaulted size of 0, and are + not a string justification nor numeric. Justified or binary strings can have a size of 0. */ + nv_newattr(np, newflag&~NV_ASSIGN, np->nvsize); + else + nv_newattr(np, newflag&~NV_ASSIGN, tp->argnum); } } if(tp->help && !nv_isattr(np,NV_MINIMAL|NV_EXPORT)) diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 70b696acd..10a84130f 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -20,7 +20,7 @@ #define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */ #define SH_RELEASE_SVER "1.0.0-alpha" /* semantic version number: https://semver.org */ -#define SH_RELEASE_DATE "2021-02-26" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2021-03-01" /* must be in this format for $((.sh.version)) */ #define SH_RELEASE_CPYR "(c) 2020-2021 Contributors to ksh " SH_RELEASE_FORK /* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */ diff --git a/src/cmd/ksh93/tests/attributes.sh b/src/cmd/ksh93/tests/attributes.sh index 73cb5f236..d32d16117 100755 --- a/src/cmd/ksh93/tests/attributes.sh +++ b/src/cmd/ksh93/tests/attributes.sh @@ -526,16 +526,16 @@ typeset -A expect=( [F12]='typeset -x -r -F 12 foo' [H]='typeset -x -r -H foo' [L]='typeset -x -r -L 0 foo' -# [L17]='typeset -x -r -L 17 foo' # TODO: outputs 'typeset -x -r -L 0 foo' + [L17]='typeset -x -r -L 17 foo' [Mtolower]='typeset -x -r -l foo' [Mtoupper]='typeset -x -r -u foo' [R]='typeset -x -r -R 0 foo' -# [R17]='typeset -x -r -R 17 foo' # TODO: outputs 'typeset -x -r -R 0 foo' + [R17]='typeset -x -r -R 17 foo' [X17]='typeset -x -r -X 17 foo' [S]='typeset -x -r foo' [T]='typeset -x -r foo' [Z]='typeset -x -r -Z 0 -R 0 foo' -# [Z13]='typeset -x -r -Z 13 -R 13 foo' # TODO: outputs 'typeset -x -r -Z 0 -R 0 foo' + [Z13]='typeset -x -r -Z 13 -R 13 foo' ) for flag in "${!expect[@]}" do unset foo @@ -637,5 +637,27 @@ exp=$'00000\n000\n0000000' [[ $got == "$exp" ]] || err_exit 'failed to zero-fill zero' \ "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +# ====== +# Applying the readonly attribute to an existing variable having a non-numeric attribute with a +# size such as -L, -R, or -Z would be set to 0 when it should have maintained the old size unless +# -L/R/Z existed as part of the new attributes being applied then its supplied size or default +# size of 0 should be used. +[[ $(typeset -L4 x; readonly x; typeset -p x) == 'typeset -r -L 4 x' ]] || err_exit "readonly apply failed to carry oldsize for typeset -r -L 4 x." +[[ $(typeset -L4 x; typeset -r x; typeset -p x) == 'typeset -r -L 4 x' ]] || err_exit "typeset -r apply failed to carry oldsize for typeset -r -L 4 x." + +[[ $(typeset -R4 x; readonly x; typeset -p x) == 'typeset -r -R 4 x' ]] || err_exit "readonly apply failed to carry oldsize for typeset -r -R 4 x." +[[ $(typeset -R4 x; typeset -r x; typeset -p x) == 'typeset -r -R 4 x' ]] || err_exit "typeset -r apply failed to carry oldsize for typeset -r -R 4 x." + +[[ $(typeset -Z4 x; readonly x; typeset -p x) == 'typeset -r -Z 4 -R 4 x' ]] || err_exit "readonly apply failed to carry oldsize for typeset -r -Z 4 -R 4." +[[ $(typeset -Z4 x; typeset -r x; typeset -p x) == 'typeset -r -Z 4 -R 4 x' ]] || err_exit "typeset -r apply failed to carry oldsize for typeset -r -Z 4 -R 4." + +[[ $(typeset -bZ4 x; readonly x; typeset -p x) == 'typeset -r -b -Z 4 -R 4 x' ]] || err_exit "readonly apply failed to carry oldsize for typeset -r -b -Z 4 -R 4." +[[ $(typeset -bZ4 x; typeset -r x; typeset -p x) == 'typeset -r -b -Z 4 -R 4 x' ]] || err_exit "typeset -r apply failed to carry oldsize for typeset -r -b -Z 4 -R 4." + +[[ $(typeset -L4 x; typeset -rL x; typeset -p x) == 'typeset -r -L 0 x' ]] || err_exit "typeset -rL failed to set new size." +[[ $(typeset -R4 x; typeset -rR x; typeset -p x) == 'typeset -r -R 0 x' ]] || err_exit "typeset -rR failed to set new size." +[[ $(typeset -Z4 x; typeset -rZ x; typeset -p x) == 'typeset -r -Z 0 -R 0 x' ]] || err_exit "typeset -rZ failed to set new size." +[[ $(typeset -bZ4 x; typeset -rbZ x; typeset -p x) == 'typeset -r -b -Z 0 -R 0 x' ]] || err_exit "typeset -rbZ failed to set new size." + # ====== exit $((Errors<125?Errors:125))