diff --git a/NEWS b/NEWS index a1ffbb7b5..37e6c276a 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,18 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2021-09-13: + +- Fixed a bug introduced in 93u+ 2012-02-07 that caused the 'printf' builtin + (and its 'print -f' equivalent) to fail to recognise integer arguments with a + leading zero as octal numbers. For example, 'printf "%d\n" 010' now once + again outputs '8' instead of '10'. + +- Disable the POSIX arithmetic context while running a command substitution + invoked from within an arithmetic expression. This fixes a bug that caused + integer arguments with a leading zero to be incorrectly interpreted as octal + numbers in non-POSIX arithmetic contexts within such command substitutions. + 2021-09-12: - When invoking a script without an interpreter/hashbang path on Linux and diff --git a/src/cmd/ksh93/COMPATIBILITY b/src/cmd/ksh93/COMPATIBILITY index 94154d6b6..a029ed241 100644 --- a/src/cmd/ksh93/COMPATIBILITY +++ b/src/cmd/ksh93/COMPATIBILITY @@ -151,6 +151,11 @@ For more details, see the NEWS file and for complete details, see the git log. correctly negates another '!', e.g., [[ ! ! 1 -eq 1 ]] now returns 0/true. Note that this has always been the case for 'test'/'['. +28. In the 'printf' builtin (and the 'print -f' equivalent), numeric + arguments with a leading zero are now once again recognized as octal + numbers as in ksh93 versions before 2012-02-07, and as POSIX requires. + For example, 'printf "%d\n" 010' now once again outputs '8'. + ____________________________________________________________________________ KSH-93 VS. KSH-88 diff --git a/src/cmd/ksh93/bltins/print.c b/src/cmd/ksh93/bltins/print.c index 26808dc53..b65b4493e 100644 --- a/src/cmd/ksh93/bltins/print.c +++ b/src/cmd/ksh93/bltins/print.c @@ -882,7 +882,9 @@ static int extend(Sfio_t* sp, void* v, Sffmt_t* fe) } break; default: + shp->inarith = 1; /* POSIX compliance: recognize octal constants, e.g. printf '%d\n' 010 */ d = sh_strnum(argp,&lastchar,0); + shp->inarith = 0; if(doutpool); sh_sigcheck(shp); @@ -591,6 +592,9 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) { if(comsub) { + /* a comsub within an arithmetic expression must not itself be in an arithmetic context */ + save_inarith = shp->inarith; + shp->inarith = 0; /* disable job control */ shp->spid = 0; sp->jobcontrol = job.jobcontrol; @@ -734,6 +738,8 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) sh_close(sp->tmpfd); } shp->fdstatus[1] = sp->fdstatus; + /* restore POSIX arithmetic context flag */ + shp->inarith = save_inarith; } if(!shp->subshare) { diff --git a/src/cmd/ksh93/tests/arith.sh b/src/cmd/ksh93/tests/arith.sh index 8e33b2ce5..96171efc0 100755 --- a/src/cmd/ksh93/tests/arith.sh +++ b/src/cmd/ksh93/tests/arith.sh @@ -876,5 +876,27 @@ then fi unset got +# ====== +# https://github.com/ksh93/ksh/issues/326 +for m in u d i o x X +do + case $m in + o) exp="10;21;32;" ;; + x) exp="8;11;1a;" ;; + X) exp="8;11;1A;" ;; + *) exp="8;17;26;" ;; + esac + got=${ printf "%$m;" 010 021 032; } + [[ $got == "$exp" ]] || err_exit "printf %$m does not recognize octal arguments" \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +done + +# https://github.com/ksh93/ksh/issues/326#issuecomment-917707463 +exp=18 +got=$(( $(integer x; x=010; echo $x) + 010 )) +# ^^^ decimal ^^^ octal +[[ $got == "$exp" ]] || err_exit 'Integer with leading zero incorrectly interpreted as octal in non-POSIX arith context' \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" + # ====== exit $((Errors<125?Errors:125))