Menu

#2778 file isdirectory causing variable corruption?

obsolete: 8.4.6
closed-fixed
5
2004-07-02
2004-06-25
No

After a call to "file isdirectory" certain paths no longer
seem to exist. I observed this with Tcl 8.4.x on Win32,
but not with Tcl 8.3.x. Something must be happening to
the variable that is passed to file isdirectory. If I make
sure that it's just a temporary string (as in TestFind2)
the problem does not occur.

Example:

proc TestFind1 {d f} {
set r1 [file exists [file join $d $f]]
puts "TF1: [file join $d $f] found: $r1"
puts "TF1: is dir a dir? [file isdirectory $d]"
set r2 [file exists [file join $d $f]]
puts "TF1: [file join $d $f] found: $r2"
puts ""
}
proc TestFind2 {d f} {
set r1 [file exists [file join $d $f]]
puts "TF2: [file join $d $f] found: $r1"
puts "TF2: is dir a dir? [file isdirectory [file join $d]]"
set r2 [file exists [file join $d $f]]
puts "TF2: [file join $d $f] found: $r2"
puts ""
}

file mkdir [file join a b c]
TestFind1 a [file join b . c]
TestFind2 a [file join b . c]

My output:
TF1: a/b/./c found: 1
TF1: is dir a dir? 1
TF1: a/b/./c found: 0

TF2: a/b/./c found: 1
TF2: is dir a dir? 1
TF2: a/b/./c found: 1

