From a61430f1b536a7ebdbac351e3e5695dc1132e7df Mon Sep 17 00:00:00 2001 From: hyenias <58673227+hyenias@users.noreply.github.com> Date: Tue, 2 Mar 2021 22:26:39 -0500 Subject: [PATCH] Readonly attribute size fix (#201) Corrected the size of attribute(s) being overwritten with 0 when 'readonly' or 'typeset -r' was applied to an existing variable. Since one cannot set any attributes with the 'readonly' command, its function call to setall() needs to be adjusted to acquire the current size from the old size or existing size of the variable. A plain 'typeset -r' is the same as 'readonly' in that it needs to load the old size as its current size for use in the subsequent to call to nv_newattr(). src/cmd/ksh93/bltins/typeset.c: setall(): - Both 'readonly' and 'typeset -r' end up calling setall(). setall() has full visibility into all user supplied values and existing values that are needed to differentiate whereas name.c newattr() acquires combined state flags. - Added a conditional check if the readonly flag was requested by user then meets the criteria of having present size of 0, cannot be a numeric nor binary string, and is void of presence of any of the justified string attributes. - -L/R/Z justified string attributes if not given a value default to a size of 0 which means to autosize. A binary string can have a fixed field size, e.g. -bZ. The present of any of the -L/R/Z attribules means that current size is valid and should be used even if it is zero. src/cmd/ksh93/tests/attributes.sh: - Added various tests to capture and reiterate that 'readonly' should be equivalent to 'typeset -r' and applying them should not alter the previous existing size unless additional attributes are set along with typeset command. --- NEWS | 5 +++++ src/cmd/ksh93/bltins/typeset.c | 7 ++++++- src/cmd/ksh93/include/version.h | 2 +- src/cmd/ksh93/tests/attributes.sh | 28 +++++++++++++++++++++++++--- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 862a7b6eac7a..ffb4176d88b8 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 709879eb0208..316a6bb3cf9a 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 70b696acd614..10a84130f3dc 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 73cb5f236d1f..d32d1611729a 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))