From 2315f6687a16b20f8b50b7a6c8bd134034b618ed Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Wed, 24 Jun 2020 19:38:09 +0200 Subject: [PATCH] Add regress test for fixed BUG_KUNSETIFS (re: 6f0e008c, 7b994b6a) Modernish is no longer detecting BUG_KUNSETIFS, as I've just discovered. Always nice when bugs spontaneously vanish... A 'git reset HEAD~1'/recompile/retest loop reveals this bug was fixed by 6f0e008c, as later modified by 7b994b6a. So, let's make sure it stays fixed. src/cmd/ksh93/tests/variables.sh: - Add a couple of regression tests for BUG_KUNSETIFS presence, detection and known workaround, based on the same in modernish. Ref.: https://github.com/modernish/modernish/blob/3ddcbd13/lib/modernish/cap/BUG_KUNSETIFS.t https://github.com/modernish/modernish/blob/3ddcbd13/lib/modernish/tst/isset.t#L204-L222 --- NEWS | 2 ++ TODO | 6 ------ src/cmd/ksh93/tests/variables.sh | 26 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 3ecfcc47d..f0b36ceaf 100644 --- a/NEWS +++ b/NEWS @@ -180,6 +180,8 @@ Any uppercase BUG_* names are modernish shell bug IDs. etc. to lose their effect after being unset in a subshell. For example: (unset PATH; PATH=/dev/null; ls); : wrongly ran 'ls' (unset LC_ALL; LC_ALL=badlocale); : failed to print a diagnostic + This also fixes BUG_KUNSETIFS: unsetting IFS in a subshell failed if IFS + was set to the empty value in the parent shell. - Fix crashes on some systems, including at least a crash in 'print -v' on macOS, by eliminating an invalid/undefined use of memccpy() on overlapping diff --git a/TODO b/TODO index bb6554274..514183e37 100644 --- a/TODO +++ b/TODO @@ -71,12 +71,6 @@ https://github.com/modernish/modernish/tree/0.16/lib/modernish/cap/ are erroneously interpreted as wildcards when quoted "$*" is used as the glob pattern. -- BUG_KUNSETIFS: ksh93: Can't unset IFS under very specific circumstances. - unset -v IFS is a known POSIX shell idiom to activate default field - splitting. With this bug, the unset builtin silently fails to unset IFS - (i.e. fails to activate field splitting) if we're executing an eval or a - trap and a number of specific conditions are met. - - BUG_LOOPRET2: If a 'return' command is given without a status argument within the set of conditional commands in a 'while' or 'until' loop (i.e., between 'while'/'until' and 'do'), the exit status passed down from the diff --git a/src/cmd/ksh93/tests/variables.sh b/src/cmd/ksh93/tests/variables.sh index 69827cebb..c9bb3fc54 100755 --- a/src/cmd/ksh93/tests/variables.sh +++ b/src/cmd/ksh93/tests/variables.sh @@ -268,6 +268,9 @@ fi for i in : % + / 3b '**' '***' '@@' '{' '[' '}' !! '*a' '$foo' do (eval : \${"$i"} 2> /dev/null) && err_exit "\${$i} not an syntax error" done + +# ___ begin: IFS tests ___ + unset IFS ( IFS=' ' ; read -r a b c <<-! x y z @@ -418,6 +421,29 @@ do ;; esac done + +# BUG_KUNSETIFS: Unsetting IFS fails to activate default default field splitting if two conditions are met: +IFS='' # condition 1: no split in main shell +: ${foo-} # at least one expansion is also needed to trigger this +( # condition 2: subshell (non-forked) + unset IFS + v="one two three" + set -- $v + let "$# == 3" # without bug, should be 3 +) || err_exit 'IFS fails to be unset in subshell (BUG_KUNSETIFS)' + +# Test known BUG_KUNSETIFS workaround (assign to IFS before unset) +IFS= v= +: ${v:=a$'\n'bc$'\t'def\ gh} +case $(unset IFS; set -- $v; print $#) in +4 | 1) # test if the workaround works whether we've got the bug or not + v=$(IFS=foobar; unset IFS; set -- $v; print $#) + [[ $v == 4 ]] || err_exit "BUG_KUNSETIFS workaround fails (expected 4, got $v)" ;; +*) err_exit 'BUG_KUNSETIFS detection failed' +esac + +# ^^^ end: IFS tests ^^^ +# restore default split: unset IFS if [[ $( (print ${12345:?}) 2>&1) != *12345* ]]