Ticket UUID: | 554068 | |||
Title: | Windows: [exec] doesn't quote special chars | |||
Type: | Bug | Version: | obsolete: 8.4a5 | |
Submitter: | vincentdarley | Created on: | 2002-05-09 11:25:05 | |
Subsystem: | 27. Channel Types | Assigned To: | davygrvy | |
Priority: | 7 High | Severity: | ||
Status: | Closed | Last Modified: | 2004-02-26 07:33:09 | |
Resolution: | Fixed | Closed By: | hobbs | |
Closed on: | 2004-02-26 00:33:09 | |||
Description: |
If I rename 'tcl8.4' to 'tcl[{8.4' and try to run the test suite ('make test') from within there, 8 tests fail: Tests ended at Wed May 08 7:56:31 PM GMT Daylight Time 2002 all.tcl: Total 10164 Passed 9479 Skipped 677 Failed 8 Sourced 128 Test Files. Files with failing tests: io.test tcltest.test C:\Tcl-source\tcl{[8.4\win> The actual failures are listed below, and seem to be due to just two specific problems. I've attached a patch which I think fixes both problems (but tested only on Windows): io.test ==== io-34.10 Tcl_Seek testing flushing of buffered input FAILED ==== Contents of test case: set f [open test3 w] fconfigure $f -translation lf puts $f xyz\n123 close $f set f [open test3 r+] fconfigure $f -translation lf set x [gets $f] seek $f 0 current puts $f 456 close $f list $x [viewFile test3] ---- Result was: /usr/bin/cat: C:/Tcl-source/tcl: No such file or directory ---- Result should have been (exact matching): xyz {xyz 456} ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ==== io-34.10 FAILED ==== io-34.11 Tcl_Seek testing flushing of buffered output FAILED ==== Contents of test case: set f [open test3 w] puts $f xyz\n123 close $f set f [open test3 w+] puts $f xyzzy seek $f 2 set x [gets $f] close $f list $x [viewFile test3] ---- Result was: /usr/bin/cat: C:/Tcl-source/tcl: No such file or directory ---- Result should have been (exact matching): zzy xyzzy ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ==== io-34.11 FAILED ==== io-34.12 Tcl_Seek testing combination of write, seek back and read FAILED ==== Contents of test case: set f [open test3 w] fconfigure $f -translation lf -eofchar {} puts $f xyz\n123 close $f set f [open test3 a+] fconfigure $f -translation lf -eofchar {} puts $f xyzzy flush $f set x [tell $f] seek $f -4 cur set y [gets $f] close $f list $x [viewFile test3] $y ---- Result was: /usr/bin/cat: C:/Tcl-source/tcl: No such file or directory ---- Result should have been (exact matching): 14 {xyz 123 xyzzy} zzy ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ==== io-34.12 FAILED ==== io-40.7 POSIX open access modes: EXCL FAILED ==== Contents of test case: removeFile test3 set f [open test3 {WRONLY CREAT EXCL}] fconfigure $f -eofchar {} puts $f "A test line" close $f viewFile test3 ---- Result was: /usr/bin/cat: C:/Tcl-source/tcl: No such file or directory ---- Result should have been (exact matching): A test line ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ==== io-40.7 FAILED ==== io-40.13 POSIX open access modes: WRONLY FAILED ==== Contents of test case: makeFile xyzzy test3 set f [open test3 WRONLY] fconfigure $f -eofchar {} puts -nonewline $f "ab" seek $f 0 current set x [list [catch {gets $f} msg] $msg] close $f lappend x [viewFile test3] string compare [string tolower $x] [list 1 "channel \"$f\" wasn't opened fo r reading" abzzy] ---- Result was: /usr/bin/cat: C:/Tcl-source/tcl: No such file or directory ---- Result should have been (exact matching): 0 ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ==== io-40.13 FAILED ==== io-40.15 POSIX open access modes: RDWR FAILED ==== Contents of test case: makeFile xyzzy test3 set f [open test3 RDWR] puts -nonewline $f "ab" seek $f 0 current set x [gets $f] close $f lappend x [viewFile test3] ---- Result was: /usr/bin/cat: C:/Tcl-source/tcl: No such file or directory ---- Result should have been (exact matching): zzy abzzy ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ==== io-40.15 FAILED tcltest.test ==== tcltest-8.13 tcltest a.tcl -testdir normaldirectory FAILED ==== Contents of test case: catch {exec $::tcltest::tcltest a.tcl -testdir normaldirectory} msg # The join is necessary because the message can be split on multiple lines regexp "testdir: $normaldirectory" [join $msg] ---- Result was: couldn't compile regular expression pattern: brackets [] not balanced ---- Result should have been (exact matching): 1 ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ==== tcltest-8.13 FAILED ==== tcltest-23.5 viewFile FAILED ==== Contents of test case: set mfdir [file join [tcltest::temporaryDirectory] mfdir] file mkdir $mfdir makeFile {foobar} t1.tmp makeFile {foobarbaz} t2.tmp $mfdir list [viewFile t1.tmp] [viewFile t2.tmp $mfdir] ---- Result was: /usr/bin/cat: C:/Tcl-source/tcl: No such file or directory ---- Result should have been (exact matching): foobar foobarbaz ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ==== tcltest-23.5 FAILED | |||
User Comments: |
hobbs added on 2004-02-26 07:33:09:
Logged In: YES user_id=72656 dgp's latest test suite correction solve most of the issues. I still see an edge case failure in filename-9.19.2, which I think isn't safe list handling (but very low prio): ==== filename-9.19.2 Tcl_JoinPath: win FAILED ==== Contents of test case: testsetplatform win set res {} lappend res [file join {foo\bar}] [file join [pwd] {foo\bar}] [file join [pwd] [pwd] {foo\bar}] string map [list [pwd] pwd] $res ---- Result was: foo/bar C:/build/tcl\{\[84/foo/bar C:/build/tcl\{\[84/foo/bar ---- Result should have been (exact matching): foo/bar pwd/foo/bar pwd/foo/bar ==== filename-9.19.2 FAILED dgp added on 2004-02-26 07:23:08: Logged In: YES user_id=80530 I see that several of the original failing tests do appear to be throwing errors due to errors from cat. Apparently these tests were being run with a fairly old tcltest that still implemented [tcltest::viewFile] as [exec cat] ? That should no longer be a problem. dgp added on 2004-02-26 06:42:28: Logged In: YES user_id=80530 core-8-4-branch now has a more robust test suite. Please try the testing again. vincentdarley added on 2004-02-26 02:19:56: Logged In: YES user_id=32170 Please do fix up those tests and we can try again... I'll be away for the next few hours, but can test things after that (can you specify whether you're going to fix the tests in HEAD or 8.4 or both, so I know what to update?) thanks. p.s. I understand the earlier patch was incorrect now, and simply caused by a bad 'cat.exe', but let's be sure the new patch does what it's supposed to. Clearly if tests fail (as they do right now with a funny directory name) then either we need to fix Tcl or fix the tests. dgp added on 2004-02-26 02:14:37: Logged In: YES user_id=80530 thanks for testing, Vince, but those look like test errors to me. I see those failures on Unix as well. Perhaps I should fix those up first, then we can test again? hobbs added on 2004-02-26 02:14:15: Logged In: YES user_id=72656 I don't get any of these errors in my 8.4 head Windows build, run from a directory names C:/build/tcl84. Let me be clear that examination of the earlier patch has shown it to be incorrect. Another user who used {} in the command line args found things broke in 8.4 because of it. It may be that just the executable needs the { backslashed, but that would be a different patch and needs testing. vincentdarley added on 2004-02-26 02:13:28: Logged In: YES user_id=32170 Note: those test errors of mine occurred after renaming Tcl's directory to "tcl-c{[vs" or something similar. vincentdarley added on 2004-02-26 02:06:03: Logged In: YES user_id=32170 I get a whole bunch of errors with these changes, for example: io.test ==== io-14.3 Tcl_SetStdChannel & Tcl_GetStdChannel FAILED ==== Contents of test case: set f [open $path(test1) w] puts $f [format { close stdin close stdout close stderr set f [open "%s" r] set f2 [open "%s" w] set f3 [open "%s" w] puts stdout [gets stdin] puts stdout out puts stderr err close $f close $f2 close $f3 } $path(test1) $path(test2) $path(test3)] close $f set result [exec [interpreter] $path(test1)] set f [open $path(test2) r] set f2 [open $path(test3) r] lappend result [read $f] [read $f2] close $f close $f2 set result ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ---- errorInfo: child process exited abnormally while executing "exec [interpreter] $path(test1)" invoked from within "set result [exec [interpreter] $path(test1)]" ("uplevel" body line 18) invoked from within "uplevel 1 $script" ---- errorCode: CHILDSTATUS 1488 1 ==== io-14.3 FAILED ==== io-14.8 reuse of stdio special channels FAILED ==== Contents of test case: file delete $path(script) file delete $path(test1) set f [open $path(script) w] puts $f [format { close stderr set f [open "%s" w] puts stderr hello close $f set f [open "%s" r] puts [gets $f] } $path(test1) $path(test1)] close $f set f [open "|[list [interpreter] $path(script)]" r] set c [gets $f] close $f set c ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ---- errorInfo: child process exited abnormally while executing "close $f" ("uplevel" body line 16) invoked from within "uplevel 1 $script" ---- errorCode: CHILDSTATUS 4000 1 ==== io-14.8 FAILED (and many more besides). Have those who made these changes actually run the test suite on Windows? dgp added on 2004-02-26 01:55:34: Logged In: YES user_id=80530 sorry to be a pain on this; just want to be sure about a fix going into a stable patch this close to release. The original report here made no mention of cat.exe . Are the failures of that original report still corrected by the current CVS code? davygrvy added on 2004-02-26 01:24:18: Logged In: YES user_id=7549 The real problem here is that cygwin's cat.exe doesn't parse its commandline properly. Hacks for cat can be added to the core, but then all other uses of '{' in the commandline string will be parsed improperly by all other applications including tclsh and wish themselves. The pass-thru must be identical. echo.tcl: foreach arg $argv { puts $arg } % exec [info name] echo.tcl foo \{\[ bar foo {[ bar % If the above can not be identical, then cat.exe is in error, not us. Before the fix from yesterday that was added to the 84 branch, { would have had a \ in front of it that the MS parse_cmdline routine would not strip off. Again, cat.exe is in error, not us. dgp added on 2004-02-25 23:08:04: Logged In: YES user_id=80530 I see changes in this area were just committed to core-8-4-branch (for release in 8.4.6? ). Is the current core-8-4-branch code correct in terms of this bug report? I'm looking for someone to assert that this bug has not be re-introduced. It's a simple test to run on a Window system, but I don't have one handy to test myself. davygrvy added on 2004-02-25 09:52:15: Logged In: YES user_id=7549 The patch is incorrect and was removed about a month ago. As per the rules of quoting for parse_cmdline() found in msvcrt.dll, '{' doesn't require quoting. And if it is quoted, pass-through will break as tested by winpipe-7.* and winpipe- 8.* and all other programs linked to msvcrt.dll Please send this bug to CYGWIN's tools maintainer. The bug is in their cat.exe or general commandline parsing routine in their runtime. hobbs added on 2004-02-25 08:30:20: Logged In: YES user_id=72656 This breaks when users create command lines that have arguments which include { that aren't filenames. andreas_kupries added on 2002-06-18 03:06:34: Logged In: YES user_id=75003 Patch committed to head. andreas_kupries added on 2002-06-18 03:04:55: Logged In: YES user_id=75003 Applied and used the test patch to verify that the behaviour is different for Linux and Windows. I agree that the Win* behaviour is a bug. Applied the patch fixing it, compiles ok. Testsuite: New test is ok now, no new failed tests. Patch is accepted. vincentdarley added on 2002-06-14 18:46:31: File Deleted - 22768: File Added - 25101: exec.test.patch Logged In: YES user_id=32170 attaching test patch vincentdarley added on 2002-06-14 18:45:39: File Added - 25100: tclWinPipe.c.diff Logged In: YES user_id=32170 This is then, presumably a bug in 'BuildCommandLine' in tclWinPipe.c, since the argc/argv values have simply been passed along from Tcl. BuildCommandLine(execPath, argc, argv, &cmdLine); if ((*tclWinProcs->createProcessProc)(NULL, (TCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo, &procInfo) == 0) { ... Had a look, and the fix is easy. Please see attached patch for fix and test of the fix. I've tested the fix and Tcl passes all tests, so I think this should be applied to cvs head. dgp added on 2002-05-11 01:34:06: Logged In: YES user_id=80530 Most of these appear to be due to a bug (?) in [exec] on Windows. The command exec cat $filename should pass $filename as a single argument to cat, no matter what funny characters are contained in $filename. I'm reassigning this over to "Channel Types" where [exec] lives. I will commit a fix for the [regexp] problem, as well as the other test failures I saw on Linux when I ran a similar test (all of the list quoting issues on matching expected results in the test suite). vincentdarley added on 2002-05-09 18:25:05: File Added - 22768: testfunnychars.patch |