From 1c55263e3653cb2ceb1d9e1574dc577faf3b0d11 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 18 Aug 2024 17:20:25 +0000 Subject: Backport: Consolidated zipfs changes --- doc/interp.n | 2 +- doc/tclsh.1 | 16 +++++++++------ doc/zipfs.3 | 20 +++++++++++-------- doc/zipfs.n | 43 ++++++++++++++++++++++------------------ generic/tclBasic.c | 13 ++++++++++-- generic/tclZipfs.c | 16 +++++++-------- tests/interp.test | 2 +- tests/zipfs.test | 58 ++++++++++++++++++++++++++---------------------------- 8 files changed, 94 insertions(+), 76 deletions(-) diff --git a/doc/interp.n b/doc/interp.n index d1b6881..75b03c7 100644 --- a/doc/interp.n +++ b/doc/interp.n @@ -658,7 +658,7 @@ creates a safe interpreter: \fBcd\fR \fBencoding\fR \fBexec\fR \fBexit\fR \fBfconfigure\fR \fBfile\fR \fBglob\fR \fBload\fR \fBopen\fR \fBpwd\fR \fBsocket\fR \fBsource\fR -\fBunload\fR +\fBunload\fR \fBzipfs\fR .DE These commands can be recreated later as Tcl procedures or aliases, or re-exposed by \fBinterp expose\fR. diff --git a/doc/tclsh.1 b/doc/tclsh.1 index c75076f..894b21e 100644 --- a/doc/tclsh.1 +++ b/doc/tclsh.1 @@ -156,15 +156,19 @@ incomplete commands. .SH "STANDARD CHANNELS" .PP See \fBTcl_StandardChannels\fR for more explanations. -.SH ZIPVFS +.SH "ZIPFS VIRTUAL FILE SYSTEM" .PP When a zipfile is concatenated to the end of a \fBtclsh\fR, on startup -the contents of the zip archive will be mounted under the virtual file -system \fB//zipfs:/\fR. If a top level directory \fBtcl_library\fR is +the contents of the zip archive will be mounted under a virtual file +system (VFS). The root of that VFS can be retrieved using the \fBzipfs root\fR +command. The zip archive is mounted under the \fBapp\fR directory within the +VFS. If a file named \fBmain.tcl\fR is present in the top +level directory of the zip archive, it will be sourced instead of +tclsh's normal command line handing. If a top level directory \fBtcl_library\fR is present in the zip archive, it will become the directory loaded as -env(TCL_LIBRARY). If a file named \fBmain.tcl\fR is present in the top -level directory of the zip archive, it will be sourced instead of the -shell's normal command line handing. +env(TCL_LIBRARY). If the file \fBtcl_library/init.tcl\fR is present in the zip +archive, the \fBtcl_library\fR global variable in the initial Tcl interpreter +is set to \fBapp/tcl_library\fR. .PP Only one zipfile can be concatenated to the end of executable image (tclsh, or wish). However, if multiple zipfiles are diff --git a/doc/zipfs.3 b/doc/zipfs.3 index 31af7d7..589dc86 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -60,17 +60,18 @@ initialization procedures, taking into account available ZIP archives as follows: .IP [1] If the current application has a mountable ZIP archive, that archive is -mounted under \fIZIPFS_VOLUME\fBapp\fR as a read-only Tcl virtual file -system. \fIZIPFS_VOLUME\fR is \fB//zipfs:/\fR on all platforms. +mounted under \fIZIPFS_VOLUME\fB/app\fR as a read-only Tcl virtual file +system (VFS). The value of \fIZIPFS_VOLUME\fR can be retrieved using the +Tcl command \fBzipfs root\fR. .IP [2] If a file named \fBmain.tcl\fR is located in the root directory of that file -system (i.e., at \fIZIPROOT\fB/app/main.tcl\fR after the ZIP archive is +system (i.e., at \fIZIPFS_VOLUME\fB/app/main.tcl\fR after the ZIP archive is mounted as described above) it is treated as the startup script for the process. .IP [3] -If the file \fIZIPROOT\fB/app/tcl_library/init.tcl\fR is present, the +If the file \fIZIPFS_VOLUME\fB/app/tcl_library/init.tcl\fR is present, the \fBtcl_library\fR global variable in the initial Tcl interpreter is set to -\fIZIPROOT\fB/app/tcl_library\fR. +\fIZIPFS_VOLUME\fB/app/tcl_library\fR. .IP [4] If the directory \fBtcl_library\fR was not found in the main application mount, the system will then search for it as either a VFS attached to the @@ -81,7 +82,7 @@ example, the Tcl 8.7.2 release would be searched for in a file \fBlibtcl_8_7_2.zip\fR.) That archive, if located, is also mounted read-only. .PP On Windows, \fBTclZipfs_AppHook\fR has a slightly different signature, since -it uses WCHAR instead of char. As a result, it requires your application to +it uses WCHAR instead of char. As a result, it requires the application to be compiled with the UNICODE preprocessor symbol defined (e.g., via the \fB\-DUNICODE\fR compiler flag). .PP @@ -97,8 +98,11 @@ specified (i.e. non-NULL), the function mounts the ZIP archive \fIzipname\fR on the mount point given in \fImountpoint\fR. If \fIpassword\fR is not NULL, it should point to the NUL terminated password protecting the archive. If not under the zipfs file system root, \fImountpoint\fR is normalized with respect to it. -For example, a mount point passed as either \fBmt\fR \fB/mt\fR would be -normalized to \fB//zipfs:/mt\fR. An error is raised if the mount point includes +For example, a mount point passed as either \fBmt\fR or \fB/mt\fR would be +normalized to \fB//zipfs:/mt\fR, given that \fIZIPFS_VOLUME\fR as returned +by \fBzipfs root\fR is +.QW //zipfs:/ . +An error is raised if the mount point includes a drive or UNC volume. On success, \fIinterp\fR's result is set to the normalized mount point path. .PP diff --git a/doc/zipfs.n b/doc/zipfs.n index 9ac283d..f4e2949 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -14,24 +14,21 @@ zipfs \- Mount and work with ZIP files within Tcl .SH SYNOPSIS .nf -\fBpackage require tcl::zipfs \fR?\fB1.0\fR? - \fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR ?\fIZIPFS\fR? \fBzipfs exists\fI filename\fR \fBzipfs find\fI directoryName\fR \fBzipfs info\fI filename\fR \fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR? -\fBzipfs lmkimg\fI outfile inlist\fR ?\fIpassword infile\fR? +\fBzipfs lmkimg\fI outfile inlist\fR ?\fIpassword\fR? ?\fIinfile\fR? \fBzipfs lmkzip\fI outfile inlist\fR ?\fIpassword\fR? \fBzipfs mkimg\fI outfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? \fBzipfs mkkey\fI password\fR \fBzipfs mkzip\fI outfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? \fBzipfs mount\fR ?\fIzipfile\fR? ?\fImountpoint\fR? ?\fIpassword\fR? +\fBzipfs mountdata\fR \fIdata\fR \fImountpoint\fR \fBzipfs root\fR \fBzipfs unmount\fI mountpoint\fR .fi -'\" The following subcommand is *UNDOCUMENTED* -'\" \fBzipfs mount_data\fR ?\fIdata\fR ?\fImountpoint\fR?? .BE .SH DESCRIPTION .PP @@ -132,9 +129,11 @@ specified as an empty string, it is defaulted to the \fB[zipfs root]\fR. The command returns the normalized mount point path. .PP If not under the zipfs file system root, \fImountpoint\fR is normalized with -respect to it. For example, a mount point passed as either \fBmt\fR \fB/mt\fR -would be normalized to \fB//zipfs:/mt\fR. An error is raised if the mount point -includes a drive or UNC volume. +respect to it. For example, a mount point passed as either \fBmt\fR or \fB/mt\fR +would be normalized to \fB//zipfs:/mt\fR (given that \fBzipfs root\fR +returns +.QW //zipfs:/ ). +An error is raised if the mount point includes a drive or UNC volume. .PP \fBNB:\fR because the current working directory is a concept maintained by the operating system, using \fBcd\fR into a mounted archive will only work in the @@ -143,15 +142,18 @@ uses direct access to the OS rather than through Tcl's filesystem API, it will not see the current directory as being inside the mount and will not be able to access the files inside the mount). .RE +.\" METHOD: mountdata +.TP +\fBzipfs mountdata\fR \fIdata\fR \fImountpoint\fR +Mounts the ZIP archive content \fIdata\fR as a Tcl virtual filesystem at +\fImountpoint\fR. .\" METHOD: root .TP \fBzipfs root\fR . Returns a constant string which indicates the mount point for zipfs volumes -for the current platform. -This value is -.QW \fB//zipfs:/\fR -on most platforms. +for the current platform. User should not rely on the mount point being +the same constant string for all platforms. .\" METHOD: unmount .TP \fBzipfs unmount \fImountpoint\fR @@ -170,7 +172,7 @@ Creates a ZIP archive file named \fIoutfile\fR from the contents of the input directory \fIindir\fR (contained regular files only) with optional ZIP password \fIpassword\fR. While processing the files below \fIindir\fR the optional file name prefix given in \fIstrip\fR is stripped off the beginning -of the respective file name. When stripping, it is common to remove either +of the respective file name if non-empty. When stripping, it is common to remove either the whole source directory name or the name of its parent directory. .RS .PP @@ -189,7 +191,7 @@ command, as they behave identically here. If the \fIinfile\fR parameter is specified, this file is prepended in front of the ZIP archive, otherwise the file returned by \fBinfo nameofexecutable\fR (i.e., the executable file of the running process) is used. If the -\fIpassword\fR parameter is not empty, an obfuscated version of that password +\fIpassword\fR parameter is not the empty string, an obfuscated version of that password (see \fBzipfs mkkey\fR) is placed between the image and ZIP chunks of the output file and the contents of the ZIP chunk are protected with that password. @@ -214,9 +216,6 @@ the user's responsibility to preserve the attached archive by first extracting it to a temporary location, and then add whatever additional files desired, before creating and attaching the new archive to the new application. -.PP -\fBCaution:\fR highly experimental, not usable on Android, only partially -tested on Linux and Windows. .RE .\" METHOD: mkkey .TP @@ -226,7 +225,7 @@ Given the clear text \fIpassword\fR argument, an obfuscated string version is returned with the same format used in the \fBzipfs mkimg\fR command. .\" METHOD: lmkimg .TP -\fBzipfs lmkimg\fI outfile inlist\fR ?\fIpassword infile\fR? +\fBzipfs lmkimg\fI outfile inlist\fR ?\fIpassword\fR? ?\fIinfile\fR? . This command is like \fBzipfs mkimg\fR, but instead of an input directory, \fIinlist\fR must be a Tcl list where the odd elements are the names of files @@ -240,6 +239,11 @@ This command is like \fBzipfs mkzip\fR, but instead of an input directory, \fIinlist\fR must be a Tcl list where the odd elements are the names of files to be copied into the archive, and the even elements are their respective names within that archive. +.SH "NOTE" +.PP +The current syntax for certain subcommands using multiple optional parameters might +change in the future to support an \fI?-option value?\fR pattern instead. +Therfore, the current syntax should not be considered stable. .SH "EXAMPLES" .PP Mounting an ZIP archive as an application directory and running code out of it @@ -307,7 +311,8 @@ close $f # Launch the executable, printing its output to stdout exec $img >@stdout -# prints: \fIHi. This is //zipfs:/app/main.tcl\fR +# prints the following line assuming [zipfs root] returns "//zipfs:/": +# \fIHi. This is //zipfs:/app/main.tcl\fR .CE .SH "SEE ALSO" tclsh(1), file(n), zipfs(3), zlib(n) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index e6dde32..e76a3b6 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -471,14 +471,23 @@ static const UnsafeEnsembleInfo unsafeEnsembleCommands[] = { {"process", "status"}, {"process", "purge"}, {"process", "autopurge"}, - /* [zipfs] has MANY unsafe commands! */ + /* + * [zipfs] perhaps has some safe commands. But like file make it inaccessible + * until they are analyzed to be safe. + */ + {"zipfs", NULL}, + {"zipfs", "canonical"}, + {"zipfs", "exists"}, + {"zipfs", "info"}, + {"zipfs", "list"}, {"zipfs", "lmkimg"}, {"zipfs", "lmkzip"}, {"zipfs", "mkimg"}, {"zipfs", "mkkey"}, {"zipfs", "mkzip"}, {"zipfs", "mount"}, - {"zipfs", "mount_data"}, + {"zipfs", "mountdata"}, + {"zipfs", "root"}, {"zipfs", "unmount"}, {NULL, NULL} }; diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index c288b3f..d8ce9ec 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2644,7 +2644,7 @@ ZipFSMountObjCmd( * * ZipFSMountBufferObjCmd -- * - * This procedure is invoked to process the [zipfs mount_data] command. + * This procedure is invoked to process the [zipfs mountdata] command. * * Results: * A standard Tcl result. @@ -6221,16 +6221,15 @@ TclZipfs_Init( {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 1}, {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 1}, {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 1}, - /* The 4 entries above are not available in safe interpreters */ {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 1}, - {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 1}, + {"mountdata", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 1}, {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 1}, {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 1}, - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 0}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 0}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 0}, - {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 0}, - {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 0}, + {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, + {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, + {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, + {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, + {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} }; static const char findproc[] = @@ -6286,7 +6285,6 @@ TclZipfs_Init( TclDictPutString(NULL, mapObj, "find", "::tcl::zipfs::find"); Tcl_CreateObjCommand(interp, "::tcl::zipfs::tcl_library_init", ZipFSTclLibraryObjCmd, NULL, NULL); - Tcl_PkgProvide(interp, "tcl::zipfs", "2.0"); } return TCL_OK; #else /* !HAVE_ZLIB */ diff --git a/tests/interp.test b/tests/interp.test index f190d62..824bd97 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -20,7 +20,7 @@ catch [list package require -exact tcl::test [info patchlevel]] testConstraint testinterpdelete [llength [info commands testinterpdelete]] -set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:encoding:system tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:home tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempdir tcl:file:tempfile tcl:file:tildeexpand tcl:file:type tcl:file:volumes tcl:file:writable tcl:info:cmdtype tcl:info:nameofexecutable tcl:process:autopurge tcl:process:list tcl:process:purge tcl:process:status tcl:zipfs:lmkimg tcl:zipfs:lmkzip tcl:zipfs:mkimg tcl:zipfs:mkkey tcl:zipfs:mkzip tcl:zipfs:mount tcl:zipfs:mount_data tcl:zipfs:unmount unload} +set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:encoding:system tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:home tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempdir tcl:file:tempfile tcl:file:tildeexpand tcl:file:type tcl:file:volumes tcl:file:writable tcl:info:cmdtype tcl:info:nameofexecutable tcl:process:autopurge tcl:process:list tcl:process:purge tcl:process:status tcl:zipfs:canonical tcl:zipfs:exists tcl:zipfs:info tcl:zipfs:list tcl:zipfs:lmkimg tcl:zipfs:lmkzip tcl:zipfs:mkimg tcl:zipfs:mkkey tcl:zipfs:mkzip tcl:zipfs:mount tcl:zipfs:mountdata tcl:zipfs:root tcl:zipfs:unmount unload zipfs} proc _ms_limit_args {ms {t0 {}}} { if {$t0 eq {}} { set t0 [clock milliseconds] } diff --git a/tests/zipfs.test b/tests/zipfs.test index b988898..d4e516f 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -27,9 +27,6 @@ set CWD [pwd] set tmpdir [file join $CWD tmp] file mkdir $tmpdir -test zipfs-0.0 {zipfs basics} -constraints zipfs -body { - package require tcl::zipfs -} -result {2.0} test zipfs-0.1 {zipfs basics} -constraints zipfs -body { expr {${ziproot} in [file volumes]} } -result 1 @@ -155,7 +152,7 @@ test zipfs-2.8 {zipfs mkzip} -constraints zipfs -body { fconfigure $fin -translation binary set dat [read $fin] close $fin - zipfs mount_data $dat def + zipfs mountdata $dat def zipfs list -glob ${ziproot}def/cp850.* } -cleanup { cd $CWD @@ -211,7 +208,7 @@ test zipfs-3.1 {zipfs in child interpreters} -constraints zipfs -setup { } } -returnCodes error -cleanup { interp delete $interp -} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, or unmount} +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mountdata, root, or unmount} test zipfs-3.2 {zipfs in child interpreters} -constraints zipfs -setup { set interp [interp create] } -body { @@ -229,16 +226,17 @@ test zipfs-3.3 {zipfs in child interpreters} -constraints zipfs -setup { } } -returnCodes error -cleanup { interp delete $safe -} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, or unmount} -test zipfs-3.4 {zipfs in child interpreters} -constraints zipfs -setup { +} -result {invalid command name "zipfs"} + +test zipfs-3.4 {zipfs in safe interpreters} -constraints zipfs -setup { set safe [interp create -safe] } -body { interp eval $safe { - zipfs mkzip + zipfs } } -returnCodes error -cleanup { interp delete $safe -} -result {not allowed to invoke subcommand mkzip of zipfs} +} -result {invalid command name "zipfs"} test zipfs-4.1 {zipfs lmkimg} -constraints zipfs -setup { set baseImage [makeFile "return sourceWorking\n\x1A" base] @@ -350,17 +348,17 @@ test zipfs-4.5 {zipfs lmkimg: making image from mounted} -constraints zipfs -set removeFile $addFile } -result [list ${ziproot}/ziptest/test/add.tcl ${ziproot}/ziptest/test/ok.tcl] -test zipfs-5.1 {zipfs mount_data: short data} -constraints zipfs -body { - zipfs mount_data {} gorp +test zipfs-5.1 {zipfs mountdata: short data} -constraints zipfs -body { + zipfs mountdata {} gorp } -returnCodes error -result {illegal file size} -test zipfs-5.2 {zipfs mount_data: short data} -constraints zipfs -body { - zipfs mount_data gorpGORPgorp gorp +test zipfs-5.2 {zipfs mountdata: short data} -constraints zipfs -body { + zipfs mountdata gorpGORPgorp gorp } -returnCodes error -result {illegal file size} -test zipfs-5.3 {zipfs mount_data: short data} -constraints zipfs -body { +test zipfs-5.3 {zipfs mountdata: short data} -constraints zipfs -body { set data PK\x03\x04..................................... append data PK\x01\x02..................................... append data PK\x05\x06..................................... - zipfs mount_data $data gorp + zipfs mountdata $data gorp } -returnCodes error -result {archive directory truncated} test zipfs-6.1 {zipfs mkkey} -constraints zipfs -body { @@ -448,8 +446,8 @@ namespace eval test_ns_zipfs { return } set data [readbin $zippath] - test zipfs-mount_data-$id $id -body { - list [catch {zipfs mount_data $data $defMountPt} message] \ + test zipfs-mountdata-$id $id -body { + list [catch {zipfs mountdata $data $defMountPt} message] \ [string match $messagePattern $message] \ [mounttarget $defMountPt] } -cleanup { @@ -470,8 +468,8 @@ namespace eval test_ns_zipfs { } -result [list 1 $zippath $zippath] {*}$args # Mount memory buffer - test zipfs-mount_data-$id "zipfs mount_data $id" -body { - set canon [zipfs mount_data [readbin $zippath] $mountpoint] + test zipfs-mountdata-$id "zipfs mountdata $id" -body { + set canon [zipfs mountdata [readbin $zippath] $mountpoint] list [file exists [file join $canon $checkPath]] \ [zipfs mount $canon] [zipfs mount $mountpoint] } -cleanup { @@ -481,7 +479,7 @@ namespace eval test_ns_zipfs { } testnumargs "zipfs mount" "" "?zipfile? ?mountpoint? ?password?" - testnumargs "zipfs mount_data" "data mountpoint" "" + testnumargs "zipfs mountdata" "data mountpoint" "" # Not supported zip files testbadmount non-existent-file nosuchfile.zip "couldn't open*nosuchfile.zip*no such file or directory" @@ -498,14 +496,14 @@ namespace eval test_ns_zipfs { test zipfs-mount-on-drive "Mount point include drive" -body { zipfs mount [zippath test.zip] C:/foo } -result {Invalid mount path "C:/foo"} -returnCodes error -constraints win - test zipfs-mount_data-on-drive "Mount point include drive" -body { - zipfs mount_data [readbin [zippath test.zip]] C:/foo + test zipfs-mountdata-on-drive "Mount point include drive" -body { + zipfs mountdata [readbin [zippath test.zip]] C:/foo } -result {Invalid mount path "C:/foo"} -returnCodes error -constraints win test zipfs-mount-on-unc "Mount point is unc" -body { zipfs mount [zippath test.zip] //unc/share/foo } -result {Invalid mount path "//unc/share/foo"} -returnCodes error - test zipfs-mount_data-on-unc "Mount point include unc" -body { - zipfs mount_data [readbin [zippath test.zip]] //unc/share/foo + test zipfs-mountdata-on-unc "Mount point include unc" -body { + zipfs mountdata [readbin [zippath test.zip]] //unc/share/foo } -result {Invalid mount path "//unc/share/foo"} -returnCodes error # Good mounts @@ -721,7 +719,7 @@ namespace eval test_ns_zipfs { lsort [zipfs list {*}$cmdargs] } -setup { foreach {zippath mountpoint} $mounts { - zipfs mount_data [readbin [zippath $zippath]] [file join [zipfs root] $mountpoint] + zipfs mountdata [readbin [zippath $zippath]] [file join [zipfs root] $mountpoint] } } -cleanup { cleanup @@ -787,7 +785,7 @@ namespace eval test_ns_zipfs { } set memory_setup { foreach {zippath mountpoint} $mounts { - zipfs mount_data [readbin [zippath $zippath]] [file join [zipfs root] $mountpoint] + zipfs mountdata [readbin [zippath $zippath]] [file join [zipfs root] $mountpoint] } } if {[dict exists $args -setup]} { @@ -982,7 +980,7 @@ namespace eval test_ns_zipfs { set data [readbin $zippath] test zipfs-read-memory-$id "zipfs read in-memory $id" -setup { unset -nocomplain fd - zipfs mount_data $data $defMountPt + zipfs mountdata $data $defMountPt } -cleanup { # In case open succeeded when it should not if {[info exists fd]} { @@ -1055,7 +1053,7 @@ namespace eval test_ns_zipfs { set data [readbin $zippath] test zipfs-write-memory-$id "zipfs write in-memory $id" -setup { unset -nocomplain fd - zipfs mount_data $data $defMountPt + zipfs mountdata $data $defMountPt } -cleanup { # In case open succeeded when it should not if {[info exists fd]} { @@ -1213,7 +1211,7 @@ namespace eval test_ns_zipfs { set data [readbin $zippath] test zipfs-rw-memory-$id "zipfs read/seek/write in-memory $id" -setup { unset -nocomplain fd - zipfs mount_data $data $defMountPt + zipfs mountdata $data $defMountPt } -cleanup { # In case open succeeded when it should not if {[info exists fd]} { @@ -1351,7 +1349,7 @@ namespace eval test_ns_zipfs { # Mount memory buffer test zipfs-crc-memory-$id "zipfs crc memory $id" -setup { - zipfs mount_data [readbin [zippath $zippath]] $defMountPt + zipfs mountdata [readbin [zippath $zippath]] $defMountPt } -cleanup { cleanup } -body { -- cgit v0.12 From 3a0cd9eb1f0b9e897b412fd78996880cb437a164 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 18 Aug 2024 21:25:31 +0000 Subject: Fix [6a8c5833c9]: NTFS alternate data streams (ADS) no longer readable writable --- win/tclWinFile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 38c6504..633e2ce 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -3161,7 +3161,7 @@ TclNativeCreateNativeRep( */ while (*wp != '\0') { - if ((*wp < ' ') || wcschr(L"\"*:<>?|", *wp)) { + if ((*wp < ' ') || wcschr(L"\"*<>?|", *wp)) { *wp |= 0xF000; } else if (*wp == '/') { *wp = '\\'; -- cgit v0.12