From 2ecc2575d5b2227d2266dc000f74ba9f25d0b4fe Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Fri, 3 Jun 2022 11:34:34 +0100 Subject: [PATCH] Fix import of float attribute/value from environment (re: 960a1a99) Bug 1: as of 960a1a99, floating point literals were no longer recognised when importing variables from the environment. The attribute was still imported but the value reverted to zero: $ (export LC_NUMERIC=C; typeset -xF5 num=7.75; \ ksh -c 'typeset -p num') typeset -x -F 5 num=0.00000 Bug 2 (inherited from 93u+): The code that imported variable attributes from the environment only checked '.' to determine whether the float attribute should be set. It should check the current radix point instead. $ (export LC_NUMERIC=debug; typeset -xF5 num=7,75; \ ksh -c 'typeset -p num') typeset -x -i num=0 ...or, after fixing bug 1 only, the output is: typeset -x -i num=75000 src/cmd/ksh93/sh/arith.c: sh_strnum(): - When importing untrusted env vars at init time, handle not only "base#value" literals using strtonll, but also floating point literals using strtold. This fixes the bug without reallowing arbitary expressions. (re: 960a1a99) - When not initialising, use sh.radixpoint (see f0386a87) instead of '.' to help decide whether to evaluate an arith expression. src/cmd/ksh93/sh/init.c: env_import_attributes(): - Use sh.radixpoint instead of '.' to check for a decimal fraction. (This code is needed because doubles are exported as integers for ksh88 compatibility; see attstore() in name.c.) --- NEWS | 5 +++++ src/cmd/ksh93/include/version.h | 2 +- src/cmd/ksh93/sh/arith.c | 9 ++++++--- src/cmd/ksh93/sh/init.c | 6 +++--- src/cmd/ksh93/tests/attributes.sh | 12 ++++++++++++ 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 1d807a759..b9ab261ab 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,11 @@ For full details, see the git log at: https://github.com/ksh93/ksh/tree/1.0 Any uppercase BUG_* names are modernish shell bug IDs. +2022-06-03: + +- Fixed a couple of bugs that caused floating point variables imported from + a parent ksh through the environment to be corrupted. + 2022-06-01: - New 'typeset' feature inspired by bash (and zsh and mksh): the -g flag diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 7d597fae2..f03ddaca5 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -21,7 +21,7 @@ #define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */ #define SH_RELEASE_SVER "1.0.0-beta.2" /* semantic version number: https://semver.org */ -#define SH_RELEASE_DATE "2022-06-01" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2022-06-03" /* must be in this format for $((.sh.version)) */ #define SH_RELEASE_CPYR "(c) 2020-2022 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/sh/arith.c b/src/cmd/ksh93/sh/arith.c index 254be76e2..404ab3b6b 100644 --- a/src/cmd/ksh93/sh/arith.c +++ b/src/cmd/ksh93/sh/arith.c @@ -540,9 +540,12 @@ Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode) d = strtonll(str,&last,&base,-1); if(*last && sh_isstate(SH_INIT)) { - /* This call is to handle "base#value" literals if we're importing untrusted env vars. */ + /* Handle floating point or "base#value" literals if we're importing untrusted env vars. */ errno = 0; - d = strtonll(str, &last, NIL(char*), -1); + if(*last==sh.radixpoint) + d = strtold(str,&last); + else + d = strtonll(str,&last,NIL(char*),-1); } if(*last || errno) { @@ -555,7 +558,7 @@ Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode) d = 0.0; else { - if(!last || *last!='.' || last[1]!='.') + if(!last || *last!=sh.radixpoint || last[1]!=sh.radixpoint) d = arith_strval(str,&last,arith,mode); if(!ptr && *last && mode>0) { diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index 570571f64..ab1c05da4 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -2089,17 +2089,17 @@ static void env_import_attributes(char *next) /* check for floating */ char *dp, *val = nv_getval(np); strtol(val,&dp,10); - if(*dp=='.' || *dp=='e' || *dp=='E') + if(*dp==sh.radixpoint || *dp=='e' || *dp=='E') { char *lp; flag |= NV_DOUBLE; - if(*dp=='.') + if(*dp==sh.radixpoint) { strtol(dp+1,&lp,10); if(*lp) dp = lp; } - if(*dp && *dp!='.') + if(*dp && *dp!=sh.radixpoint) { flag |= NV_EXPNOTE; size = dp-val; diff --git a/src/cmd/ksh93/tests/attributes.sh b/src/cmd/ksh93/tests/attributes.sh index 025d377c5..362e8b9b6 100755 --- a/src/cmd/ksh93/tests/attributes.sh +++ b/src/cmd/ksh93/tests/attributes.sh @@ -787,5 +787,17 @@ got=${got/ -x/} [[ $got == "$exp" ]] || err_exit 'typeset -x causes zerofill width to change' \ "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +# ====== +# Check import of float attribute/value from environment +exp='typeset -x -F 5 num=7.75000' +got=$(typeset -xF5 num=7.75; "$SHELL" -c 'typeset -p num') +[[ $got == "$exp" ]] || err_exit "floating '.' attribute/value not imported correctly" \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +# try again with AST debug locale which has the comma as the radix point +exp='typeset -x -F 5 num=7,75000' +got=$(export LC_NUMERIC=debug; typeset -xF5 num=7,75; "$SHELL" -c 'typeset -p num') +[[ $got == "$exp" ]] || err_exit "floating ',' attribute/value not imported correctly" \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" + # ====== exit $((Errors<125?Errors:125))