1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix octal number arguments in printf integer arithmetic

Bug 1: POSIX requires numbers used as arguments for all the %d,
%u... in printf to be interpreted as in the C language, so
	printf '%d\n' 010
should output 8 when the posix option is on. However, it outputs 10.

This bug was introduced as a side effect of a change introduced in
the 2012-02-07 version of ksh 93u+m, which caused the recognition
of leading-zero numbers as octal in arithmetic expressions to be
disabled outside ((...)) and $((...)). However, POSIX requires
leading-zero octal numbers to be recognised for printf, too.

The change in question introduced a sh.arith flag that is set while
we're processing a POSIX arithmetic expression, i.e., one that
recognises leading-zero octal numbers.
Bug 2: Said flag is not reset in a command substitution used within
an arithmetic expression. A command substitution should be a
completely new context, so the following should both output 10:

$ ksh -c 'integer x; x=010; echo $x'
10            # ok; it's outside ((…)) so octals are not recognised
$ ksh -c 'echo $(( $(integer x; x=010; echo $x) ))'
8             # bad; $(comsub) should create new non-((…)) context

src/cmd/ksh93/bltins/print.c: extend():
- For the u, d, i, o, x, and X conversion modifiers, set the POSIX
  arithmetic context flag before calling sh_strnum() to convert the
  argument. This fixes bug 1.

src/cmd/ksh93/sh/subshell.c: sh_subshell():
- When invoking a command substitution, save and unset the POSIX
  arithmetic context flag. Restore it at the end. This fixes bug 2.

Reported-by: @stephane-chazelas
Resolves: https://github.com/ksh93/ksh/issues/326
This commit is contained in:
Martijn Dekker 2021-09-13 04:23:50 +02:00
parent 44bdb3fbfc
commit 7b5b0a5d54
8 changed files with 50 additions and 3 deletions

View file

@ -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))