Ticket UUID: | 956063 | |||
Title: | [file dirname] broken | |||
Type: | Bug | Version: | obsolete: 8.5a1 | |
Submitter: | dgp | Created on: | 2004-05-18 16:47:51 | |
Subsystem: | 37. File System | Assigned To: | kennykb | |
Priority: | 8 | Severity: | ||
Status: | Closed | Last Modified: | 2004-05-19 23:58:09 | |
Resolution: | Fixed | Closed By: | vincentdarley | |
Closed on: | 2004-05-19 16:58:09 | |||
Description: |
% info patch 8.5a1 % file mkdir foo % set f [open [file join foo bar.tcl] w] file3 % puts $f { puts SOURCE:[info script] puts NORMALIZED:[file normalize [info script]] puts HOME:[file dirname [file normalize [info script]]] } % close $f % source [file join foo bar.tcl] SOURCE:foo/bar.tcl NORMALIZED:/home/dgp/foo/bar.tcl HOME:/home/dgp Of course, I expect to see HOME:/home/dgp/foo This is a very common way to set up paths relative to a script being [source]d. It must be reliably correct. | |||
User Comments: |
vincentdarley added on 2004-05-19 23:58:09:
Logged In: YES user_id=32170 Checked out both patches, and I think on balance I prefer mine-- that code in Tcl_FSJoinPath was designed to handle the case that dgp's patch is excluding, which I think just removes a possible efficiency benefit. vincentdarley added on 2004-05-19 22:43:08: File Added - 87657: filedirname.diff Logged In: YES user_id=32170 I can get the problem to occur on windows, quite simply: test cmdAH-8.46 {Tcl_FileObjCmd: dirname} { set f [file normalize [info nameof]] file exists $f set res1 [file dirname [file join $f foo/bar]] set res2 [file dirname "${f}/foo/bar"] if {$res1 eq $res2} { set res "ok" } else { set res "file dirname problem, $res1, $res2 not equal" } set res } {ok} I've attached an alternative patch which changes the behaviour of TclPathPart. For what it's worth, TclPathPart's optimization is what really introduced the bug so the obvious place to me to fix it is there. However, I'm interested to look at your patch and see how you fixed it in a different way (just no time today). dgp added on 2004-05-19 04:57:09: File Added - 87578: 956063.patch Logged In: YES user_id=80530 Here's a patch. Not also that this patch makes clear why the failure doesn't show up on Windows. The flaw is in a Unix-only optimization. Please test. dgp added on 2004-05-19 04:48:39: Logged In: YES user_id=80530 It appears that the cleanest place to correct this is within Tcl_FSJoinPath(). That appears to be the only place where TclNewFSPathObj() gets called with a possibility that addStrRep might contain separators. Also, there's already fallback code there to deal with the failing case. dgp added on 2004-05-19 03:22:40: Logged In: YES user_id=80530 However, [file join] calls Tcl_FSJoinToPath() directly, and it has no such restriction, so perhaps the docs are wrong, or perhaps I don't correctly understand what a "path segement" is. dgp added on 2004-05-19 03:20:54: Logged In: YES user_id=80530 NOTE: Both Tcl_FSJoinPath and Tcl_FSJoinToPath are explicitly documented to accept a list and array, respectively, of path segments. It is a bug to call them with one of those segments containing a path separator. dgp added on 2004-05-19 03:06:03: Logged In: YES user_id=80530 TclPathPart notices when the PATHFLAGS is not 0 (presumably is TCLPATH_APPENDED) and based on that assumes that the cwdPtr is the dirname and the normPathPtr is the tail. That would be a safe assumption if TclNewFSPathObj forbade path separators in its addStrRep argument, but it doesn't appear to do so. Since these are internal routines, all would also be ok, if simply by convention, nothing called TclNewFSPathObj with a separator in the addStrRep argument. However, in this test script, the call: TclNewFSPathObj (dirPtr=0x8071070, addStrRep=0x8081b30 "foo/bar.tcl", len=11) at ../unix/../generic/tclPathObj.c:109 takes place. I think the proper fix here requires a more precise spec. of what assumptions different PATHFLAGS values impose, and a careful audit the the relevant routines preserve those specs. vincentdarley added on 2004-05-19 00:59:02: Logged In: YES user_id=32170 I suspect TclPathPart in tclPathObj.c, for the special case of a path which is the result of a [file join]. Don't have time to look into it at the moment, but that's probably the culprit. dgp added on 2004-05-19 00:00:39: Logged In: YES user_id=80530 change to set path [file normalize [info script]] puts HOME:[file dirname [string range " $path" 1 end]] and that works, so something is broken in the cached normalized path value. Forcing the shimmer fixes it. dgp added on 2004-05-18 23:57:14: Logged In: YES user_id=80530 Bug appears to be on Unix systems only. Works correctly on Windows. Suspect errors in TclpObjNormalizePath() or related code in the unix/ source. dgp added on 2004-05-18 23:48:39: Logged In: YES user_id=80530 BTW, this bug appears to be new in Tcl 8.5. Tcl 8.4.6 behaves correctly on this test. |