Discussion

  • Joe Mistachkin

    Joe Mistachkin - 2004-06-28

    Logged In: YES
    user_id=113501

    Results from NON-THREADED build of core-8-4-branch on
    FreeBSD 4.10-STABLE:

    TF1: a/b/./c found: 1
    TF1: is dir a dir? 1
    TF1: a/b/./c found: 1

    TF2: a/b/./c found: 1
    TF2: is dir a dir? 1
    TF2: a/b/./c found: 1

    Results from THREADED build of core-8-4-branch on FreeBSD
    4.10-STABLE:

    TF1: a/b/./c found: 1
    TF1: is dir a dir? 1
    TF1: a/b/./c found: 1

    TF2: a/b/./c found: 1
    TF2: is dir a dir? 1
    TF2: a/b/./c found: 1

    Results from NON-THREADED build of HEAD on FreeBSD 4.10-
    STABLE:

    TF1: a/b/./c found: 1
    TF1: is dir a dir? 1
    TF1: a/b/./c found: 1

    TF2: a/b/./c found: 1
    TF2: is dir a dir? 1
    TF2: a/b/./c found: 1

    Results from THREADED build of HEAD on FreeBSD 4.10-
    STABLE:

    TF1: a/b/./c found: 1
    TF1: is dir a dir? 1
    TF1: a/b/./c found: 1

    TF2: a/b/./c found: 1
    TF2: is dir a dir? 1
    TF2: a/b/./c found: 1

     
  • Vince Darley

    Vince Darley - 2004-06-28
    • status: open --> pending
     
  • Vince Darley

    Vince Darley - 2004-06-28

    Logged In: YES
    user_id=32170

    It looks from mistachkin's comments that this, if it was a
    bug, has been fixed in both 8.4 and 8.5 branches.

     
  • Vince Darley

    Vince Darley - 2004-06-28
    • status: pending --> pending-out-of-date
     
  • Joe Mistachkin

    Joe Mistachkin - 2004-06-28

    Logged In: YES
    user_id=113501

    Is there any way we can find out what was causing this and
    how it was fixed (in case the root problem has just been
    obscured and not really fixed)?

    Submitter: Was this in a released build and if so, what build?

     
  • Alexander James Pasadyn

    Logged In: YES
    user_id=1055638

    My earlier tests were from the 8.4.5 and 8.4.6 releases on
    Windows 2000, using threaded builds from both msys-mingw
    and MSVC. I just tried the same test using the 8.5a1 release
    (threaded builds on both compilers), and I got the following
    output (even worse than before):

    TF1: a/b/./c found: 1
    TF1: is dir a dir? 1
    TF1: a/b/./c found: 0

    TF2: a/b/./c found: 1
    TF2: is dir a dir? 1
    TF2: a/b/./c found: 0

    This is really strange. The way I found this was that I had a
    set of scripts that was assembling paths from multiple
    sources, and when I upgraded from 8.3 to 8.4 it stopped
    working. This is the smallest test that still showed the
    problem.

    I cannot access the CVS repository from here, but this
    evening I can pull it, and I can test using Linux as well.
    Maybe this only happens on Win32.

     
  • Alexander James Pasadyn

    • status: pending-out-of-date --> open-out-of-date
     
  • Donal K. Fellows

    • priority: 5 --> 9
     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902

    Sounds offhand like something is getting cached in the
    internal rep of $d that is semantics-altering. This is
    really really bad.

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902

    BTW, the fact that it doesn't happen under Joe Mistachkin's
    config might just mean that the problem is Win specific.

    (It works for me with 8.4.1, but that doesn't necessarily
    mean very much except for the fact that I ought to upgrade
    sometime!)

     
  • Vince Darley

    Vince Darley - 2004-06-28

    Logged In: YES
    user_id=32170

    I'll look into this. I can reproduce it, so shouldn't be
    too hard to solve. Only subtlety is that it fails in
    different ways on 8.4 vs 8.5 (8.4 = 110 111, 8.5 = 110 110)

     
  • Alexander James Pasadyn

    Logged In: YES
    user_id=1055638

    Just FYI: looks like 8.4.1 acts normally (111 111) and 8.4.2 is
    when the problem started showing up (110 111)

     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2004-06-28

    Logged In: YES
    user_id=72656

    Confirmed that this is a bug in 8-4-head and HEAD of
    2004-06-28 on Windows, but not on Linux (and that HEAD fails
    with 110 110 as Vince noted).

     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2004-06-28
    • status: open-out-of-date --> open
     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902

    I suspect that the work done on path normalization fixes in
    the HEAD allows the fault results to propagate further, but
    that the problem is not that at all.

    Currently, #1 suspicion points at bad information getting
    attached to the Tcl_Obj inside $d, and that this bad info is
    coming from a mistake in the Win native FS.

     
  • Vince Darley

    Vince Darley - 2004-06-29

    Logged In: YES
    user_id=32170

    In Tcl 8.5 the problem is caused here in tclPathObj.c (line
    1590):

    Tcl_AppendObjToObj(copy, fsPathPtr->normPathPtr);
    /*
    * Normalize the combined string, but only starting after
    * the end of the previously normalized 'dir'. This should
    * be much faster! We use 'cwdLen-1' so that we are
    * already pointing at the dir-separator that we know about.
    * The normalization code will actually start off directly
    * after that separator.
    */
    TclFSNormalizeToUniquePath(interp, copy, cwdLen-1,
    (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL));

    where we are calling TclFSNormalizeToUniquePath contrary to
    its documentation, with a string which may still contain
    './' or '../' sequences (from fsPathPtr->normPathPtr).

    It's not really clear where the fix should be -- perhaps the
    special 'joined' pathObj representation shouldn't be allowed
    if the second part has '.' or '..' sequences, or else this
    bit of code shown above should be cleverer, or else the
    native normalization code should actually cope with the
    existence of such sequences.

    The problem occurs because the TclpObjNormalizePath routine
    tries to find the 'long, unique path name' for each path
    segment (one by one), and therefore turns 'a/b/./c' into
    'a/b/b/c' (since the real name of '.' is 'b' in this case).
    Similar bugs exist with '..'.

    Lastly I should add that turning on 'TclNORM_LONG_PATH' in
    tclWinFile.c seems to fix the problem, at least for the
    cases I've tested (it activates a different version of the
    normalization), but I think that other cases might still
    trigger a failure.

    Anyway, this is too hard for a quick fix, so it'll take me
    some time (i.e. until I have some time) -- others are very
    welcome to look into it.

     
  • Vince Darley

    Vince Darley - 2004-06-29

    diff -u with windows eols

     
  • Vince Darley

    Vince Darley - 2004-06-29

    Logged In: YES
    user_id=32170

    Here's a proposed patch for Tcl 8.5. Something similar (if
    not identical) should work for 8.4

     
  • Alexander James Pasadyn

    Logged In: YES
    user_id=1055638

    That patch seems to work for me with both the 8.4 and 8.5
    versions. I didn't try anything other than that test yet
    though, so hopefully it doesn't break anything else.

     
  • Vince Darley

    Vince Darley - 2004-06-30
    • priority: 9 --> 5
    • status: open --> open-fixed
     
  • Vince Darley

    Vince Darley - 2004-06-30

    Logged In: YES
    user_id=32170

    Checked in fix for Tcl 8.5.

    Leaving open since fix still needs applying to 8.4

     
  • Vince Darley

    Vince Darley - 2004-07-02
    • status: open-fixed --> closed-fixed
     
  • Vince Darley

    Vince Darley - 2004-07-02

    Logged In: YES
    user_id=32170

    Backported to 8.4 branch.

     
MongoDB Logo MongoDB