• tclvfs: vfs::zip discards leading dots in filenames

    From Ralf Fassel@21:1/5 to All on Mon May 9 19:06:01 2022
    Ticket: https://core.tcl-lang.org/tclvfs/tktview/887778e1916c934f8a303a6337a10869d0ac2963

    tcl 8.6.12

    tclvfs module vfs::zip discards the leading dot of files stored in an
    ZIP archive:

    # create ZIP archive
    $ touch .foo bar
    $ zip test.zip .foo bar

    open via vfs::zip

    $ tclsh
    % package require vfs::zip
    1.0.4
    % vfs::zip::Mount test.zip test.zip
    file3
    % glob test.zip/*
    test.zip/bar test.zip/foo

    As you can see, '.foo' became 'foo' in vfs::zip

    % open test.zip/bar
    rc0
    % open test.zip/.foo
    couldn't open "test.zip/.foo": no such file or directory
    % open test.zip/foo
    rc1

    But the ZIP really holds '.foo', not 'foo'

    % exec unzip -l test.zip
    Archive: test.zip
    Length Date Time Name
    --------- ---------- ----- ----
    0 2022-05-09 18:15 .foo
    0 2022-05-09 18:15 bar
    --------- -------
    0 2 files


    This is due to the following code in

    proc zip::TOC {...} {
    ...
    set sb(name) [string trimleft $sb(name) "./"]

    which looks suspiciously like someone was trying to strip off the "./"
    prefix sequence from names like "./foo"

    Cleary stripping off the dot from a file name is plain wrong.

    Proposed patch

    --- zipvfs.tcl 2022/05/09 17:00:22 1.1
    +++ zipvfs.tcl 2022/05/09 17:00:28
    @@ -546,7 +546,9 @@
    set sb(name) [encoding convertfrom utf-8 $sb(name)]
    set sb(comment) [encoding convertfrom utf-8 $sb(comment)]
    }
    - set sb(name) [string trimleft $sb(name) "./"]
    + if {[string range $sb(name) 0 1] == "./"} {
    + set sb(name) [string range $sb(name) 2 end]
    + }
    set parent [file dirname $sb(name)]
    if {$parent == "."} {set parent ""}
    lappend cbdir([string tolower $parent]) [file tail [string trimright $sb(name) /]]


    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to Ralf Fassel on Mon May 9 14:05:13 2022
    On 5/9/22 1:06 PM, Ralf Fassel wrote:

    This is due to the following code in

    proc zip::TOC {...} {
    ...
    set sb(name) [string trimleft $sb(name) "./"]

    which looks suspiciously like someone was trying to strip off the "./"
    prefix sequence from names like "./foo"

    Cleary stripping off the dot from a file name is plain wrong.



    Hello,

    You are correct. "./" prefix in a file name resolves to the file name
    itself: the "." means in the current directory, and the slash is the
    usual file separator.

    However, it looks like a bug, to be honest. The command "string
    trimleft" will trim *any* characters in its second argument. I suspect
    the error is that the sequencing of those characters matters, which in
    reality, does not. There are several file commands to deal with such
    cases.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)