mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix field splitting bug triggered by DEBUG trap
An unquoted variable expansion evaluated in a DEBUG trap action caused IFS field splitting to be deactivated in code executed after the trap action. Thanks to Koichi Nakashima for the reproducer: | v='' | trap ': $v' DEBUG | A="a b c" | set -- $A | printf '%s\n' "$@" | | Expected | | a | b | c | | Actual | | a b c src/cmd/ksh93/sh/fault.c: sh_trap(): - Remove incorrect save/restore of sh.ifstable, the internal state table for field splitting. This reverts three lines added in ksh 93t+ 2009-11-30. Analysis: As an expansion is split into fields (macro.c, lines 2367-2471), sh.ifstable is modified. If that happens within a DEBUG trap, any modifications in ifstable are undone by the restoring memccpy, leaving an inconsistent state. src/cmd/ksh93/COMPATIBILITY: - Document the DEBUG trap fixes, particularly the incorrect inheritance by subshells and functions that some scripts may now rely on because this bug is so longstanding. (re:2a835a2d
) src/cmd/ksh93/tests/basic.sh: - Add relevant tests. Resolves: https://github.com/ksh93/ksh/issues/155 TODO: add a -T (-o functrace) option as in bash, which should allow subshells and ksh-style functions to inherit DEBUG traps. P.S.: The very handy multishell repo allows us to use 'git blame' to trace the origin of the recently fixed DEBUG trap bugs. The off-by-one error causing various bugs, reverted in2a835a2d
, was introduced in ksh 93t 2008-07-25:8e947ccf
(fault.c, line 321) The incorrect check causing the exit status bug, reverted ind00b4b39
, was introduced in ksh 93t 2008-11-04:b1ade268
(fault.c, line 459) The ifstable save/restore causing the field splitting bug, reverted in this commit, was introduced in ksh 93t+ 2009-11-30:53d9f009
(fault.c, lines 440, 444, 482) So all the bugs reported in #155 were fixed by simply reverting these specific changes. I think that they are some experiments that the developers simply forgot to remove. I've suspected such a thing multiple times before. ksh93 was developed by researchers who were genius innovators, but incredibly sloppy maintainers.
This commit is contained in:
parent
e664b78f98
commit
70368c57d6
5 changed files with 70 additions and 7 deletions
|
@ -745,8 +745,9 @@ got=$(eval 'x=`for i in test; do case $i in test) true;; esac; done`' 2>&1) \
|
|||
|| err_exit "case in a for loop inside a \`comsub\` caused syntax error (got $(printf %q "$got"))"
|
||||
|
||||
# ======
|
||||
# Various DEBUG trap fixes: https://github.com/ksh93/ksh/issues/155
|
||||
|
||||
# Redirecting disabled the DEBUG trap
|
||||
# https://github.com/ksh93/ksh/issues/155 (#1)
|
||||
exp=$'LINENO: 4\nfoo\nLINENO: 5\nLINENO: 6\nbar\nLINENO: 7\nbaz'
|
||||
got=$({ "$SHELL" -c '
|
||||
PATH=/dev/null
|
||||
|
@ -760,7 +761,6 @@ got=$({ "$SHELL" -c '
|
|||
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
|
||||
|
||||
# The DEBUG trap crashed when re-trapping inside a subshell
|
||||
# https://github.com/ksh93/ksh/issues/155 (#2)
|
||||
exp=$'trap -- \': main\' EXIT\ntrap -- \': main\' ERR\ntrap -- \': main\' KEYBD\ntrap -- \': main\' DEBUG'
|
||||
got=$({ "$SHELL" -c '
|
||||
PATH=/dev/null
|
||||
|
@ -774,8 +774,20 @@ got=$({ "$SHELL" -c '
|
|||
((!(e = $?))) && [[ $got == "$exp" ]] || err_exit 'Pseudosignal trap failed when re-trapping in subshell' \
|
||||
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
|
||||
|
||||
# Field splitting broke upon evaluating an unquoted expansion in a DEBUG trap
|
||||
exp=$'a\nb\nc'
|
||||
got=$({ "$SHELL" -c '
|
||||
PATH=/dev/null
|
||||
v=""
|
||||
trap ": \$v" DEBUG
|
||||
A="a b c"
|
||||
set -- $A
|
||||
printf "%s\n" "$@"
|
||||
'; } 2>&1)
|
||||
((!(e = $?))) && [[ $got == "$exp" ]] || err_exit 'Field splitting broke after executing DEBUG trap' \
|
||||
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
|
||||
|
||||
# The DEBUG trap had side effects on the exit status
|
||||
# https://github.com/ksh93/ksh/issues/155 (#4)
|
||||
trap ':' DEBUG
|
||||
(exit 123)
|
||||
(((e=$?)==123)) || err_exit "DEBUG trap run in subshell affects exit status (expected 123, got $e)"
|
||||
|
@ -785,5 +797,46 @@ r=`exit 123`
|
|||
(((e=$?)==123)) || err_exit "DEBUG trap run in \`comsub\` affects exit status (expected 123, got $e)"
|
||||
trap - DEBUG
|
||||
|
||||
# The DEBUG trap was incorrectly inherited by subshells
|
||||
exp=$'Subshell\nDebug 1\nParentshell'
|
||||
got=$(
|
||||
trap 'echo Debug ${.sh.subshell}' DEBUG
|
||||
(echo Subshell)
|
||||
echo Parentshell
|
||||
)
|
||||
trap - DEBUG # bug compat
|
||||
[[ $got == "$exp" ]] || err_exit "DEBUG trap inherited by subshell" \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
|
||||
# The DEBUG trap was incorrectly inherited by ksh functions
|
||||
exp=$'Debug 0\nFunctionEnv\nDebug 0\nParentEnv'
|
||||
got=$(
|
||||
function myfn
|
||||
{
|
||||
echo FunctionEnv
|
||||
}
|
||||
trap 'echo Debug ${.sh.level}' DEBUG
|
||||
myfn
|
||||
echo ParentEnv
|
||||
)
|
||||
trap - DEBUG # bug compat
|
||||
[[ $got == "$exp" ]] || err_exit "DEBUG trap inherited by ksh function" \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
|
||||
# Make sure the DEBUG trap is still inherited by POSIX functions
|
||||
exp=$'Debug 0\nDebug 1\nFunction\nDebug 0\nNofunction'
|
||||
got=$(
|
||||
myfn()
|
||||
{
|
||||
echo Function
|
||||
}
|
||||
trap 'echo Debug ${.sh.level}' DEBUG
|
||||
myfn
|
||||
echo Nofunction
|
||||
)
|
||||
trap - DEBUG # bug compat
|
||||
[[ $got == "$exp" ]] || err_exit "DEBUG trap not inherited by POSIX function" \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue