#### BUG: ksh93 from ast-open.2010-10-26 has issued with gcc strict aliasing # To test: Compile with -O2 -O2 -fstrict-aliasing -Wstrict-aliasing gcc (GCC) 3.4.3 (csl-sol210-3_4-20050802) on Solaris 11/x86/32bit gives the following warnings: -- snip -- src/lib/libast/sfio/sfcvt.c:133: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:133: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:133: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:144: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:144: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:144: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:182: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:182: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:182: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:311: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:311: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:311: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:322: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:322: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:322: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:356: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:356: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libast/sfio/sfcvt.c:356: warning: dereferencing type-punned pointer will break strict-aliasing rules src/cmd/builtin/tr.c:200: warning: dereferencing type-punned pointer will break strict-aliasing rules src/cmd/builtin/tr.c:215: warning: dereferencing type-punned pointer will break strict-aliasing rules src/cmd/bzip/bzip2.c:404: warning: dereferencing type-punned pointer will break strict-aliasing rules src/cmd/bzip/bzip2.c:491: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libdss/dssopen.c:570: warning: dereferencing type-punned pointer will break strict-aliasing rules src/cmd/dsslib/time_t/time_t.c:562: warning: dereferencing type-punned pointer will break strict-aliasing rules src/cmd/ksh93/sh/name.c:2691: warning: dereferencing type-punned pointer will break strict-aliasing rules ./FEATURE/math:98: warning: dereferencing type-punned pointer will break strict-aliasing rules ./FEATURE/math:98: warning: dereferencing type-punned pointer will break strict-aliasing rules ./FEATURE/math:98: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/vcrecode.c:46: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/vcsfio.c:248: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/vcsfio.c:574: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/vcsfio.c:734: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vcdelta/vcdelta.c:295: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vcdelta/vcdelta.c:299: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vcdelta/vcdelta.c:303: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vcdelta/vcdelta.c:369: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vcdelta/vcdelta.c:373: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vcdelta/vcdelta.c:377: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vcdelta/vcdtable.c:108: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vcdelta/vcdtable.c:155: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vchuff/vchuffgroup.c:381: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vchuff/vchuffgroup.c:511: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vchuff/vchuffgroup.c:513: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vchuff/vchuffgroup.c:609: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vchuff/vchuffgroup.c:611: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vchuff/vchuffpart.c:101: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libvcodex/Vchuff/vchuffpart.c:261: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtksh/tcl/tclUnixNotfy.c:278: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/unix/tkUnixSelect.c:411: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/unix/tkUnixSelect.c:878: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/unix/tkUnixWm.c:2078: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/unix/tkUnixWm.c:2083: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/generic/tkCmds.c:900: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/generic/tkOption.c:1365: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/generic/tkSend.c:376: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/generic/tkSend.c:599: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/generic/tkSend.c:1166: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/generic/tkSend.c:1311: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/generic/tkTest.c:1124: warning: dereferencing type-punned pointer will break strict-aliasing rules src/lib/libtk/generic/tkTest.c:1125: warning: dereferencing type-punned pointer will break strict-aliasing rules -- snip -- ## NOT A BUG (resolved by dgk): ast-ksh.2010-10-26 does not export a local variable in a function if exported with "typeset -x" or "export". Testcase: -- snip -- # bash4.0: works $ bash -c 'function y { ksh -c "print \$ex" ; } ; function x { typeset -x ex ; for ex in "foo" "bar" ; do export ex ; y ; done ; } ; x' foo bar # Solaris ksh88: works $ ksh -c 'function y { ksh -c "print \$ex" ; } ; function x { typeset -x ex ; for ex in "foo" "bar" ; do export ex ; y ; done ; } ; x' foo bar # ksh93: FAIL $ ksh93 -c 'function y { ksh -c "print \$ex" ; } ; function x { typeset -x ex ; for ex in "foo" "bar" ; do export ex ; y ; done ; } ; x' -- snip -- ## BUG: ast-ksh.2010-10-26 does not print the variable name for "set -o nounset" correctly. Example: -- snip -- $ timex ~/bin/ksh -c 'typeset s="" ; integer i ; for ((i=0 ; i < 1024 ; i++)) ; do s+="X" ; x=$( ~/bin/ksh -u -c "print \${$s}" 2>&1 ) ; [[ $x == *" ${s}: "* ]] || print "FAIL $s" ; done' FAIL XXX FAIL XXXX FAIL XXXXX FAIL XXXXXX FAIL XXXXXXX FAIL XXXXXXXX FAIL XXXXXXXXX FAIL XXXXXXXXXX [snip] -- snip -- BUG: Swapping elements of a compound variable array (both indexed and associative) fails like this: -- snip -- ~/bin/ksh -c 'compound -a x=( [0]=(a=1) [1]=(b=2) ) ; print -C x ; typeset -m "z=x[1]" ; typeset -m "x[1]=x[0]" ; typeset -m "x[0]=z" ; print -C x' ((a=1) (b=2)) (() (a=1)) $ ~/bin/ksh -c 'compound -A x=( [0]=(a=1) [1]=(b=2) ) ; print -C x ; typeset -m "z=x[1]" ; typeset -m "x[1]=x[0]" ; typeset -m "x[0]=z" ; print -C x' ([0]=(a=1) [1]=(b=2)) /home/test001/bin/ksh[1]: typeset: ( a=1 ): invalid variable name -- snip -- BUG: Moving elements between an associative and indexed compound array fails like this: -- snip -- $ ~/bin/ksh -c 'compound c ; compound -a c.a=( [1]=( aa=1 ) ) ; compound -A c.b=( [2]=( bb=2 ) ) ; typeset -m "c.b[9]=c.a[1]" ; print -v c' /home/test001/bin/ksh[1]: typeset: : invalid variable name -- snip -- BUG: Swapping moving an element between two indexed compound variable arrays leaves an empty element with the source name: -- snip -- $ ~/bin/ksh -c 'compound c ; compound -a c.a=( [1]=( aa=1 ) ) ; compound -a c.b=( [2]=( bb=2 ) ) ; typeset -m "c.b[9]=c.a[1]" ; print -v c' ( typeset -C -a a=( [1]= ) typeset -C -a b=( [2]=( bb=2 ) [9]=( aa=1 ) ) ) -- snip -- AFAIK the expected output should be: -- snip -- ( typeset -C -a a typeset -C -a b=( [2]=( bb=2 ) [9]=( aa=1 ) ) ) -- snip -- BUG: Moving a compound variable array into another compound variable array as element fails: -- snip -- $ ~/bin/ksh -c 'compound c ; compound -a c.a=( [1]=( aa=1 ) ) ; compound -a c.b=( [2]=( bb=2 ) ) ; typeset -m "c.b[9]=c.a" ; print -v c' ( typeset -C -a a=( [1]=( aa=1 ) ) typeset -C -a b=( [2]=( bb=2 ) ) ) -- snip -- AFAIK the expected output should look like this: -- snip -- ( typeset -C -a b=( [2]=( bb=2 ) [9]=( typeset -C -a a=( [1]=( aa=1 ) ) ) ) ) -- snip -- BUG: Indexed array of typed variables calls "unset" discipline function twice... During testing we found a small bug in ast-ksh.2010-10-26 which causes the "unset" discipline function to be called twice on program exit: -- snip -- $ ~/bin/ksh -c 'typeset -T u_t=( integer dummy ; unset() { printf "unsetme %q / %q\n" "${.sh.name}" "${.sh.subscript}" ; } ; ) ; u_t -a x ; unset x' unsetme x / 0 unsetme x / 0 -- snip -- AFAIK the correct output should be: -- snip -- unsetme x / '' -- snip --. ... where "${.sh.subscript}" should simply not be set. BUG: String literals are not assigned correctly to variables when "shcomp" is running in "-n" mode: This testcase works... -- snip -- $ print $'x="aaa" ; print "$x" ; x=$\'aaa\' ; print "$x" ; x=\'aaa\' ; print "$x"' | ~/bin/shcomp | ~/bin/ksh aaa aaa aaa -- snip -- ... but adding "-n" somehow adds the surrounding quotes to the values: -- snip -- $ print $'x="aaa" ; print "$x" ; x=$\'aaa\' ; print "$x" ; x=\'aaa\' ; print "$x"' | ~/bin/shcomp -n | ~/bin/ksh "aaa" $'aaa' 'aaa' -- snip -- BUG: Nesting custom types in an array causes corrupted output: -- snip -- $ ~/bin/ksh -c 'typeset -T a_t=( typeset a="hello" ) ; typeset -T b_t=( a_t b ) ; compound c ; compound -a c.ca ; b_t c.ca[4].b ; print -v c' ( typeset -C -a ca=( [4]=( b_t b=( ) ) ) ca[4]=( b_t b=( a_t b=( a=hello ) ) ) ) -- snip -- AFAIK the output should look like this: -- snip -- ( typeset -C -a ca=( [4]=( b_t b=( a_t b=( a=hello ) ) ) ) ) -- snip -- BUG: read -t with very small timeout results in no timeout. ksh93 -c 'sleep 600 | read -t0.1 x' # waits 0.1 seconds ksh93 -c 'sleep 600 | read -t0.00001 x' # waits 600 seconds BUG: [[ -v .sh.match[n] ]] does not work # in theory this should print "OK" ksh -c 'x="foo bar" ; dummy=${x/~(Elr-g)(.*) (.*)/} ; [[ -v .sh.match[1] ]] && print OK' BUG: "grep -r" removes the leading "./" from relative filenames Example: $ (cd /etc/inet ; gnu_grep -r CacheFS .) ./inetd.conf:# CacheFS daemon. Provided only as a basis for conversion by inetconv(1M). ggrep: ./secret: Permission denied $ (cd /etc/inet ; ast_grep -r CacheFS .) inetd.conf:# CacheFS daemon. Provided only as a basis for conversion by inetconv(1M). grep: secret: cannot read directory [Permission denied] BUG: getconf PC_PIPE_BUF /tmp # does not work The ksh93/AST builtin "getconf" does not recognise PC_PIPE_BUF BUG: ls -R as builtin does not restore original CWD If "ls" is a builtin utility it does not restore the original CWD if interupted via BUG: grep -r as builtin does not restore original CWD If "grep" is a builtin utility it does not restore the original CWD if interupted via BUG: "pr" builtin crashes BUG: (Nested) "for"-loop as only element in a subshell causes for-loop to be executed out-of-sync with parent shell level: The following statement to execute the inner "for"-loop completely "async" like a background process: -- snip -- $ ksh93 -c 'for i1 in a1 b1 c1 d1 ; do (for i2 in a2 b2 c2 d2 ; do /bin/printf "%s%s\n" "$i1$i2" ; done) ; done ; print "##done"' a1a2 a1b2 b1a2 a1c2 b1b2 a1d2 b1c2 c1a2 b1d2 c1b2 c1c2 c1d2 d1a2 ##done d1b2 d1c2 -- snip -- This did work in ast_ksh_20100914 but started to fail in ast_ksh_20100924. The problem goes away if I change the "done)" to "done ; true)" (e.g. $ ksh93 -c 'for i1 in a1 b1 c1 d1 ; do (for i2 in a2 b2 c2 d2 ; do /bin/printf "%s%s\n" "$i1$i2" ; done ; true) ; done ; print "##done"' #), suggesting a subtle issue with loop optimisation vs. subshell optimisation. BUG: "read -C" with a compound variable value which contains special shell keywords or aliases like "functions", "alias", "!" causes the shell to produce errors like this: -- snip -- $ ~/bin/ksh -c 'print "( compound -A a1=( [4]=( typeset -a x=( alias ) ) ) ; compound -A a2=( [4]=( typeset -a x=( ! ! ! alias ) ) ) )" | read -C c ; print -v c' 1>/dev/null /home/test001/bin/ksh[1]: alias: c.a1[4].x: compound assignment requires sub-variable name -- snip -- BUG: $ ksh93 -c '[[ "@" == ~(E)[\\\]\[\*@_] ]] && print match' # does not print "match" $ ksh93 -c '[[ "@" == ~(E)[\\\]\[\*@_] ]] && print match' # does not print match, likely because the \] inside a [...] is not recognised correctly and causes the shell to interpret the regex as invalid. BUG: "tee" used as builtin utility may fail if receives a SIGCHLD The following testcase... -- snip -- builtin tee rm -f 'pipe' mknod 'pipe' p (sleep 4; cat pipe) & (sleep 2; print 'aa') | tee -a 'pipe' rm 'pipe' wait -- snip -- ... fails like this: -- snip -- $ ~/bin/ksh x.sh tee: pipe: cannot create [Interrupted system call] aa cat: pipe: cannot open [No such file or directory] -- snip -- BUG: "who" builtin has problems with "utmp" vs. "utmpx". Fix: -- snip -- Index: i386/src/lib/libcmd/FEATURE/utmp =================================================================== --- i386/src/lib/libcmd/FEATURE/utmp (revision 2270) +++ i386/src/lib/libcmd/FEATURE/utmp (working copy) @@ -7,9 +7,6 @@ #define _LIB_cmd_g 1 /* ../../../lib/libcmd-g.a is a library */ #define _LIB_md 1 /* -lmd is a library */ #define _hdr_utmpx 1 /* #include ok */ -#define _hdr_utmp 1 /* #include ok */ -#define _mem_ut_type_utmp 1 /* ut_type is a member of struct utmp */ -#define _mem_ut_user_utmp 1 /* ut_user is a member of struct utmp */ #define _mem_ut_host_utmpx 1 /* ut_host is a member of struct utmpx */ #define _mem_ut_tv_utmpx 1 /* ut_tv is a member of struct utmpx */ #define _mem_ut_type_utmpx 1 /* ut_type is a member of struct utmpx */ -- snip -- BUG: Dereferencing a name reference to a non-existing (compound) array element mangles the index to "(null)": -- snip -- $ ~/bin/ksh -c 'compound c ; compound -A c.a ; nameref nr=c.a[hello] ; print "${!nr}"' c.a[(null)] -- snip -- AFAIK it should print "c.a[hello]" but ast-ksh.2010-1-12 prints "c.a[(null)]" instead... ;-( BUG: "tail"'s "-t" optin does not support sub-second timeouts. Example "tail-f -t0.001s" waits forever. BUG: ~(E) regular expressions do not match ']' in ~(E) character range $ ksh93 -c '[[ "@" == ~(E)[\\\]\[\*@_] ]] && print match' # not print "match" ? BUG: ~/bin/ksh -c 'compound c ; compound -A c.a ; nameref nr=c.a[hello] ; print "${!nr}"' prints '(null)' as array index Example: -- snip -- $ ~/bin/ksh -c 'compound c ; compound -A c.a ; nameref nr=c.a[hello] ; print "${!nr}"' c.a[(null)] -- snip -- AFAIK it should print "c.a[hello]" but ast-ksh.2010-1-12 prints "c.a[(null)]" instead... ;-( BUG: ksh93 uses |regcomp()| two times during shell startup - which is _very_ expensive: -- snip -- 0x00000001000cfd24: _ast_regcomp : save %sp, -576, %sp (dbx) where =>[1] _ast_regcomp(0x1002ab2f8, 0x1002ab350, 0x1131, 0x12, 0xff0000, 0x12), at 0x1000cfd24 [2] _ast_regcache(0x10012c725, 0x1131, 0x0, 0xffffffffffffffff, 0x1002ab2f8, 0x1002ab2a0), at 0x1000d0e2c [3] _ast_strgrpmatch(0x1002aa9e0, 0x10012c725, 0x0, 0x0, 0x121, 0x0), at 0x1000988b4 [4] test_stat(0x1002aa9e0, 0xffffffff7fffefa0, 0x0, 0x1f375c, 0x2f, 0x100281928), at 0x10008e1ec [5] test_inode(0x1002aa9e0, 0x10012c880, 0x1002844e0, 0x1002aa9e0, 0x0, 0x1002a6ac8), at 0x10008ddd4 [6] path_pwd(0x1002844e0, 0x0, 0x1002aa9e0, 0x100060f10, 0x0, 0x10029ebb0), at 0x10006108c [7] env_init(0x1002844e0, 0x4e, 0x0, 0x3000, 0x10029ebb0, 0x100281928), at 0x1000379a0 [8] sh_init(0x2, 0xffffffff7ffffa78, 0x100284780, 0x1002844e0, 0x100299800, 0x100281928), at 0x100035f14 [9] sh_main(0x2, 0xffffffff7ffffa78, 0x0, 0xffffffff7ffff9b0, 0x0, 0x0), at 0x10001d604 [10] main(0x2, 0xffffffff7ffffa78, 0x10000, 0x400000000, 0x1c80, 0x4), at 0x10001ce30 (dbx) print (char *)0x1002ab350 dbx: warning: unknown language, 'c' assumed (char *) 4297765712 = 0x1002ab350 "/dev/fd/+([0-9])" (dbx) cont Reading en_US.UTF-8.so.3 Reading methods_unicode.so.3 stopped in _ast_regcomp at 0x00000001000cfd24 0x00000001000cfd24: _ast_regcomp : save %sp, -576, %sp (dbx) where =>[1] _ast_regcomp(0x1002ab2f8, 0x1002ab350, 0x1131, 0x12, 0xff0000, 0x12), at 0x1000cfd24 [2] _ast_regcache(0x10012c725, 0x1131, 0x0, 0xffffffffffffffff, 0x1002ab2f8, 0x0), at 0x1000d0e2c [3] _ast_strgrpmatch(0xffffffff7ffffc66, 0x10012c725, 0x0, 0x0, 0x121, 0x0), at 0x1000988b4 [4] sh_init(0x2, 0xffffffff7ffffa78, 0x100284780, 0x1002844e0, 0x100299800, 0x100281928), at 0x100036398 [5] sh_main(0x2, 0xffffffff7ffffa78, 0x0, 0xffffffff7ffff9b0, 0x0, 0x0), at 0x10001d604 [6] main(0x2, 0xffffffff7ffffa78, 0x10000, 0x400000000, 0x1c80, 0x4), at 0x10001ce30 (dbx) print (char*)0x1002ab350 dbx: warning: unknown language, 'c' assumed (char *) 4297765712 = 0x1002ab350 "/dev/fd/+([0-9])" -- snip -- BUG: ast-ksh.2010-11-22 warns about '<' and '>' in extended regular expressions like this: $ ~/bin/ksh -n -c 'str=" " ; dummy="${str//~(E-g)<.*> (<.*>)}" ; print -v .sh.match' /home/test001/bin/ksh: warning: line 1: < within ${} should be quoted /home/test001/bin/ksh: warning: line 1: > within ${} should be quoted BUG: libast has no |posix_memalign()| which is mapped via map.c libast has no |posix_memalign()| which is mapped via map.c BUG: 'compound -A ar=( [hello]=( integer num=4 ) ) ; (( ar[hello].num+=1 )) ; print ${ar[hello].num}' generates a shlint warning $ ~/bin/ksh -n -c 'compound -A ar=( [hello]=( integer num=4 ) ) ; (( ar[hello].num+=1 )) ; print ${ar[hello].num}' /home/test001/bin/ksh: ar[hello].num+=1 : arithmetic syntax error BUG: typeset -l/typeset -u (lowercase/uppercase conversion) does not work for non-ASCII characters Testcase (assumes ksh93 "print" is available as /usr/bin/print) - it should print two lowercase "ae": -- snip -- $ ~/bin/ksh -c 'typeset -l x ; x=$(/usr/bin/print -f "x\u[c4]\u[e4]x") ; print "$x"' xx -- snip -- BUG: fault.c line 650 uses |pause()| in a way which will not work: It basically boils down to this code in fault.c, around line 650: -- snip -- if(sig) { /* generate fault termination code */ signal(sig,SIG_DFL); sigrelease(sig); kill(getpid(),sig); pause(); } -- snip -- This code will not work in some cases because the signal |kill()| sends may arrive long before |pause()| is reached (e.g. some kind of race condition), leading to a lockup of the shell. We found the issue when doing testing with SIGWINCH - modern window managers often allow windows to be resized while moving the mouse, resulting in hundreds of WINCH signals to be send. The problem/hang can be reproduced by doing a $ ksh -c 'trap "print winchange" WINCH ; for ((i=0 ; i < 10 ; i++ )) ; do sleep 1 ; done # and then "madly" resize the window with a window manager which does resize-while-drag. Usually you'll see 2, 3 or 4 times the line "winchange" and then the shell locked-up and waits in fault.c line 650 (the |pause()| call above). BUG: libast uses mb*()/wc*() functions instead of the safer/faster mbr*/wcr*() functions There are many places where |mblen()| is being called. However |mblen()| is usually just a call to |mbrlen()| with an internal |state| variable. The problem is that this global state variable is _very_ _very_ expensive to use and is not threadsafe on all platforms. The solution is simply to round-up all calls to |mblen()| and change them to calls to |mbrlen()|, something which other shells like bash4 have already done. Unfortunately |mblen()| isn't the only function - AFAIK the following need to be changed: mblen --> mbrlen mbtowc --> mbrtowc wctomb --> wcrtomb wcstombs --> wcsrtombs mbstowcs --> mbsrtowcs BUG: De-serialisation of hexfloat values is broken in ast-ksh.2010-12-01: $ ~/bin/ksh -c 'typeset -l -E x ; str="0x1.df768ed398ee1e01329a130627ae0000p-1" ; (( x=str ))' /home/test001/bin/ksh: line 1: x1.df768ed398ee1e01329a130627ae0000p: no parent BUG "grep" has issues with eating empty lines The following example seems to swallow the empty line in the middle: -- snip -- $./arch/linux.i386/bin/ksh -c './arch/linux.i386/bin/ksh -c "/bin/echo line1 ; /bin/echo ; /bin/echo line3" | ./arch/linux.i386/bin/grep -v "char"' line1 line3 -- snip -- Expected output would be (newline between "line1" and "line3"): -- snip -- line1 line3 -- snip -- BUG: libcmd's "rm" builtin asks interactively to remove a file which has no "read" permission The following testcase (when running from an "xterm" terminal ; running it as $ ./script" myfoo ; chmod a+x,a-r myfoo ; rm myfoo ; true ; find .' + builtin rm + umask 0022 + mkdir x + cd x + print true + 1> myfoo + chmod a+x,a-r myfoo + rm myfoo override protection -wx--x--x for myfoo? -- snip -- BUG: Indexed array access has issues with variable name corruption The following testcase for ast-ksh.2010-12-01 creates a |strcpy()|-call which may lead to undefined behaviour on some platforms. Example (note that variable "l1" must be exactly two charcaters wide): -- snip -- $ ksh -c 'typeset -T r_t=( typeset left ; typeset right ) ; r_t -r -a x=([0]=(right="1") [1]=(right="2")) ; integer l1=1 ; print ${x[l1].right}' -- snip -- ... running this testcase on SuSE Linux 11.0 under "valgrind" control delivers this warning: -- snip -- ==28763== Source and destination overlap in strcpy(0x4223B31, 0x4223B32) ==28763== at 0x4C25E8D: strcpy (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) ==28763== by 0x45B4B9: nv_create (name.c:1053) ==28763== by 0x45C878: nv_open (name.c:1348) ==28763== by 0x452299: varsub (macro.c:1305) ==28763== by 0x44F6D3: copyto (macro.c:626) ==28763== by 0x44D9FA: sh_macexpand (macro.c:240) ==28763== by 0x4AE4D7: arg_expand (args.c:871) ==28763== by 0x4ADE9D: sh_argbuild (args.c:728) ==28763== by 0x48097B: sh_exec (xec.c:916) ==28763== by 0x484753: sh_exec (xec.c:1962) ==28763== by 0x417ED6: exfile (main.c:601) ==28763== by 0x4170CD: sh_main (main.c:373) -- snip -- This is bad since on some platforms an optimised |strcpy()| codepath may garble the string, resulting in a corrupted string... Workaround: Replace ${x[l1].right} with ${x[$l1].right} ... The following testcase demonstrates that the issue may even lead to a failure: -- snip -- $ ksh -o nounset -c 'typeset -T r_t=( typeset left ; typeset right ) ; r_t -r -a very_long_array_name=([0]=(rightvalue="1") [1]=(rightvalue="2")) ; integer i=0 ; print ${very_long_array_name[i].rightvalue} ${very_long_array_name[i].rightvalue}' ./arch/linux.i386/bin/ksh: line 1: rightvalue: is not an element of very_long_array_name[0] -- snip -- BUG: Uninitalised variable in io.c: The following testcase triggers many warnings from "valgrind" that function |io_heredoc()| uses variable |off| without initalising it first: -- snip -- valgrind ./arch/linux.i386/bin/ksh -c 'builtin cat ; function ff { cat <<<"hello" ; } ; ff' [snip] ==16561== Conditional jump or move depends on uninitialised value(s) ==16561== at 0x54F332: sfseek (sfseek.c:124) ==16561== by 0x43E0BB: io_heredoc (io.c:1538) ==16561== by 0x43CF8D: sh_redirect (io.c:1186) ==16561== by 0x481C44: sh_exec (xec.c:1206) ==16561== by 0x4890B4: sh_funscope (xec.c:3207) ==16561== by 0x489792: sh_funct (xec.c:3293) ==16561== by 0x48292C: sh_exec (xec.c:1397) ==16561== by 0x48475B: sh_exec (xec.c:1962) ==16561== by 0x417ED6: exfile (main.c:601) ==16561== by 0x4170CD: sh_main (main.c:373) ==16561== by 0x41618B: main (pmain.c:45) ==16561== ==16561== Conditional jump or move depends on uninitialised value(s) ==16561== at 0x54F344: sfseek (sfseek.c:124) ==16561== by 0x43E0BB: io_heredoc (io.c:1538) ==16561== by 0x43CF8D: sh_redirect (io.c:1186) ==16561== by 0x481C44: sh_exec (xec.c:1206) ==16561== by 0x4890B4: sh_funscope (xec.c:3207) ==16561== by 0x489792: sh_funct (xec.c:3293) ==16561== by 0x48292C: sh_exec (xec.c:1397) ==16561== by 0x48475B: sh_exec (xec.c:1962) ==16561== by 0x417ED6: exfile (main.c:601) ==16561== by 0x4170CD: sh_main (main.c:373) ==16561== by 0x41618B: main (pmain.c:45) ==16561== ==16561== Conditional jump or move depends on uninitialised value(s) ==16561== at 0x573877: _sfexcept (sfexcept.c:48) ==16561== by 0x552047: sfsk (sfsk.c:89) ==16561== by 0x54F3EB: sfseek (sfseek.c:134) ==16561== by 0x43E0BB: io_heredoc (io.c:1538) ==16561== by 0x43CF8D: sh_redirect (io.c:1186) ==16561== by 0x481C44: sh_exec (xec.c:1206) ==16561== by 0x4890B4: sh_funscope (xec.c:3207) ==16561== by 0x489792: sh_funct (xec.c:3293) ==16561== by 0x48292C: sh_exec (xec.c:1397) ==16561== by 0x48475B: sh_exec (xec.c:1962) ==16561== by 0x417ED6: exfile (main.c:601) ==16561== by 0x4170CD: sh_main (main.c:373) ==16561== ==16561== Conditional jump or move depends on uninitialised value(s) ==16561== at 0x5739F5: _sfexcept (sfexcept.c:64) ==16561== by 0x552047: sfsk (sfsk.c:89) ==16561== by 0x54F3EB: sfseek (sfseek.c:134) ==16561== by 0x43E0BB: io_heredoc (io.c:1538) ==16561== by 0x43CF8D: sh_redirect (io.c:1186) ==16561== by 0x481C44: sh_exec (xec.c:1206) ==16561== by 0x4890B4: sh_funscope (xec.c:3207) ==16561== by 0x489792: sh_funct (xec.c:3293) ==16561== by 0x48292C: sh_exec (xec.c:1397) ==16561== by 0x48475B: sh_exec (xec.c:1962) ==16561== by 0x417ED6: exfile (main.c:601) ==16561== by 0x4170CD: sh_main (main.c:373) ==16561== ==16561== Syscall param lseek(offset) contains uninitialised byte(s) ==16561== at 0x53570C0: lseek (in /lib64/libc-2.8.so) ==16561== by 0x551FF8: sfsk (sfsk.c:80) ==16561== by 0x54F3EB: sfseek (sfseek.c:134) ==16561== by 0x43E0BB: io_heredoc (io.c:1538) ==16561== by 0x43CF8D: sh_redirect (io.c:1186) ==16561== by 0x481C44: sh_exec (xec.c:1206) ==16561== by 0x4890B4: sh_funscope (xec.c:3207) ==16561== by 0x489792: sh_funct (xec.c:3293) ==16561== by 0x48292C: sh_exec (xec.c:1397) ==16561== by 0x48475B: sh_exec (xec.c:1962) ==16561== by 0x417ED6: exfile (main.c:601) ==16561== by 0x4170CD: sh_main (main.c:373) ==16561== ==16561== Conditional jump or move depends on uninitialised value(s) ==16561== at 0x54F3F0: sfseek (sfseek.c:134) ==16561== by 0x43E0BB: io_heredoc (io.c:1538) ==16561== by 0x43CF8D: sh_redirect (io.c:1186) ==16561== by 0x481C44: sh_exec (xec.c:1206) ==16561== by 0x4890B4: sh_funscope (xec.c:3207) ==16561== by 0x489792: sh_funct (xec.c:3293) ==16561== by 0x48292C: sh_exec (xec.c:1397) ==16561== by 0x48475B: sh_exec (xec.c:1962) ==16561== by 0x417ED6: exfile (main.c:601) ==16561== by 0x4170CD: sh_main (main.c:373) ==16561== by 0x41618B: main (pmain.c:45) hello ==16561== -- snip -- ... and so on... Proposed fix: -- snip -- diff -r -u old/src/cmd/ksh93/sh/io.c src/cmd/ksh93/sh/io.c --- old/src/cmd/ksh93/sh/io.c 2010-12-02 16:39:41.000000000 +0100 +++ src/cmd/ksh93/sh/io.c 2010-12-14 00:17:12.000000000 +0100 @@ -1533,9 +1533,9 @@ if(infile) sfclose(infile); } + sfseek(shp->heredocs,off,SEEK_SET); } /* close stream outfile, but save file descriptor */ - sfseek(shp->heredocs,off,SEEK_SET); fd = sffileno(outfile); sfsetfd(outfile,-1); sfclose(outfile); -- snip -- BUG: ksh -c '(( (0-0) ))' causes "valgrind" hit The following testcase reports that |if(nargs<0)| in line 701 in streval.c relies on a value which was never be initalised, e.g. |lvalue.nargs| contains a "random" value: -- snip -- $ valgrind ./arch/linux.i386/bin/ksh -c 'printf "%f\n" "(0-0)"' [snip] ==8938== Conditional jump or move depends on uninitialised value(s) ==8938== at 0x4783BE: expr (streval.c:701) ==8938== by 0x479694: arith_compile (streval.c:900) ==8938== by 0x4798FA: strval (streval.c:949) ==8938== by 0x425148: sh_strnum (arith.c:464) ==8938== by 0x49FE90: extend (print.c:829) ==8938== by 0x558C9C: sfvprintf (sfvprintf.c:541) ==8938== by 0x54CDFD: sfprintf (sfprintf.c:48) ==8938== by 0x49E432: b_print (print.c:294) ==8938== by 0x49DC31: b_printf (print.c:133) ==8938== by 0x48200A: sh_exec (xec.c:1257) ==8938== by 0x417ED6: exfile (main.c:601) ==8938== by 0x4170CD: sh_main (main.c:373) -- snip -- An even shorter testcase is... $ ksh -c '(( (0-0) ))' # ... note that you need the brackets in the arithmetric expression. # EOF.