Not so much a bug report but simply a way to test that the IFS code in sh(1) is up to snuff. Glenn Fowler at AT&T Research has a shell script [1] that tests how good a shell's IFS code is. The script can be downloaded from [1] but is also attached to the end of this PR. [1] http://www.research.att.com/~gsf/public/ifs.sh Fix: On my 4.10 box sh(1) has the following results: [...] # tests 6856 passed 1097 failed 5759 ordered 1644 I don't have any other systems to test on. Here's the script: # Usage: $SHELL ifs.sh # # This script generates 6856 tests for the set(1) and read(1) # builtins w.r.t. IFS whitespace and non-whitespace characters. # Each failed test produces one line on the standard output that # contains the test along with the expected and actual results. # The last output line contains the test result counts. ordered>0 # are the number of tests where IFS=": " produced different results # than IFS=" :". If a test fails the same way for IFS=": " and # IFS=" :" then the second output line is suppressed. TESTS=6856 ksh_read=0 echo 1 | read ksh_read ksh_arith=0 eval '((ksh_arith+=1))' 2>/dev/null failed=0 ordered=0 passed=0 split() { i=$1 s=$2 r=$3 S='' R='' for ifs in ': ' ' :' do IFS=$ifs set x $i shift IFS=' ' g="[$#]" while : do case $# in 0) break ;; esac g="$g($1)" shift done case $g in "$s") case $ksh_arith in 1) ((passed+=1)) ;; *) passed=`expr $passed + 1` ;; esac case $S in '') S=$g ;; "$g") ;; *) case $ksh_arith in 1) ((ordered+=1)) ;; *) ordered=`expr $ordered + 1` ;; esac ;; esac ;; "$S") case $ksh_arith in 1) ((failed+=1)) ;; *) failed=`expr $failed + 1` ;; esac ;; *) case $ksh_arith in 1) ((failed+=1)) ;; *) failed=`expr $failed + 1` ;; esac case $s in "$S") ;; ?0*) echo "IFS=\"$ifs\"; x=\"$i\"; set x \$x; shift; echo \"[\$#]\" # expected \"$s\" got \"$g\"" ;; ?1*) echo "IFS=\"$ifs\"; x=\"$i\"; set x \$x; shift; echo \"[\$#](\$1)\" # expected \"$s\" got \"$g\"" ;; ?2*) echo "IFS=\"$ifs\"; x=\"$i\"; set x \$x; shift; echo \"[\$#](\$1)(\$2)\" # expected \"$s\" got \"$g\"" ;; ?3*) echo "IFS=\"$ifs\"; x=\"$i\"; set x \$x; shift; echo \"[\$#](\$1)(\$2)(\$3)\" # expected \"$s\" got \"$g\"" ;; *) echo TEST ERROR i="'$i'" s="'$s'" ;; esac case $S in '') S=$g ;; "$g") ;; *) case $ksh_arith in 1) ((ordered+=1)) ;; *) ordered=`expr $ordered + 1` ;; esac ;; esac esac case $ksh_read in 1) echo "$i" | IFS=$ifs read x y; g="($x)($y)" ;; *) g=`export ifs; echo "$i" | ( IFS=$ifs; read x y; echo "($x)($y)" )` ;; esac case $g in "$r") case $ksh_arith in 1) ((passed+=1)) ;; *) passed=`expr $passed + 1` ;; esac case $R in '') R=$g ;; "$g") ;; *) case $ksh_arith in 1) ((ordered+=1)) ;; *) ordered=`expr $ordered + 1` ;; esac ;; esac ;; "$R") case $ksh_arith in 1) ((failed+=1)) ;; *) failed=`expr $failed + 1` ;; esac ;; *) case $ksh_arith in 1) ((failed+=1)) ;; *) failed=`expr $failed + 1` ;; esac case $r in "$R") ;; *) echo "echo \"$i\" | ( IFS=\"$ifs\" read x y; echo \"(\$x)(\$y)\" ) # expected \"$r\" got \"$g\"" ;; esac case $R in '') R=$g ;; "$g") ;; *) case $ksh_arith in 1) ((ordered+=1)) ;; *) ordered=`expr $ordered + 1` ;; esac ;; esac ;; esac done } for str in \ '-' \ 'a' \ '- -' \ '- a' \ 'a -' \ 'a b' \ '- - -' \ '- - a' \ '- a -' \ '- a b' \ 'a - -' \ 'a - b' \ 'a b -' \ 'a b c' \ do IFS=' ' set x $str shift case $# in 0) continue ;; esac f1=$1 case $f1 in '-') f1='' ;; esac shift case $# in 0) for d0 in '' ' ' do for d1 in '' ' ' ':' ' :' ': ' ' : ' do case $f1$d1 in '') split "$d0$f1$d1" "[0]" "()()" ;; ' ') ;; *) split "$d0$f1$d1" "[1]($f1)" "($f1)()" ;; esac done done continue ;; esac f2=$1 case $f2 in '-') f2='' ;; esac shift case $# in 0) for d0 in '' ' ' do for d1 in ' ' ':' ' :' ': ' ' : ' do case ' ' in $f1$d1|$d1$f2) continue ;; esac for d2 in '' ' ' ':' ' :' ': ' ' : ' do case $f2$d2 in '') split "$d0$f1$d1$f2$d2" "[1]($f1)" "($f1)()" ;; ' ') ;; *) split "$d0$f1$d1$f2$d2" "[2]($f1)($f2)" "($f1)($f2)" ;; esac done done done continue ;; esac f3=$1 case $f3 in '-') f3='' ;; esac shift case $# in 0) for d0 in '' ' ' do for d1 in ':' ' :' ': ' ' : ' do case ' ' in $f1$d1|$d1$f2) continue ;; esac for d2 in ' ' ':' ' :' ': ' ' : ' do case $f2$d2 in ' ') continue ;; esac case ' ' in $f2$d2|$d2$f3) continue ;; esac for d3 in '' ' ' ':' ' :' ': ' ' : ' do case $f3$d3 in '') split "$d0$f1$d1$f2$d2$f3$d3" "[2]($f1)($f2)" "($f1)($f2)" ;; ' ') ;; *) x=$f2$d2$f3$d3 x=${x#' '} x=${x%' '} split "$d0$f1$d1$f2$d2$f3$d3" "[3]($f1)($f2)($f3)" "($f1)($x)" ;; esac done done done done continue ;; esac done case $ksh_arith in 1) ((tests=passed+failed)) ;; *) tests=`expr $passed + $failed` ;; esac case $ordered in 0) ordered="" ;; *) ordered=" ordered $ordered" ;; esac case $tests in $TESTS) fatal="" ;; *) fatal=" -- fundamental IFS error -- $TESTS tests expected" esac echo "# tests $tests passed $passed failed $failed$ordered$fatal" How-To-Repeat: /bin/sh ifs.sh
Responsible Changed From-To: freebsd-standards->stefanf Stefan has been doing a lot of work lately writing regression tests for /bin/sh.
standards/79067 mentions this test script too but also has patches to fix the problems -- Jilles Tjoelker
On Sat, April 4, 2009 09:39, Jilles Tjoelker wrote: > standards/79067 mentions this test script too but also has patches to > fix the problems If you want to marked it a dupe of the other, or close it if the patch fixes things, that's fine with me. I filed the bug a while ago, and no longer have a FreeBSD to test things on.
I'm not working on /bin/sh anymore.
batch change: For bugs that match the following - Status Is In progress AND - Untouched since 2018-01-01. AND - Affects Base System OR Documentation DO: Reset to open status. Note: I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.
Keyword: patch or patch-ready – in lieu of summary line prefix: [patch] * bulk change for the keyword * summary lines may be edited manually (not in bulk). Keyword descriptions and search interface: <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>
(In reply to David Magda from 2005 comment #0) > [1] http://www.research.att.com/~gsf/public/ifs.sh No longer available. Linked: a capture in the Wayback Machine. (In reply to Jilles Tjoelker from 2009 comment #2) > standards/79067 mentions this test script too but also has patches to fix > the problems (In reply to Eitan Adler from 2018 comment #5) > … I did a quick pass but if you are getting this email it might be > worthwhile to double check to see if this bug ought to be closed. ---- ^Triage: bug 79067 was fixed in 2009 with <https://github.com/freebsd/freebsd-src/commit/f19a2f6c574ce3dc437d9998a879ad65e8666c5d> so let's close here, as overcome by events. If necessary, please reopen or make a new report. Thanks. f19a2f6c574c Fix some weirdnesses in the NetBSD IFS code, in particular "$@"$ifschar if the final positional parameter is empty. With the NetBSD code, adding the $ifschar removes a parameter.