mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
arithmetic: Fix the octal leading zero mess (#337)
In C/POSIX arithmetic, a leading 0 denotes an octal number, e.g. 010 == 8. But this is not a desirable feature as it can cause problems with processing things like dates with a leading zero. In ksh, you should use 8#10 instead ("10" with base 8). It would be tolerable if ksh at least implemented it consistently. But AT&T made an incredible mess of it. For anyone who is not intimately familiar with ksh internals, it is inscrutable where arithmetic evaluation special-cases a leading 0 and where it doesn't. Here are just some of the surprises/inconsistencies: 1. The AT&T maintainers tried to honour a leading 0 inside of ((...)) and $((...)) and not for arithmetic contexts outside it, but even that inconsistency was never quite consistent. 2. Since 2010-12-12, $((x)) and $(($x)) are different: $ /bin/ksh -c 'x=010; echo $((x)) $(($x))' 10 8 That's a clear violation of both POSIX and the principle of least astonishment. $((x)) and $(($x)) should be the same in all cases. 3. 'let' with '-o letoctal' acts in this bizarre way: $ set -o letoctal; x=010; let "y1=$x" "y2=010"; echo $y1 $y2 10 8 That's right, 'let y=$x' is different from 'let y=010' even when $x contains the same string value '010'! This violates established shell grammar on the most basic level. This commit introduces consistency. By default, ksh now acts like mksh and zsh: the octal leading zero is disabled in all arithmetic contexts equally. In POSIX mode, it is enabled equally. The one exception is the 'let' built-in, where this can still be controlled independently with the letoctal option as before (but, because letoctal is synched with posix when switching that on/off, it's consistent by default). We're also removing the hackery that causes variable expansions for the 'let' builtin to be quietly altered, so that 'x=010; let y=$x' now does the same as 'let y=010' even with letoctal on. Various files: - Get rid of now-redundant sh.inarith (shp->inarith) flag, as we're no longer distinguishing between being inside or outside ((...)). src/cmd/ksh93/sh/arith.c: - arith(): Let disabling POSIX octal constants by skipping leading zeros depend on either the letoctal option being off (if we're running the "let" built-in") or the posix option being off. - sh_strnum(): Preset a base of 10 for strtonll(3) depending on the posix or letoctal option being off, not on the sh.inarith flag. src/cmd/ksh93/include/argnod.h, src/cmd/ksh93/sh/args.c, src/cmd/ksh93/sh/macro.c: - Remove astonishing hackery that violated shell grammar for 'let'. src/cmd/ksh93/sh/name.c (nv_getnum()), src/cmd/ksh93/sh/nvdisc.c (nv_getn()): - Remove loops for skipping leading zeroes that included a broken check for justify/zerofill attributes, thereby fixing this bug: $ typeset -Z x=0x15; echo $((x)) -ksh: x15: parameter not set Even if this code wasn't redundant before, it is now: sh_arith() is called immediately after the removed code and it ignores leading zeroes via sh_strnum() and strtonll(3). Resolves: https://github.com/ksh93/ksh/issues/334
This commit is contained in:
parent
257eea612a
commit
c734568b02
14 changed files with 86 additions and 93 deletions
18
NEWS
18
NEWS
|
@ -3,6 +3,19 @@ For full details, see the git log at: https://github.com/ksh93/ksh
|
|||
|
||||
Any uppercase BUG_* names are modernish shell bug IDs.
|
||||
|
||||
2021-11-16:
|
||||
|
||||
- By default, arithmetic expressions in ksh no longer interpret a number
|
||||
with a leading zero as octal in any context. Use 8#octalnumber instead.
|
||||
Before, ksh would arbitrarily recognize the leading octal zero in some
|
||||
contexts but not others, e.g., both of:
|
||||
$ x=010; echo "$((x)), $(($x))"
|
||||
$ set -o letoctal; x=010; let y=$x z=010; echo "$y, $z"
|
||||
would output '10, 8'. These now output '10, 10' and '8, 8', respectively.
|
||||
Arithmetic expressions now also behave identically within and outside
|
||||
((...)) and $((...)). Setting the --posix compliance option turns on the
|
||||
recognition of the leading octal zero for all arithmetic contexts.
|
||||
|
||||
2021-11-15:
|
||||
|
||||
- In arithmetic evaluation, the --posix compliance option now disables the
|
||||
|
@ -42,11 +55,6 @@ 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue