Tcl Source Code

View Ticket
Login
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

Attachments: