summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/safe.n10
-rw-r--r--library/safe.tcl108
-rw-r--r--tests/safe-stock87.test413
-rw-r--r--tests/safe-zipfs.test957
-rw-r--r--tests/safe.test1372
5 files changed, 1568 insertions, 1292 deletions
diff --git a/doc/safe.n b/doc/safe.n
index 5b95eeb..5777f74 100644
--- a/doc/safe.n
+++ b/doc/safe.n
@@ -75,11 +75,19 @@ See the \fBOPTIONS\fR section below for a description of the
optional arguments.
If the \fIslave\fR argument is omitted, a name will be generated.
\fB::safe::interpCreate\fR always returns the interpreter name.
+.sp
+The interpreter name \fIslave\fR may include namespace separators,
+but may not have leading or trailing namespace separators, or excess
+colon characters in namespace separators. The interpreter name is
+qualified relative to the global namespace ::, not the namespace in which
+the \fB::safe::interpCreate\fR command is evaluated.
.TP
\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
This command is similar to \fBinterpCreate\fR except it that does not
create the safe interpreter. \fIslave\fR must have been created by some
-other means, like \fBinterp create\fR \fB\-safe\fR.
+other means, like \fBinterp create\fR \fB\-safe\fR. The interpreter
+name \fIslave\fR may include namespace separators, subject to the same
+restrictions as for \fBinterpCreate\fR.
.TP
\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
If no \fIoptions\fR are given, returns the settings for all options for the
diff --git a/library/safe.tcl b/library/safe.tcl
index b73aad5..9a1915d 100644
--- a/library/safe.tcl
+++ b/library/safe.tcl
@@ -83,6 +83,7 @@ proc ::safe::interpCreate {args} {
set autoPath {}
}
set Args [::tcl::OptKeyParse ::safe::interpCreate $args]
+ RejectExcessColons $slave
set withAutoPath [::tcl::OptProcArgGiven -autoPath]
InterpCreate $slave $accessPath \
@@ -98,6 +99,8 @@ proc ::safe::interpInit {args} {
if {![::interp exists $slave]} {
return -code error "\"$slave\" is not an interpreter"
}
+ RejectExcessColons $slave
+
set withAutoPath [::tcl::OptProcArgGiven -autoPath]
InterpInit $slave $accessPath \
[InterpStatics] [InterpNested] $deleteHook $autoPath $withAutoPath
@@ -105,7 +108,7 @@ proc ::safe::interpInit {args} {
# Check that the given slave is "one of us"
proc ::safe::CheckInterp {slave} {
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
if {![info exists state] || ![::interp exists $slave]} {
return -code error \
"\"$slave\" is not an interpreter managed by ::safe::"
@@ -135,7 +138,7 @@ proc ::safe::interpConfigure {args} {
# checks for the "-help" option.
set Args [::tcl::OptKeyParse ::safe::interpIC $args]
CheckInterp $slave
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
set TMP [list \
[list -accessPath $state(access_path)] \
@@ -164,7 +167,7 @@ proc ::safe::interpConfigure {args} {
return -code error [::tcl::OptFlagUsage $desc $arg]
}
CheckInterp $slave
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
set item [::tcl::OptCurDesc $desc]
set name [::tcl::OptName $item]
@@ -213,7 +216,7 @@ proc ::safe::interpConfigure {args} {
# create did
set Args [::tcl::OptKeyParse ::safe::interpIC $args]
CheckInterp $slave
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
# Get the current (and not the default) values of whatever has
# not been given:
@@ -322,8 +325,10 @@ proc ::safe::InterpCreate {
withAutoPath
} {
# Create the slave.
+ # If evaluated in ::safe, the interpreter command for foo is ::foo;
+ # but for foo::bar is safe::foo::bar. So evaluate in :: instead.
if {$slave ne ""} {
- ::interp create -safe $slave
+ namespace eval :: [list ::interp create -safe $slave]
} else {
# empty argument: generate slave name
set slave [::interp create -safe]
@@ -392,7 +397,7 @@ proc ::safe::InterpSetConfig {slave access_path staticsok nestedok deletehook au
Log $slave "Setting auto_path=($raw_auto_path)" NOTICE
}
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
# clear old autopath if it existed
# build new one
@@ -531,7 +536,8 @@ proc ::safe::DetokPath {slave tokenPath} {
#
# When debugging, use TranslatePath for the inverse operation.
proc ::safe::interpFindInAccessPath {slave path} {
- namespace upvar ::safe S$slave state
+ CheckInterp $slave
+ namespace upvar ::safe [VarName $slave] state
if {![dict exists $state(access_path,remap) $path]} {
return -code error "$path not found in access path"
@@ -548,7 +554,8 @@ proc ::safe::interpFindInAccessPath {slave path} {
proc ::safe::interpAddToAccessPath {slave path} {
# first check if the directory is already in there
# (inlined interpFindInAccessPath).
- namespace upvar ::safe S$slave state
+ CheckInterp $slave
+ namespace upvar ::safe [VarName $slave] state
if {[dict exists $state(access_path,remap) $path]} {
return [dict get $state(access_path,remap) $path]
@@ -647,7 +654,7 @@ proc ::safe::InterpInit {
# Sync the paths used to search for Tcl modules. This can be done only
# now, after tm.tcl was loaded.
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
if {[llength $state(tm_path_slave)] > 0} {
::interp eval $slave [list \
::tcl::tm::add {*}[lreverse $state(tm_path_slave)]]
@@ -679,12 +686,16 @@ proc ::safe::AddSubDirs {pathList} {
}
# This procedure deletes a safe slave managed by Safe Tcl and cleans up
-# associated state:
+# associated state.
+# - The command will also delete non-Safe-Base interpreters.
+# - This is regrettable, but to avoid breaking existing code this should be
+# amended at the next major revision by uncommenting "CheckInterp".
proc ::safe::interpDelete {slave} {
Log $slave "About to delete" NOTICE
- namespace upvar ::safe S$slave state
+ # CheckInterp $slave
+ namespace upvar ::safe [VarName $slave] state
# When an interpreter is deleted with [interp delete], any sub-interpreters
# are deleted automatically, but this leaves behind their data in the Safe
@@ -692,7 +703,7 @@ proc ::safe::interpDelete {slave} {
# Safe Base sub-interpreter, so each one is deleted cleanly and not by
# the automatic mechanism built into [interp delete].
foreach sub [interp slaves $slave] {
- if {[info exists ::safe::S[list $slave $sub]]} {
+ if {[info exists ::safe::[VarName [list $slave $sub]]]} {
::safe::interpDelete [list $slave $sub]
}
}
@@ -768,7 +779,7 @@ proc ::safe::setLogCmd {args} {
#
proc ::safe::SyncAccessPath {slave} {
variable AutoPathSync
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
set slave_access_path $state(access_path,slave)
if {$AutoPathSync} {
@@ -798,7 +809,7 @@ proc ::safe::PathToken {n} {
# translate virtual path into real path
#
proc ::safe::TranslatePath {slave path} {
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
# somehow strip the namespaces 'functionality' out (the danger is that
# we would strip valid macintosh "../" queries... :
@@ -1066,12 +1077,15 @@ proc ::safe::AliasSource {slave args} {
return -code error "permission denied"
}
- # do the checks on the filename :
+ # Check that the filename exists and is readable. If it is not, deliver
+ # this -errorcode so that caller in tclPkgUnknown does not write a message
+ # to tclLog. Has no effect on other callers of ::source, which are in
+ # "package ifneeded" scripts.
if {[catch {
CheckFileName $slave $realfile
} msg]} {
Log $slave "$realfile:$msg"
- return -code error $msg
+ return -code error -errorcode {POSIX EACCES} $msg
}
# Passed all the tests, lets source it. Note that we do this all manually
@@ -1116,7 +1130,7 @@ proc ::safe::AliasLoad {slave file args} {
# package name (can be empty if file is not).
set package [lindex $args 0]
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
# Determine where to load. load use a relative interp path and {}
# means self, so we can directly and safely use passed arg.
@@ -1178,7 +1192,7 @@ proc ::safe::AliasLoad {slave file args} {
# the security here relies on "file dirname" answering the proper
# result... needs checking ?
proc ::safe::FileInAccessPath {slave file} {
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
set access_path $state(access_path)
if {[file isdirectory $file]} {
@@ -1190,14 +1204,14 @@ proc ::safe::FileInAccessPath {slave file} {
# potential pathname anomalies.
set norm_parent [file normalize $parent]
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
if {$norm_parent ni $state(access_path,norm)} {
return -code error "\"$file\": not in access_path"
}
}
proc ::safe::DirInAccessPath {slave dir} {
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
set access_path $state(access_path)
if {[file isfile $dir]} {
@@ -1208,7 +1222,7 @@ proc ::safe::DirInAccessPath {slave dir} {
# potential pathname anomalies.
set norm_dir [file normalize $dir]
- namespace upvar ::safe S$slave state
+ namespace upvar ::safe [VarName $slave] state
if {$norm_dir ni $state(access_path,norm)} {
return -code error "\"$dir\": not in access_path"
}
@@ -1246,6 +1260,58 @@ proc ::safe::AliasExeName {slave} {
return ""
}
+# ------------------------------------------------------------------------------
+# Using Interpreter Names with Namespace Qualifiers
+# ------------------------------------------------------------------------------
+# (1) We wish to preserve compatibility with existing code, in which Safe Base
+# interpreter names have no namespace qualifiers.
+# (2) safe::interpCreate and the rest of the Safe Base previously could not
+# accept namespace qualifiers in an interpreter name.
+# (3) The interp command will accept namespace qualifiers in an interpreter
+# name, but accepts distinct interpreters that will have the same command
+# name (e.g. foo, ::foo, and :::foo) (bug 66c2e8c974).
+# (4) To satisfy these constraints, Safe Base interpreter names will be fully
+# qualified namespace names with no excess colons and with the leading "::"
+# omitted.
+# (5) Trailing "::" implies a namespace tail {}, which interp reads as {{}}.
+# Reject such names.
+# (6) We could:
+# (a) EITHER reject usable but non-compliant names (e.g. excess colons) in
+# interpCreate, interpInit;
+# (b) OR accept such names and then translate to a compliant name in every
+# command.
+# The problem with (b) is that the user will expect to use the name with the
+# interp command and will find that it is not recognised.
+# E.g "interpCreate ::foo" creates interpreter "foo", and the user's name
+# "::foo" works with all the Safe Base commands, but "interp eval ::foo"
+# fails.
+# So we choose (a).
+# (7) The command
+# namespace upvar ::safe S$slave state
+# becomes
+# namespace upvar ::safe [VarName $slave] state
+# ------------------------------------------------------------------------------
+
+proc ::safe::RejectExcessColons {slave} {
+ set stripped [regsub -all -- {:::*} $slave ::]
+ if {[string range $stripped end-1 end] eq {::}} {
+ return -code error {interpreter name must not end in "::"}
+ }
+ if {$stripped ne $slave} {
+ set msg {interpreter name has excess colons in namespace separators}
+ return -code error $msg
+ }
+ if {[string range $stripped 0 1] eq {::}} {
+ return -code error {interpreter name must not begin "::"}
+ }
+ return
+}
+
+proc ::safe::VarName {slave} {
+ # return S$slave
+ return S[string map {:: @N @ @A} $slave]
+}
+
proc ::safe::Setup {} {
####
#
diff --git a/tests/safe-stock87.test b/tests/safe-stock87.test
new file mode 100644
index 0000000..a8f5bd2
--- /dev/null
+++ b/tests/safe-stock87.test
@@ -0,0 +1,413 @@
+# safe-stock87.test --
+#
+# This file contains tests for safe Tcl that were previously in the file
+# safe.test, and use files and packages of stock Tcl 8.7 to perform the tests.
+# These files may be changed or disappear in future revisions of Tcl, for
+# example package opt will eventually be removed.
+#
+# The tests are replaced in safe.tcl with tests that use files provided in the
+# tests directory. Test numbering is for comparison with similar tests in
+# safe.test.
+#
+# Sourcing this file into tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# The defunct package http 1.0 was convenient for testing package loading.
+# - This file, safe-stock87.test, uses packages opt and (from cookiejar)
+# tcl::idna to provide alternative tests based on stock Tcl packages.
+# - These are tests 7.1 7.2 7.4 9.11 9.13
+# - Tests 7.[124], 9.1[13] use "package require opt".
+# - Tests 9.1[13] also use "package require tcl::idna".
+# - The corresponding tests in safe.test use example packages provided in
+# subdirectory auto0 of the tests directory, which are independent of any
+# changes made to the packages provided with Tcl.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.5-
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+# When using package opt for testing positive/negative package search:
+# - The directory location and the error message depend on whether
+# and how the package is installed.
+
+# Error message for test 7.2 for "package require opt".
+if {[string match *zipfs:/* [info library]]} {
+ # pkgIndex.tcl is in [info library]
+ # file to be sourced is in [info library]/opt*
+ set pkgOptErrMsg {permission denied}
+} else {
+ # pkgIndex.tcl and file to be sourced are
+ # both in [info library]/opt*
+ set pkgOptErrMsg {can't find package opt}
+}
+
+# Directory of opt for tests 7.4, 9.10, 9.12 for "package require opt".
+if {[file exists [file join [info library] opt0.4]]} {
+ # Installed files in lib8.7/opt0.4
+ set pkgOptDir opt0.4
+} elseif {[file exists [file join [info library] opt]]} {
+ # Installed files in zipfs, or source files used by "make test"
+ set pkgOptDir opt
+} else {
+ error {cannot find opt library}
+}
+
+# Directory of cookiejar for tests 9.10, 9.12 for "package require tcl::idna".
+if {[file exists [file join [info library] cookiejar0.2]]} {
+ # Installed files in lib8.7/cookiejar0.2
+ set pkgJarDir cookiejar0.2
+} elseif {[file exists [file join [info library] cookiejar]]} {
+ # Installed files in zipfs, or source files used by "make test"
+ set pkgJarDir cookiejar
+} else {
+ error {cannot find cookiejar library}
+}
+
+set SaveAutoPath $::auto_path
+set ::auto_path [info library]
+set TestsDir [file normalize [file dirname [info script]]]
+set PathMapp {}
+lappend PathMapp [file join [info library] $pkgOptDir] TCLLIB/OPTDIR
+lappend PathMapp [file join [info library] $pkgJarDir] TCLLIB/JARDIR
+lappend PathMapp $tcl_library TCLLIB $TestsDir TESTSDIR
+
+proc mapList {map listIn} {
+ set listOut {}
+ foreach element $listIn {
+ lappend listOut [string map $map $element]
+ }
+ return $listOut
+}
+proc mapAndSortList {map listIn} {
+ set listOut {}
+ foreach element $listIn {
+ lappend listOut [string map $map $element]
+ }
+ lsort $listOut
+}
+
+# Force actual loading of the safe package because we use un-exported (and
+# thus un-autoindexed) APIs in this test result arguments:
+catch {safe::interpConfigure}
+
+# testing that nested and statics do what is advertised (we use a static
+# package - Tcltest - but it might be absent if we're in standard tclsh)
+
+testConstraint TcltestPackage [expr {![catch {package require Tcltest}]}]
+
+testConstraint AutoSyncDefined 1
+
+# high level general test
+test safe-stock87-7.1 {tests that everything works at high level with conventional AutoPathSync, use pkg opt} -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+
+ set i [safe::interpCreate]
+} -body {
+ # no error shall occur:
+ # (because the default access_path shall include 1st level sub dirs so
+ # package require in a slave works like in the master)
+ set v [interp eval $i {package require opt}]
+ # no error shall occur:
+ interp eval $i {::tcl::Lempty {a list}}
+ set v
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result 0.4.*
+test safe-stock87-7.2 {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync, use pkg opt} -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ } else {
+ set SyncVal_TMP 1
+ }
+} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+ # should add as p* (not p1 if master has a module path)
+ set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
+ # an error shall occur (opt is not anymore in the secure 0-level
+ # provided deep path)
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ list $token1 $token2 -- \
+ [catch {interp eval $i {package require opt}} msg] $msg -- \
+ $mappA -- [safe::interpDelete $i]
+} -cleanup {
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result "{\$p(:0:)} {\$p(:*:)} -- 1 {$pkgOptErrMsg} --\
+ {TCLLIB */dummy/unixlike/test/path} -- {}"
+test safe-stock87-7.4 {tests specific path and positive search with conventional AutoPathSync, use pkg opt} -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ } else {
+ set SyncVal_TMP 1
+ }
+} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+ # should add as p* (not p1 if master has a module path)
+ set token2 [safe::interpAddToAccessPath $i [file join [info library] $pkgOptDir]]
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ # this time, unlike test safe-stock87-7.2, opt should be found
+ list $token1 $token2 -- \
+ [catch {interp eval $i {package require opt}} msg] $msg -- \
+ $mappA -- [safe::interpDelete $i]
+ # Note that the glob match elides directories (those from the module path)
+ # other than the first and last in the access path.
+} -cleanup {
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 0.4.* --\
+ {TCLLIB * TCLLIB/OPTDIR} -- {}}
+
+# The following test checks whether the definition of tcl_endOfWord can be
+# obtained from auto_loading. It was previously test "safe-5.1".
+test safe-stock87-9.8 {test auto-loading in safe interpreters, was safe-5.1} -setup {
+ catch {safe::interpDelete a}
+ safe::interpCreate a
+} -body {
+ interp eval a {tcl_endOfWord "" 0}
+} -cleanup {
+ safe::interpDelete a
+} -result -1
+test safe-stock87-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement with conventional AutoPathSync, uses pkg opt and tcl::idna} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library \
+ [file join $tcl_library $pkgOptDir] \
+ [file join $tcl_library $pkgJarDir]]]
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]
+
+ # Load pkgIndex.tcl data.
+ catch {interp eval $i {package require NOEXIST}}
+
+ # Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
+ # This has no effect because the records in Pkg of these directories were from access as children of {$p(:0:)}.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $tcl_library $pkgJarDir] \
+ [file join $tcl_library $pkgOptDir]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set mappB [mapList $PathMapp [dict get $confB -accessPath]]
+ set path3 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]
+
+ # Try to load the packages and run a command from each one.
+ set code3 [catch {interp eval $i {package require tcl::idna}} msg3]
+ set code4 [catch {interp eval $i {package require opt}} msg4]
+ set code5 [catch {interp eval $i {::tcl::Lempty {a list}}} msg5]
+ set code6 [catch {interp eval $i {::tcl::idna::IDNAencode example.com}} msg6]
+
+ list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
+ $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 1.* 0 0.4.* --\
+ {TCLLIB TCLLIB/OPTDIR TCLLIB/JARDIR*} --\
+ {TCLLIB TCLLIB/JARDIR TCLLIB/OPTDIR*} --\
+ 0 0 0 example.com}
+test safe-stock87-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed with conventional AutoPathSync, uses pkg opt and tcl::idna} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library \
+ [file join $tcl_library $pkgOptDir] \
+ [file join $tcl_library $pkgJarDir]]]
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]
+
+ # Load pkgIndex.tcl data.
+ catch {interp eval $i {package require NOEXIST}}
+
+ # Limit access path. Remove tokens {$p(:1:)} and {$p(:2:)}.
+ safe::interpConfigure $i -accessPath [list $tcl_library]
+
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set mappB [mapList $PathMapp [dict get $confB -accessPath]]
+ set code4 [catch {::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]} path4]
+ set code5 [catch {::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]} path5]
+
+ # Try to load the packages.
+ set code3 [catch {interp eval $i {package require opt}} msg3]
+ set code6 [catch {interp eval $i {package require tcl::idna}} msg6]
+
+ list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
+ $mappA -- $mappB
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
+ 1 {* not found in access path} -- 1 1 --\
+ {TCLLIB TCLLIB/OPTDIR TCLLIB/JARDIR*} -- {TCLLIB*}}
+
+test safe-stock87-18.1 {cf. safe-stock87-7.1opt - tests that everything works at high level without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 0
+ } else {
+ error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
+ }
+
+ # Without AutoPathSync, we need a more complete auto_path,
+ # because the slave will use the same value.
+ set lib1 [info library]
+ set lib2 [file dirname $lib1]
+ set ::auto_TMP $::auto_path
+ set ::auto_path [list $lib1 $lib2]
+
+ set i [safe::interpCreate]
+ set ::auto_path $::auto_TMP
+} -body {
+ # no error shall occur:
+ # (because the default access_path shall include 1st level sub dirs so
+ # package require in a slave works like in the master)
+ set v [interp eval $i {package require opt}]
+ # no error shall occur:
+ interp eval $i {::tcl::Lempty {a list}}
+ set v
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result 0.4.*
+test safe-stock87-18.2 {cf. safe-stock87-7.2opt - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 0
+ } else {
+ error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
+ }
+} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+ set auto1 [interp eval $i {set ::auto_path}]
+ interp eval $i {set ::auto_path [list {$p(:0:)}]}
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+ # should add as p* (not p1 if master has a module path)
+ set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
+ # an error shall occur (opt is not anymore in the secure 0-level
+ # provided deep path)
+ list $auto1 $token1 $token2 \
+ [catch {interp eval $i {package require opt}} msg] $msg \
+ [safe::interpConfigure $i]\
+ [safe::interpDelete $i]
+} -cleanup {
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} 1 {$pkgOptErrMsg}\
+ {-accessPath {[list $tcl_library */dummy/unixlike/test/path]}\
+ -statics 0 -nested 1 -deleteHook {} -autoPath [list $tcl_library]} {}"
+test safe-stock87-18.4 {cf. safe-stock87-7.4opt - tests specific path and positive search and auto_path without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 0
+ } else {
+ error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
+ }
+} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+
+ # should not have been set by Safe Base:
+ set auto1 [interp eval $i {set ::auto_path}]
+
+ interp eval $i {set ::auto_path [list {$p(:0:)}]}
+
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+
+ # should add as p* (not p1 if master has a module path)
+ set token2 [safe::interpAddToAccessPath $i [file join [info library] $pkgOptDir]]
+
+ # should not have been changed by Safe Base:
+ set auto2 [interp eval $i {set ::auto_path}]
+
+ # This time, unlike test safe-stock87-18.2opt and the try above, opt should be found:
+ list $auto1 $auto2 $token1 $token2 \
+ [catch {interp eval $i {package require opt}} msg] $msg \
+ [safe::interpConfigure $i]\
+ [safe::interpDelete $i]
+} -cleanup {
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} 0 0.4.*\
+ {-accessPath {[list $tcl_library *$tcl_library/$pkgOptDir]}\
+ -statics 0 -nested 1 -deleteHook {} -autoPath [list $tcl_library]} {}"
+
+set ::auto_path $SaveAutoPath
+unset pkgOptErrMsg pkgOptDir pkgJarDir SaveAutoPath TestsDir PathMapp
+rename mapList {}
+rename mapAndSortList {}
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/safe-zipfs.test b/tests/safe-zipfs.test
new file mode 100644
index 0000000..4793bb2
--- /dev/null
+++ b/tests/safe-zipfs.test
@@ -0,0 +1,957 @@
+# safe-zipfs.test --
+#
+# This file contains tests for safe Tcl that test its compatibility with the
+# zipfs facilities introduced in Tcl 8.7. Test numbering is for comparison
+# with similar tests in safe.test that do not use the zipfs file system.
+#
+# Sourcing this file into tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.5-
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+set SaveAutoPath $::auto_path
+set ::auto_path [info library]
+set TestsDir [file normalize [file dirname [info script]]]
+
+set ZipMountPoint [zipfs root]auto-files
+zipfs mount $ZipMountPoint [file join $TestsDir auto-files.zip]
+
+set PathMapp {}
+lappend PathMapp $tcl_library TCLLIB $TestsDir TESTSDIR $ZipMountPoint ZIPDIR
+
+proc mapList {map listIn} {
+ set listOut {}
+ foreach element $listIn {
+ lappend listOut [string map $map $element]
+ }
+ return $listOut
+}
+proc mapAndSortList {map listIn} {
+ set listOut {}
+ foreach element $listIn {
+ lappend listOut [string map $map $element]
+ }
+ lsort $listOut
+}
+
+# Force actual loading of the safe package because we use un-exported (and
+# thus un-autoindexed) APIs in this test result arguments:
+catch {safe::interpConfigure}
+
+# testing that nested and statics do what is advertised (we use a static
+# package - Tcltest - but it might be absent if we're in standard tclsh)
+
+testConstraint TcltestPackage [expr {![catch {package require Tcltest}]}]
+
+testConstraint AutoSyncDefined 1
+
+# Tests 5.* test the example files before using them to test safe interpreters.
+
+test safe-zipfs-5.1 {example tclIndex commands, test in master interpreter; zipfs} -setup {
+ set tmpAutoPath $::auto_path
+ lappend ::auto_path [file join $ZipMountPoint auto0 auto1] [file join $ZipMountPoint auto0 auto2]
+} -body {
+ # Try to load the commands.
+ set code3 [catch report1 msg3]
+ set code4 [catch report2 msg4]
+ list $code3 $msg3 $code4 $msg4
+} -cleanup {
+ catch {rename report1 {}}
+ catch {rename report2 {}}
+ set ::auto_path $tmpAutoPath
+ auto_reset
+} -match glob -result {0 ok1 0 ok2}
+test safe-zipfs-5.2 {example tclIndex commands, negative test in master interpreter; zipfs} -setup {
+ set tmpAutoPath $::auto_path
+ lappend ::auto_path [file join $ZipMountPoint auto0]
+} -body {
+ # Try to load the commands.
+ set code3 [catch report1 msg3]
+ set code4 [catch report2 msg4]
+ list $code3 $msg3 $code4 $msg4
+} -cleanup {
+ catch {rename report1 {}}
+ catch {rename report2 {}}
+ set ::auto_path $tmpAutoPath
+ auto_reset
+} -match glob -result {1 {invalid command name "report1"} 1 {invalid command name "report2"}}
+test safe-zipfs-5.3 {example pkgIndex.tcl packages, test in master interpreter, child directories; zipfs} -setup {
+ set tmpAutoPath $::auto_path
+ lappend ::auto_path [file join $ZipMountPoint auto0]
+} -body {
+ # Try to load the packages and run a command from each one.
+ set code3 [catch {package require SafeTestPackage1} msg3]
+ set code4 [catch {package require SafeTestPackage2} msg4]
+ set code5 [catch HeresPackage1 msg5]
+ set code6 [catch HeresPackage2 msg6]
+ list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
+} -cleanup {
+ set ::auto_path $tmpAutoPath
+ catch {package forget SafeTestPackage1}
+ catch {package forget SafeTestPackage2}
+ catch {rename HeresPackage1 {}}
+ catch {rename HeresPackage2 {}}
+} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
+test safe-zipfs-5.4 {example pkgIndex.tcl packages, test in master interpreter, main directories; zipfs} -setup {
+ set tmpAutoPath $::auto_path
+ lappend ::auto_path [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]
+} -body {
+ # Try to load the packages and run a command from each one.
+ set code3 [catch {package require SafeTestPackage1} msg3]
+ set code4 [catch {package require SafeTestPackage2} msg4]
+ set code5 [catch HeresPackage1 msg5]
+ set code6 [catch HeresPackage2 msg6]
+ list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
+} -cleanup {
+ set ::auto_path $tmpAutoPath
+ catch {package forget SafeTestPackage1}
+ catch {package forget SafeTestPackage2}
+ catch {rename HeresPackage1 {}}
+ catch {rename HeresPackage2 {}}
+} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
+test safe-zipfs-5.5 {example modules packages, test in master interpreter, replace path; zipfs} -setup {
+ set oldTm [tcl::tm::path list]
+ foreach path $oldTm {
+ tcl::tm::path remove $path
+ }
+ tcl::tm::path add [file join $ZipMountPoint auto0 modules]
+} -body {
+ # Try to load the modules and run a command from each one.
+ set code0 [catch {package require test0} msg0]
+ set code1 [catch {package require mod1::test1} msg1]
+ set code2 [catch {package require mod2::test2} msg2]
+ set out0 [test0::try0]
+ set out1 [mod1::test1::try1]
+ set out2 [mod2::test2::try2]
+ list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
+} -cleanup {
+ tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
+ foreach path [lreverse $oldTm] {
+ tcl::tm::path add $path
+ }
+ catch {package forget test0}
+ catch {package forget mod1::test1}
+ catch {package forget mod2::test2}
+ catch {namespace delete ::test0}
+ catch {namespace delete ::mod1}
+} -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
+test safe-zipfs-5.6 {example modules packages, test in master interpreter, append to path; zipfs} -setup {
+ tcl::tm::path add [file join $ZipMountPoint auto0 modules]
+} -body {
+ # Try to load the modules and run a command from each one.
+ set code0 [catch {package require test0} msg0]
+ set code1 [catch {package require mod1::test1} msg1]
+ set code2 [catch {package require mod2::test2} msg2]
+ set out0 [test0::try0]
+ set out1 [mod1::test1::try1]
+ set out2 [mod2::test2::try2]
+ list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
+} -cleanup {
+ tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
+ catch {package forget test0}
+ catch {package forget mod1::test1}
+ catch {package forget mod2::test2}
+ catch {namespace delete ::test0}
+ catch {namespace delete ::mod1}
+} -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
+
+# high level general test
+# Use zipped example packages not tcl8.x/opt
+test safe-zipfs-7.1 {tests that everything works at high level with conventional AutoPathSync; zipfs} -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+ set tmpAutoPath $::auto_path
+ lappend ::auto_path [file join $ZipMountPoint auto0]
+ set i [safe::interpCreate]
+ set ::auto_path $tmpAutoPath
+} -body {
+ # no error shall occur:
+ # (because the default access_path shall include 1st level sub dirs so
+ # package require in a slave works like in the master)
+ set v [interp eval $i {package require SafeTestPackage1}]
+ # no error shall occur:
+ interp eval $i {HeresPackage1}
+ set v
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result 1.2.3
+test safe-zipfs-7.2 {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync; zipfs} -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ } else {
+ set SyncVal_TMP 1
+ }
+} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+ # should add as p* (not p1 if master has a module path)
+ set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
+ # should add as p* (not p2 if master has a module path)
+ set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ # an error shall occur (SafeTestPackage1 is not anymore in the secure 0-level
+ # provided deep path)
+ list $token1 $token2 $token3 -- \
+ [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg -- \
+ $mappA -- [safe::interpDelete $i]
+} -cleanup {
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:0:)} {$p(:*:)} {$p(:*:)} --\
+ 1 {can't find package SafeTestPackage1} --\
+ {TCLLIB */dummy/unixlike/test/path ZIPDIR/auto0} -- {}}
+test safe-zipfs-7.4 {tests specific path and positive search with conventional AutoPathSync; zipfs} -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ } else {
+ set SyncVal_TMP 1
+ }
+} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+ # should add as p* (not p1 if master has a module path)
+ set token2 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ # this time, unlike test safe-zipfs-7.2, SafeTestPackage1 should be found
+ list $token1 $token2 -- \
+ [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg -- \
+ $mappA -- [safe::interpDelete $i]
+ # Note that the glob match elides directories (those from the module path)
+ # other than the first and last in the access path.
+} -cleanup {
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 1.2.3 --\
+ {TCLLIB * ZIPDIR/auto0/auto1} -- {}}
+
+test safe-zipfs-9.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset) with conventional AutoPathSync; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]]
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Load auto_load data.
+ interp eval $i {catch nonExistentCommand}
+
+ # Load and run the commands.
+ # This guarantees the test will pass even if the tokens are swapped.
+ set code1 [catch {interp eval $i {report1}} msg1]
+ set code2 [catch {interp eval $i {report2}} msg2]
+
+ # Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto2] \
+ [file join $ZipMountPoint auto0 auto1]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set mappB [mapList $PathMapp [dict get $confB -accessPath]]
+ set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Run the commands.
+ set code3 [catch {interp eval $i {report1}} msg3]
+ set code4 [catch {interp eval $i {report2}} msg4]
+
+ list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 --\
+ {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} --\
+ {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*}}
+test safe-zipfs-9.10 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset) with conventional AutoPathSync; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]]
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Load auto_load data.
+ interp eval $i {catch nonExistentCommand}
+
+ # Do not load the commands. With the tokens swapped, the test
+ # will pass only if the Safe Base has called auto_reset.
+
+ # Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto2] \
+ [file join $ZipMountPoint auto0 auto1]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set mappB [mapList $PathMapp [dict get $confB -accessPath]]
+ set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Load and run the commands.
+ set code3 [catch {interp eval $i {report1}} msg3]
+ set code4 [catch {interp eval $i {report2}} msg4]
+
+ list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
+ 0 ok1 0 ok2 --\
+ {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} --\
+ {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*}}
+test safe-zipfs-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement with conventional AutoPathSync; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+} -body {
+ # For complete correspondence to safe-stock87-9.11, include auto0 in access path.
+ set i [safe::interpCreate -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0] \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]]
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Load pkgIndex.tcl data.
+ catch {interp eval $i {package require NOEXIST}}
+
+ # Rearrange access path. Swap tokens {$p(:2:)} and {$p(:3:)}.
+ # This would have no effect because the records in Pkg of these directories
+ # were from access as children of {$p(:1:)}.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0] \
+ [file join $ZipMountPoint auto0 auto2] \
+ [file join $ZipMountPoint auto0 auto1]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set mappB [mapList $PathMapp [dict get $confB -accessPath]]
+ set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Try to load the packages and run a command from each one.
+ set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
+ set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
+ set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
+ set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]
+
+ list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
+ $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} -- 0 1.2.3 0 2.3.4 --\
+ {TCLLIB ZIPDIR/auto0 ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} --\
+ {TCLLIB ZIPDIR/auto0 ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*} --\
+ 0 OK1 0 OK2}
+test safe-zipfs-9.12 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, 9.10 without path auto0 with conventional AutoPathSync; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]]
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Load pkgIndex.tcl data.
+ catch {interp eval $i {package require NOEXIST}}
+
+ # Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto2] \
+ [file join $ZipMountPoint auto0 auto1]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set mappB [mapList $PathMapp [dict get $confB -accessPath]]
+ set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Try to load the packages and run a command from each one.
+ set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
+ set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
+ set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
+ set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]
+
+ list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
+ $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
+ 0 1.2.3 0 2.3.4 --\
+ {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} --\
+ {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*} --\
+ 0 OK1 0 OK2}
+test safe-zipfs-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, with conventional AutoPathSync; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]]
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set mappA [mapList $PathMapp [dict get $confA -accessPath]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+
+ # Load pkgIndex.tcl data.
+ catch {interp eval $i {package require NOEXIST}}
+
+ # Limit access path. Remove tokens {$p(:1:)} and {$p(:2:)}.
+ safe::interpConfigure $i -accessPath [list $tcl_library]
+
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set mappB [mapList $PathMapp [dict get $confB -accessPath]]
+ set code4 [catch {::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]} path4]
+ set code5 [catch {::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]} path5]
+
+ # Try to load the packages.
+ set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
+ set code6 [catch {interp eval $i {package require SafeTestPackage2}} msg6]
+
+ list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
+ $mappA -- $mappB
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
+ 1 {* not found in access path} -- 1 1 --\
+ {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB*}}
+test safe-zipfs-9.20 {check module loading, with conventional AutoPathSync; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+ set oldTm [tcl::tm::path list]
+ foreach path $oldTm {
+ tcl::tm::path remove $path
+ }
+ tcl::tm::path add [file join $ZipMountPoint auto0 modules]
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library]]
+
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
+ set modsA [interp eval $i {tcl::tm::path list}]
+ set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Try to load the packages and run a command from each one.
+ set code0 [catch {interp eval $i {package require test0}} msg0]
+ set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
+ set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
+ set out0 [interp eval $i {test0::try0}]
+ set out1 [interp eval $i {mod1::test1::try1}]
+ set out2 [interp eval $i {mod2::test2::try2}]
+
+ list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
+ $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $out0 $out1 $out2
+} -cleanup {
+ tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
+ foreach path [lreverse $oldTm] {
+ tcl::tm::path add $path
+ }
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
+ 0 0.5 0 1.0 0 2.0 --\
+ {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
+ ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
+# - The command safe::InterpSetConfig adds the master's [tcl::tm::list] in
+# tokenized form to the slave's access path, and then adds all the
+# descendants, discovered recursively by using glob.
+# - The order of the directories in the list returned by glob is system-dependent,
+# and therefore this is true also for (a) the order of token assignment to
+# descendants of the [tcl::tm::list] roots; and (b) the order of those same
+# directories in the access path. Both those things must be sorted before
+# comparing with expected results. The test is therefore not totally strict,
+# but will notice missing or surplus directories.
+test safe-zipfs-9.21 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 1; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+ set oldTm [tcl::tm::path list]
+ foreach path $oldTm {
+ tcl::tm::path remove $path
+ }
+ tcl::tm::path add [file join $ZipMountPoint auto0 modules]
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library]]
+
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
+ set modsA [interp eval $i {tcl::tm::path list}]
+ set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Add to access path.
+ # This injects more tokens, pushing modules to higher token numbers.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
+ set modsB [interp eval $i {tcl::tm::path list}]
+ set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Load pkg data.
+ catch {interp eval $i {package require NOEXIST}}
+ catch {interp eval $i {package require mod1::NOEXIST}}
+ catch {interp eval $i {package require mod2::NOEXIST}}
+
+ # Try to load the packages and run a command from each one.
+ set code0 [catch {interp eval $i {package require test0}} msg0]
+ set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
+ set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
+ set out0 [interp eval $i {test0::try0}]
+ set out1 [interp eval $i {mod1::test1::try1}]
+ set out2 [interp eval $i {mod2::test2::try2}]
+
+ list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
+ [lsort [list $path3 $path4 $path5]] -- $modsB -- \
+ $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
+ $out0 $out1 $out2
+} -cleanup {
+ tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
+ foreach path [lreverse $oldTm] {
+ tcl::tm::path add $path
+ }
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
+ {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
+ 0 0.5 0 1.0 0 2.0 --\
+ {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
+ ZIPDIR/auto0/modules/mod2} --\
+ {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules\
+ ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} --\
+ res0 res1 res2}
+# See comments on lsort after test safe-zipfs-9.20.
+test safe-zipfs-9.22 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 0; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+ set oldTm [tcl::tm::path list]
+ foreach path $oldTm {
+ tcl::tm::path remove $path
+ }
+ tcl::tm::path add [file join $ZipMountPoint auto0 modules]
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library]]
+
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
+ set modsA [interp eval $i {tcl::tm::path list}]
+ set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Add to access path.
+ # This injects more tokens, pushing modules to higher token numbers.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
+ set modsB [interp eval $i {tcl::tm::path list}]
+ set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Try to load the packages and run a command from each one.
+ set code0 [catch {interp eval $i {package require test0}} msg0]
+ set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
+ set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
+ set out0 [interp eval $i {test0::try0}]
+ set out1 [interp eval $i {mod1::test1::try1}]
+ set out2 [interp eval $i {mod2::test2::try2}]
+
+ list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
+ [lsort [list $path3 $path4 $path5]] -- $modsB -- \
+ $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
+ $out0 $out1 $out2
+} -cleanup {
+ tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
+ foreach path [lreverse $oldTm] {
+ tcl::tm::path add $path
+ }
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
+ {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
+ 0 0.5 0 1.0 0 2.0 --\
+ {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
+ ZIPDIR/auto0/modules/mod2} --\
+ {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules\
+ ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} --\
+ res0 res1 res2}
+# See comments on lsort after test safe-zipfs-9.20.
+test safe-zipfs-9.23 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 3; zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+ set oldTm [tcl::tm::path list]
+ foreach path $oldTm {
+ tcl::tm::path remove $path
+ }
+ tcl::tm::path add [file join $ZipMountPoint auto0 modules]
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library]]
+
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
+ set modsA [interp eval $i {tcl::tm::path list}]
+ set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Force the interpreter to acquire pkg data which will soon become stale.
+ catch {interp eval $i {package require NOEXIST}}
+ catch {interp eval $i {package require mod1::NOEXIST}}
+ catch {interp eval $i {package require mod2::NOEXIST}}
+
+ # Add to access path.
+ # This injects more tokens, pushing modules to higher token numbers.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
+ set modsB [interp eval $i {tcl::tm::path list}]
+ set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Refresh stale pkg data.
+ catch {interp eval $i {package require NOEXIST}}
+ catch {interp eval $i {package require mod1::NOEXIST}}
+ catch {interp eval $i {package require mod2::NOEXIST}}
+
+ # Try to load the packages and run a command from each one.
+ set code0 [catch {interp eval $i {package require test0}} msg0]
+ set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
+ set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
+ set out0 [interp eval $i {test0::try0}]
+ set out1 [interp eval $i {mod1::test1::try1}]
+ set out2 [interp eval $i {mod2::test2::try2}]
+
+ list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
+ [lsort [list $path3 $path4 $path5]] -- $modsB -- \
+ $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
+ $out0 $out1 $out2
+} -cleanup {
+ tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
+ foreach path [lreverse $oldTm] {
+ tcl::tm::path add $path
+ }
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
+ {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
+ 0 0.5 0 1.0 0 2.0 --\
+ {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
+ ZIPDIR/auto0/modules/mod2} --\
+ {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules\
+ ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} --\
+ res0 res1 res2}
+# See comments on lsort after test safe-zipfs-9.20.
+test safe-zipfs-9.24 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 2 (worst case); zipfs} -setup {
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 1
+ }
+ set oldTm [tcl::tm::path list]
+ foreach path $oldTm {
+ tcl::tm::path remove $path
+ }
+ tcl::tm::path add [file join $ZipMountPoint auto0 modules]
+} -body {
+ set i [safe::interpCreate -accessPath [list $tcl_library]]
+
+ # Inspect.
+ set confA [safe::interpConfigure $i]
+ set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
+ set modsA [interp eval $i {tcl::tm::path list}]
+ set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Force the interpreter to acquire pkg data which will soon become stale.
+ catch {interp eval $i {package require NOEXIST}}
+ catch {interp eval $i {package require mod1::NOEXIST}}
+ catch {interp eval $i {package require mod2::NOEXIST}}
+
+ # Add to access path.
+ # This injects more tokens, pushing modules to higher token numbers.
+ safe::interpConfigure $i -accessPath [list $tcl_library \
+ [file join $ZipMountPoint auto0 auto1] \
+ [file join $ZipMountPoint auto0 auto2]]
+ # Inspect.
+ set confB [safe::interpConfigure $i]
+ set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
+ set modsB [interp eval $i {tcl::tm::path list}]
+ set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
+ set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
+
+ # Try to load the packages and run a command from each one.
+ set code0 [catch {interp eval $i {package require test0}} msg0]
+ set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
+ set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
+ set out0 [interp eval $i {test0::try0}]
+ set out1 [interp eval $i {mod1::test1::try1}]
+ set out2 [interp eval $i {mod2::test2::try2}]
+
+ list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
+ [lsort [list $path3 $path4 $path5]] -- $modsB -- \
+ $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
+ $out0 $out1 $out2
+} -cleanup {
+ tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
+ foreach path [lreverse $oldTm] {
+ tcl::tm::path add $path
+ }
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
+ {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
+ 0 0.5 0 1.0 0 2.0 --\
+ {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
+ ZIPDIR/auto0/modules/mod2} --\
+ {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules\
+ ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} --\
+ res0 res1 res2}
+# See comments on lsort after test safe-zipfs-9.20.
+
+test safe-zipfs-18.1 {cf. safe-zipfs-7.1 - tests that everything works at high level without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 0
+ } else {
+ error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
+ }
+
+ # Without AutoPathSync, we need a more complete auto_path,
+ # because the slave will use the same value.
+ set lib1 [info library]
+ set lib2 [file join $ZipMountPoint auto0]
+ set ::auto_TMP $::auto_path
+ set ::auto_path [list $lib1 $lib2]
+
+ set i [safe::interpCreate]
+ set ::auto_path $::auto_TMP
+} -body {
+ # no error shall occur:
+ # (because the default access_path shall include 1st level sub dirs so
+ # package require in a slave works like in the master)
+ set v [interp eval $i {package require SafeTestPackage1}]
+ # no error shall occur:
+ interp eval $i HeresPackage1
+ set v
+} -cleanup {
+ safe::interpDelete $i
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result 1.2.3
+test safe-zipfs-18.2 {cf. safe-zipfs-7.2 - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 0
+ } else {
+ error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
+ }
+} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+ set auto1 [interp eval $i {set ::auto_path}]
+ interp eval $i {set ::auto_path [list {$p(:0:)}]}
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+ # should add as p* (not p1 if master has a module path)
+ set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
+ # should add as p* (not p2 if master has a module path)
+ set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
+ # an error shall occur (SafeTestPackage1 is not anymore in the secure 0-level
+ # provided deep path)
+ list $auto1 $token1 $token2 $token3 \
+ [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg \
+ [safe::interpConfigure $i]\
+ [safe::interpDelete $i]
+} -cleanup {
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)}\
+ 1 {can't find package SafeTestPackage1}\
+ {-accessPath {[list $tcl_library \
+ */dummy/unixlike/test/path \
+ $ZipMountPoint/auto0]}\
+ -statics 0 -nested 1 -deleteHook {} -autoPath [list $tcl_library]} {}"
+test safe-zipfs-18.4 {cf. safe-zipfs-7.4 - tests specific path and positive search and auto_path without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
+ # All ::safe commands are loaded at start of file.
+ set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
+ if {$SyncExists} {
+ set SyncVal_TMP [safe::setAutoPathSync]
+ safe::setAutoPathSync 0
+ } else {
+ error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
+ }
+} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+
+ # should not have been set by Safe Base:
+ set auto1 [interp eval $i {set ::auto_path}]
+
+ interp eval $i {set ::auto_path [list {$p(:0:)}]}
+
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+
+ # should add as p* (not p1 if master has a module path)
+ set token2 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
+
+ # should add as p* (not p2 if master has a module path)
+ set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0 auto1]]
+
+ # should not have been changed by Safe Base:
+ set auto2 [interp eval $i {set ::auto_path}]
+
+ set auto3 [interp eval $i [list set ::auto_path [list {$p(:0:)} $token2]]]
+
+ # This time, unlike test safe-zipfs-18.2 and the try above, SafeTestPackage1 should be found:
+ list $auto1 $auto2 $token1 $token2 $token3 \
+ [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg \
+ [safe::interpConfigure $i]\
+ [safe::interpDelete $i]
+} -cleanup {
+ if {$SyncExists} {
+ safe::setAutoPathSync $SyncVal_TMP
+ }
+} -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)} 0 1.2.3\
+ {-accessPath {[list $tcl_library *$ZipMountPoint/auto0 $ZipMountPoint/auto0/auto1]}\
+ -statics 0 -nested 1 -deleteHook {}\
+ -autoPath {[list $tcl_library $ZipMountPoint/auto0]}} {}"
+
+set ::auto_path $SaveAutoPath
+zipfs unmount ${ZipMountPoint}
+unset SaveAutoPath TestsDir ZipMountPoint PathMapp
+rename mapList {}
+rename mapAndSortList {}
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/safe.test b/tests/safe.test
index 981165a..ae4af7c 100644
--- a/tests/safe.test
+++ b/tests/safe.test
@@ -4,6 +4,16 @@
# using safe interpreters. Sourcing this file into tcl runs the tests and
# generates output for errors. No output means no errors were found.
#
+# The defunct package http 1.0 was convenient for testing package loading.
+# - Tests that used http are replaced here with tests that use example packages
+# provided in subdirectory auto0 of the tests directory, which are independent
+# of any changes made to the packages provided with Tcl itself.
+# - These are tests 7.1 7.2 7.4 9.11 9.13 18.1 18.2 18.4
+# - Tests 5.* test the example packages themselves before they
+# are used to test Safe Base interpreters.
+# - Alternative tests using stock packages of Tcl 8.7 are in file
+# safe-stock87.test.
+#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
@@ -17,75 +27,14 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
-testConstraint AutoSyncDefined 1
-
foreach i [interp slaves] {
interp delete $i
}
set SaveAutoPath $::auto_path
set ::auto_path [info library]
-
-# The defunct package http 1.0 was convenient for testing package loading.
-# - Replaced here with tests using example packages provided in subdirectory
-# auto0 of the tests directory, which are independent of any changes
-# made to the packages provided with Tcl.
-# - These are tests 7.1 7.2 7.4 9.10 9.12 18.1 18.2 18.4
-# - Tests 7.0[a-f] test the example packages themselves before they
-# are used to test Safe Base interpreters.
-# - Alternatively use packages opt and (from cookiejar) tcl::idna.
-# - These alternative tests have suffix "opt".
-# - These are 7.[124]opt, 9.1[02]opt, 18.[124]opt.
-# - Tests 7.[124]opt, 9.1[02]opt, 18.[124]opt use "package require opt".
-# - Tests 9.1[02]opt also use "package require tcl::idna".
-#
-# When using package opt for testing positive/negative package search:
-# - The directory location and the error message depend on whether
-# and how the package is installed.
-
-# Error message for tests 7.2opt, 18.2opt for "package require opt".
-if {[string match *zipfs:/* [info library]]} {
- # pkgIndex.tcl is in [info library]
- # file to be sourced is in [info library]/opt*
- set pkgOptErrMsg {permission denied}
-} else {
- # pkgIndex.tcl and file to be sourced are
- # both in [info library]/opt*
- set pkgOptErrMsg {can't find package opt}
-}
-
-# Directory of opt for tests 7.4opt, 9.10opt, 9.12opt, 18.4opt
-# for "package require opt".
-if {[file exists [file join [info library] opt0.4]]} {
- # Installed files in lib8.7/opt0.4
- set pkgOptDir opt0.4
-} elseif {[file exists [file join [info library] opt]]} {
- # Installed files in zipfs, or source files used by "make test"
- set pkgOptDir opt
-} else {
- error {cannot find opt library}
-}
-
-# Directory of cookiejar for tests 9.10opt, 9.12opt
-# for "package require tcl::idna".
-if {[file exists [file join [info library] cookiejar0.2]]} {
- # Installed files in lib8.7/cookiejar0.2
- set pkgJarDir cookiejar0.2
-} elseif {[file exists [file join [info library] cookiejar]]} {
- # Installed files in zipfs, or source files used by "make test"
- set pkgJarDir cookiejar
-} else {
- error {cannot find cookiejar library}
-}
-
set TestsDir [file normalize [file dirname [info script]]]
-set ZipMountPoint [zipfs root]auto-files
-zipfs mount $ZipMountPoint [file join $TestsDir auto-files.zip]
-
-set PathMapp {}
-lappend PathMapp [file join [info library] $pkgOptDir] TCLLIB/OPTDIR
-lappend PathMapp [file join [info library] $pkgJarDir] TCLLIB/JARDIR
-lappend PathMapp $tcl_library TCLLIB $TestsDir TESTSDIR $ZipMountPoint ZIPDIR
+set PathMapp [list $tcl_library TCLLIB $TestsDir TESTSDIR]
proc mapList {map listIn} {
set listOut {}
@@ -110,6 +59,8 @@ catch {safe::interpConfigure}
# package - Tcltest - but it might be absent if we're in standard tclsh)
testConstraint TcltestPackage [expr {![catch {package require Tcltest}]}]
+
+testConstraint AutoSyncDefined 1
test safe-1.1 {safe::interpConfigure syntax} -returnCodes error -body {
safe::interpConfigure
@@ -144,6 +95,8 @@ test safe-2.2 {creating interpreters, should have no aliases} -setup {
a aliases
} -cleanup {
safe::interpDelete a
+ # This (ab)use of safe::interpDelete to delete non-Safe-Base interpreters
+ # is regrettable and should be removed at the next major revision.
} -result ""
test safe-2.3 {creating safe interpreters, should have no unexpected aliases} -setup {
catch {safe::interpDelete a}
@@ -193,6 +146,8 @@ test safe-4.1 {safe::interpDelete} -setup {
} -body {
interp create a
safe::interpDelete a
+ # This (ab)use of safe::interpDelete to delete non-Safe-Base interpreters
+ # is regrettable and should be removed at the next major revision.
} -result ""
test safe-4.2 {safe::interpDelete, indirectly} -setup {
catch {safe::interpDelete a}
@@ -200,6 +155,8 @@ test safe-4.2 {safe::interpDelete, indirectly} -setup {
interp create a
a alias exit safe::interpDelete a
a eval exit
+ # This (ab)use of safe::interpDelete to delete non-Safe-Base interpreters
+ # is regrettable and should be removed at the next major revision.
} -result ""
test safe-4.5 {safe::interpDelete} -setup {
catch {safe::interpDelete a}
@@ -216,51 +173,11 @@ test safe-4.6 {safe::interpDelete, indirectly} -setup {
a eval exit
} -result ""
-# The following test checks whether the definition of tcl_endOfWord can be
-# obtained from auto_loading.
-
-test safe-5.1 {test auto-loading in safe interpreters} -setup {
- catch {safe::interpDelete a}
- safe::interpCreate a
-} -body {
- interp eval a {tcl_endOfWord "" 0}
-} -cleanup {
- safe::interpDelete a
-} -result -1
+# The old test "safe-5.1" has been moved to "safe-stock87-9.8".
+# A replacement test using example files is "safe-9.8".
+# Tests 5.* test the example files before using them to test safe interpreters.
-# test safe interps 'information leak'
-proc SafeEval {script} {
- # Helper procedure that ensures the safe interp is cleaned up even if
- # there is a failure in the script.
- set SafeInterp [interp create -safe]
- catch {$SafeInterp eval $script} msg opts
- interp delete $SafeInterp
- return -options $opts $msg
-}
-
-test safe-6.1 {test safe interpreters knowledge of the world} {
- lsort [SafeEval {info globals}]
-} {tcl_interactive tcl_patchLevel tcl_platform tcl_version}
-test safe-6.2 {test safe interpreters knowledge of the world} {
- SafeEval {info script}
-} {}
-test safe-6.3 {test safe interpreters knowledge of the world} {
- set r [SafeEval {array names tcl_platform}]
- # If running a windows-debug shell, remove the "debug" element from r.
- if {[testConstraint win]} {
- set r [lsearch -all -inline -not -exact $r "debug"]
- }
- set r [lsearch -all -inline -not -exact $r "threaded"]
- lsort $r
-} {byteOrder engine pathSeparator platform pointerSize wordSize}
-
-rename SafeEval {}
-# More test should be added to check that hostname, nameofexecutable, aren't
-# leaking infos, but they still do...
-
-# Tests 7.0* test the example files before using them to test safe interpreters.
-
-test safe-7.0a {example tclIndex commands, test in master interpreter} -setup {
+test safe-5.1 {example tclIndex commands, test in master interpreter} -setup {
set tmpAutoPath $::auto_path
lappend ::auto_path [file join $TestsDir auto0 auto1] [file join $TestsDir auto0 auto2]
} -body {
@@ -274,21 +191,7 @@ test safe-7.0a {example tclIndex commands, test in master interpreter} -setup {
set ::auto_path $tmpAutoPath
auto_reset
} -match glob -result {0 ok1 0 ok2}
-test safe-7.0az {example tclIndex commands, test in master interpreter; zipfs} -setup {
- set tmpAutoPath $::auto_path
- lappend ::auto_path [file join $ZipMountPoint auto0 auto1] [file join $ZipMountPoint auto0 auto2]
-} -body {
- # Try to load the commands.
- set code3 [catch report1 msg3]
- set code4 [catch report2 msg4]
- list $code3 $msg3 $code4 $msg4
-} -cleanup {
- catch {rename report1 {}}
- catch {rename report2 {}}
- set ::auto_path $tmpAutoPath
- auto_reset
-} -match glob -result {0 ok1 0 ok2}
-test safe-7.0b {example tclIndex commands, negative test in master interpreter} -setup {
+test safe-5.2 {example tclIndex commands, negative test in master interpreter} -setup {
set tmpAutoPath $::auto_path
lappend ::auto_path [file join $TestsDir auto0]
} -body {
@@ -302,21 +205,7 @@ test safe-7.0b {example tclIndex commands, negative test in master interpreter}
set ::auto_path $tmpAutoPath
auto_reset
} -match glob -result {1 {invalid command name "report1"} 1 {invalid command name "report2"}}
-test safe-7.0bz {example tclIndex commands, negative test in master interpreter; zipfs} -setup {
- set tmpAutoPath $::auto_path
- lappend ::auto_path [file join $ZipMountPoint auto0]
-} -body {
- # Try to load the commands.
- set code3 [catch report1 msg3]
- set code4 [catch report2 msg4]
- list $code3 $msg3 $code4 $msg4
-} -cleanup {
- catch {rename report1 {}}
- catch {rename report2 {}}
- set ::auto_path $tmpAutoPath
- auto_reset
-} -match glob -result {1 {invalid command name "report1"} 1 {invalid command name "report2"}}
-test safe-7.0c {example pkgIndex.tcl packages, test in master interpreter, child directories} -setup {
+test safe-5.3 {example pkgIndex.tcl packages, test in master interpreter, child directories} -setup {
set tmpAutoPath $::auto_path
lappend ::auto_path [file join $TestsDir auto0]
} -body {
@@ -333,24 +222,7 @@ test safe-7.0c {example pkgIndex.tcl packages, test in master interpreter, child
catch {rename HeresPackage1 {}}
catch {rename HeresPackage2 {}}
} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
-test safe-7.0cz {example pkgIndex.tcl packages, test in master interpreter, child directories; zipfs} -setup {
- set tmpAutoPath $::auto_path
- lappend ::auto_path [file join $ZipMountPoint auto0]
-} -body {
- # Try to load the packages and run a command from each one.
- set code3 [catch {package require SafeTestPackage1} msg3]
- set code4 [catch {package require SafeTestPackage2} msg4]
- set code5 [catch HeresPackage1 msg5]
- set code6 [catch HeresPackage2 msg6]
- list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
-} -cleanup {
- set ::auto_path $tmpAutoPath
- catch {package forget SafeTestPackage1}
- catch {package forget SafeTestPackage2}
- catch {rename HeresPackage1 {}}
- catch {rename HeresPackage2 {}}
-} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
-test safe-7.0d {example pkgIndex.tcl packages, test in master interpreter, main directories} -setup {
+test safe-5.4 {example pkgIndex.tcl packages, test in master interpreter, main directories} -setup {
set tmpAutoPath $::auto_path
lappend ::auto_path [file join $TestsDir auto0 auto1] \
[file join $TestsDir auto0 auto2]
@@ -368,25 +240,7 @@ test safe-7.0d {example pkgIndex.tcl packages, test in master interpreter, main
catch {rename HeresPackage1 {}}
catch {rename HeresPackage2 {}}
} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
-test safe-7.0dz {example pkgIndex.tcl packages, test in master interpreter, main directories; zipfs} -setup {
- set tmpAutoPath $::auto_path
- lappend ::auto_path [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]
-} -body {
- # Try to load the packages and run a command from each one.
- set code3 [catch {package require SafeTestPackage1} msg3]
- set code4 [catch {package require SafeTestPackage2} msg4]
- set code5 [catch HeresPackage1 msg5]
- set code6 [catch HeresPackage2 msg6]
- list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
-} -cleanup {
- set ::auto_path $tmpAutoPath
- catch {package forget SafeTestPackage1}
- catch {package forget SafeTestPackage2}
- catch {rename HeresPackage1 {}}
- catch {rename HeresPackage2 {}}
-} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
-test safe-7.0e {example modules packages, test in master interpreter, replace path} -setup {
+test safe-5.5 {example modules packages, test in master interpreter, replace path} -setup {
set oldTm [tcl::tm::path list]
foreach path $oldTm {
tcl::tm::path remove $path
@@ -412,33 +266,7 @@ test safe-7.0e {example modules packages, test in master interpreter, replace pa
catch {namespace delete ::test0}
catch {namespace delete ::mod1}
} -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
-test safe-7.0ez {example modules packages, test in master interpreter, replace path; zipfs} -setup {
- set oldTm [tcl::tm::path list]
- foreach path $oldTm {
- tcl::tm::path remove $path
- }
- tcl::tm::path add [file join $ZipMountPoint auto0 modules]
-} -body {
- # Try to load the modules and run a command from each one.
- set code0 [catch {package require test0} msg0]
- set code1 [catch {package require mod1::test1} msg1]
- set code2 [catch {package require mod2::test2} msg2]
- set out0 [test0::try0]
- set out1 [mod1::test1::try1]
- set out2 [mod2::test2::try2]
- list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
-} -cleanup {
- tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
- foreach path [lreverse $oldTm] {
- tcl::tm::path add $path
- }
- catch {package forget test0}
- catch {package forget mod1::test1}
- catch {package forget mod2::test2}
- catch {namespace delete ::test0}
- catch {namespace delete ::mod1}
-} -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
-test safe-7.0f {example modules packages, test in master interpreter, append to path} -setup {
+test safe-5.6 {example modules packages, test in master interpreter, append to path} -setup {
tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
# Try to load the modules and run a command from each one.
@@ -457,58 +285,41 @@ test safe-7.0f {example modules packages, test in master interpreter, append to
catch {namespace delete ::test0}
catch {namespace delete ::mod1}
} -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
-test safe-7.0fz {example modules packages, test in master interpreter, append to path; zipfs} -setup {
- tcl::tm::path add [file join $ZipMountPoint auto0 modules]
-} -body {
- # Try to load the modules and run a command from each one.
- set code0 [catch {package require test0} msg0]
- set code1 [catch {package require mod1::test1} msg1]
- set code2 [catch {package require mod2::test2} msg2]
- set out0 [test0::try0]
- set out1 [mod1::test1::try1]
- set out2 [mod2::test2::try2]
- list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
-} -cleanup {
- tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
- catch {package forget test0}
- catch {package forget mod1::test1}
- catch {package forget mod2::test2}
- catch {namespace delete ::test0}
- catch {namespace delete ::mod1}
-} -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
-# high level general test
-# Use example packages not tcl8.x/opt
-test safe-7.1 {tests that everything works at high level with conventional AutoPathSync} -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
+# test safe interps 'information leak'
+proc SafeEval {script} {
+ # Helper procedure that ensures the safe interp is cleaned up even if
+ # there is a failure in the script.
+ set SafeInterp [interp create -safe]
+ catch {$SafeInterp eval $script} msg opts
+ interp delete $SafeInterp
+ return -options $opts $msg
+}
- set tmpAutoPath $::auto_path
- lappend ::auto_path [file join $TestsDir auto0]
- set i [safe::interpCreate]
- set ::auto_path $tmpAutoPath
-} -body {
- # no error shall occur:
- # (because the default access_path shall include 1st level sub dirs so
- # package require in a slave works like in the master)
- set v [interp eval $i {package require SafeTestPackage1}]
- # no error shall occur:
- interp eval $i {HeresPackage1}
- set v
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
+test safe-6.1 {test safe interpreters knowledge of the world} {
+ lsort [SafeEval {info globals}]
+} {tcl_interactive tcl_patchLevel tcl_platform tcl_version}
+test safe-6.2 {test safe interpreters knowledge of the world} {
+ SafeEval {info script}
+} {}
+test safe-6.3 {test safe interpreters knowledge of the world} {
+ set r [SafeEval {array names tcl_platform}]
+ # If running a windows-debug shell, remove the "debug" element from r.
+ if {[testConstraint win]} {
+ set r [lsearch -all -inline -not -exact $r "debug"]
}
-} -match glob -result 1.2.3
+ set r [lsearch -all -inline -not -exact $r "threaded"]
+ lsort $r
+} {byteOrder engine pathSeparator platform pointerSize wordSize}
+
+rename SafeEval {}
+# More test should be added to check that hostname, nameofexecutable, aren't
+# leaking infos, but they still do...
+
# high level general test
-# Use zipped example packages not tcl8.x/opt
-test safe-7.1z {tests that everything works at high level with conventional AutoPathSync; zipfs} -setup {
+# Use example packages not tcl8.x/opt
+test safe-7.1 {tests that everything works at high level with conventional AutoPathSync} -setup {
# All ::safe commands are loaded at start of file.
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
@@ -518,7 +329,7 @@ test safe-7.1z {tests that everything works at high level with conventional Auto
}
set tmpAutoPath $::auto_path
- lappend ::auto_path [file join $ZipMountPoint auto0]
+ lappend ::auto_path [file join $TestsDir auto0]
set i [safe::interpCreate]
set ::auto_path $tmpAutoPath
} -body {
@@ -535,31 +346,6 @@ test safe-7.1z {tests that everything works at high level with conventional Auto
safe::setAutoPathSync $SyncVal_TMP
}
} -match glob -result 1.2.3
-# high level general test
-test safe-7.1opt {tests that everything works at high level with conventional AutoPathSync, use pkg opt} -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
-
- set i [safe::interpCreate]
-} -body {
- # no error shall occur:
- # (because the default access_path shall include 1st level sub dirs so
- # package require in a slave works like in the master)
- set v [interp eval $i {package require opt}]
- # no error shall occur:
- interp eval $i {::tcl::Lempty {a list}}
- set v
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result 0.4.*
test safe-7.2 {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync} -setup {
# All ::safe commands are loaded at start of file.
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
@@ -592,67 +378,6 @@ test safe-7.2 {tests specific path and interpFind/AddToAccessPath with conventio
} -match glob -result {{$p(:0:)} {$p(:*:)} {$p(:*:)} --\
1 {can't find package SafeTestPackage1} --\
{TCLLIB */dummy/unixlike/test/path TESTSDIR/auto0} -- {}}
-test safe-7.2z {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync; zipfs} -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- } else {
- set SyncVal_TMP 1
- }
-} -body {
- set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
- # should not add anything (p0)
- set token1 [safe::interpAddToAccessPath $i [info library]]
- # should add as p* (not p1 if master has a module path)
- set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
- # should add as p* (not p2 if master has a module path)
- set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- # an error shall occur (SafeTestPackage1 is not anymore in the secure 0-level
- # provided deep path)
- list $token1 $token2 $token3 -- \
- [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg -- \
- $mappA -- [safe::interpDelete $i]
-} -cleanup {
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:0:)} {$p(:*:)} {$p(:*:)} --\
- 1 {can't find package SafeTestPackage1} --\
- {TCLLIB */dummy/unixlike/test/path ZIPDIR/auto0} -- {}}
-test safe-7.2opt {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync, use pkg opt} -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- } else {
- set SyncVal_TMP 1
- }
-} -body {
- set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
- # should not add anything (p0)
- set token1 [safe::interpAddToAccessPath $i [info library]]
- # should add as p* (not p1 if master has a module path)
- set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
- # an error shall occur (opt is not anymore in the secure 0-level
- # provided deep path)
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- list $token1 $token2 -- \
- [catch {interp eval $i {package require opt}} msg] $msg -- \
- $mappA -- [safe::interpDelete $i]
-} -cleanup {
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result "{\$p(:0:)} {\$p(:*:)} -- 1 {$pkgOptErrMsg} --\
- {TCLLIB */dummy/unixlike/test/path} -- {}"
test safe-7.3 {check that safe subinterpreters work} {
set g [interp slaves]
if {$g ne {}} {
@@ -667,6 +392,23 @@ test safe-7.3 {check that safe subinterpreters work} {
list $g $h [interp eval $j {join {o k} ""}] [safe::interpDelete $i] \
[interp exists $j] [info vars ::safe::S*]
} {{} {} ok {} 0 {}}
+test safe-7.3.1 {check that safe subinterpreters work with namespace names} -setup {
+} -body {
+ set g [interp slaves]
+ if {$g ne {}} {
+ append g { -- residue of an earlier test}
+ }
+ set h [info vars ::safe::S*]
+ if {$h ne {}} {
+ append h { -- residue of an earlier test}
+ }
+ set i [safe::interpCreate foo::bar]
+ set j [safe::interpCreate [list $i hello::world]]
+ list $g $h [interp eval $j {join {o k} ""}] \
+ [foo::bar eval {hello::world eval {join {o k} ""}}] \
+ [safe::interpDelete $i] \
+ [interp exists $j] [info vars ::safe::S*]
+} -match glob -result {{} {} ok ok {} 0 {}}
test safe-7.4 {tests specific path and positive search with conventional AutoPathSync} -setup {
# All ::safe commands are loaded at start of file.
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
@@ -697,67 +439,6 @@ test safe-7.4 {tests specific path and positive search with conventional AutoPat
}
} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 1.2.3 --\
{TCLLIB * TESTSDIR/auto0/auto1} -- {}}
-test safe-7.4z {tests specific path and positive search with conventional AutoPathSync; zipfs} -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- } else {
- set SyncVal_TMP 1
- }
-} -body {
- set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
- # should not add anything (p0)
- set token1 [safe::interpAddToAccessPath $i [info library]]
- # should add as p* (not p1 if master has a module path)
- set token2 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- # this time, unlike test safe-7.2, SafeTestPackage1 should be found
- list $token1 $token2 -- \
- [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg -- \
- $mappA -- [safe::interpDelete $i]
- # Note that the glob match elides directories (those from the module path)
- # other than the first and last in the access path.
-} -cleanup {
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 1.2.3 --\
- {TCLLIB * ZIPDIR/auto0/auto1} -- {}}
-test safe-7.4opt {tests specific path and positive search with conventional AutoPathSync, use pkg opt} -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- } else {
- set SyncVal_TMP 1
- }
-} -body {
- set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
- # should not add anything (p0)
- set token1 [safe::interpAddToAccessPath $i [info library]]
- # should add as p* (not p1 if master has a module path)
- set token2 [safe::interpAddToAccessPath $i [file join [info library] $pkgOptDir]]
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- # this time, unlike test safe-7.2opt, opt should be found
- list $token1 $token2 -- \
- [catch {interp eval $i {package require opt}} msg] $msg -- \
- $mappA -- [safe::interpDelete $i]
- # Note that the glob match elides directories (those from the module path)
- # other than the first and last in the access path.
-} -cleanup {
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 0.4.* --\
- {TCLLIB * TCLLIB/OPTDIR} -- {}}
-
test safe-7.5 {tests positive and negative module loading with conventional AutoPathSync} -setup {
# All ::safe commands are loaded at start of file.
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
@@ -1034,12 +715,7 @@ test safe-9.7 {interpConfigure widget like behaviour (demystified)} -body {
{-accessPath *} {-nested 1} {-statics 0} {-deleteHook {foo bar}}\
{-accessPath * -statics 1 -nested 1 -deleteHook {foo bar}}\
{-accessPath * -statics 0 -nested 0 -deleteHook toto}}
-test safe-9.8 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset)} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
+test safe-9.8 {test autoloading commands indexed in tclIndex files} -setup {
} -body {
set i [safe::interpCreate -accessPath [list $tcl_library \
[file join $TestsDir auto0 auto1] \
@@ -1050,38 +726,16 @@ test safe-9.8 {interpConfigure change the access path; tclIndex commands unaffec
set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
- # Load auto_load data.
- interp eval $i {catch nonExistentCommand}
-
# Load and run the commands.
- # This guarantees the test will pass even if the tokens are swapped.
set code1 [catch {interp eval $i {report1}} msg1]
set code2 [catch {interp eval $i {report2}} msg2]
- # Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $TestsDir auto0 auto2] \
- [file join $TestsDir auto0 auto1]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set mappB [mapList $PathMapp [dict get $confB -accessPath]]
- set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
- set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
-
- # Run the commands.
- set code3 [catch {interp eval $i {report1}} msg3]
- set code4 [catch {interp eval $i {report2}} msg4]
-
- list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
+ list $path1 $path2 -- $code1 $msg1 $code2 $msg2 -- $mappA
} -cleanup {
safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 --\
- {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
- {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*}}
-test safe-9.8z {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset); zipfs} -setup {
+} -match glob -result {{$p(:1:)} {$p(:2:)} -- 0 ok1 0 ok2 --\
+ {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*}}
+test safe-9.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset), with conventional AutoPathSync} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -1089,13 +743,13 @@ test safe-9.8z {interpConfigure change the access path; tclIndex commands unaffe
}
} -body {
set i [safe::interpCreate -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]]
+ [file join $TestsDir auto0 auto1] \
+ [file join $TestsDir auto0 auto2]]]
# Inspect.
set confA [safe::interpConfigure $i]
set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+ set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
+ set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
# Load auto_load data.
interp eval $i {catch nonExistentCommand}
@@ -1107,13 +761,13 @@ test safe-9.8z {interpConfigure change the access path; tclIndex commands unaffe
# Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto2] \
- [file join $ZipMountPoint auto0 auto1]]
+ [file join $TestsDir auto0 auto2] \
+ [file join $TestsDir auto0 auto1]]
# Inspect.
set confB [safe::interpConfigure $i]
set mappB [mapList $PathMapp [dict get $confB -accessPath]]
- set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
+ set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
+ set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
# Run the commands.
set code3 [catch {interp eval $i {report1}} msg3]
@@ -1126,9 +780,9 @@ test safe-9.8z {interpConfigure change the access path; tclIndex commands unaffe
safe::setAutoPathSync $SyncVal_TMP
}
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 --\
- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} --\
- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*}}
-test safe-9.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset)} -setup {
+ {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
+ {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*}}
+test safe-9.10 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset), with conventional AutoPathSync} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -1174,53 +828,7 @@ test safe-9.9 {interpConfigure change the access path; tclIndex commands unaffec
0 ok1 0 ok2 --\
{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*}}
-test safe-9.9z {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset); zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]]
- # Inspect.
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
-
- # Load auto_load data.
- interp eval $i {catch nonExistentCommand}
-
- # Do not load the commands. With the tokens swapped, the test
- # will pass only if the Safe Base has called auto_reset.
-
- # Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto2] \
- [file join $ZipMountPoint auto0 auto1]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set mappB [mapList $PathMapp [dict get $confB -accessPath]]
- set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
-
- # Load and run the commands.
- set code3 [catch {interp eval $i {report1}} msg3]
- set code4 [catch {interp eval $i {report2}} msg4]
-
- list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
- 0 ok1 0 ok2 --\
- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} --\
- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*}}
-test safe-9.10 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement} -setup {
+test safe-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, with conventional AutoPathSync} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -1273,106 +881,7 @@ test safe-9.10 {interpConfigure change the access path; pkgIndex.tcl packages un
{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
0 OK1 0 OK2}
-test safe-9.10z {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement; zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
-} -body {
- # For complete correspondence to safe-9.10opt, include auto0 in access path.
- set i [safe::interpCreate -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0] \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]]
- # Inspect.
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
-
- # Load pkgIndex.tcl data.
- catch {interp eval $i {package require NOEXIST}}
-
- # Rearrange access path. Swap tokens {$p(:2:)} and {$p(:3:)}.
- # This would have no effect because the records in Pkg of these directories
- # were from access as children of {$p(:1:)}.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0] \
- [file join $ZipMountPoint auto0 auto2] \
- [file join $ZipMountPoint auto0 auto1]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set mappB [mapList $PathMapp [dict get $confB -accessPath]]
- set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
-
- # Try to load the packages and run a command from each one.
- set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
- set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
- set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
- set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]
-
- list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
- $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} -- 0 1.2.3 0 2.3.4 --\
- {TCLLIB ZIPDIR/auto0 ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} --\
- {TCLLIB ZIPDIR/auto0 ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*} --\
- 0 OK1 0 OK2}
-test safe-9.10opt {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, uses pkg opt and tcl::idna} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library \
- [file join $tcl_library $pkgOptDir] \
- [file join $tcl_library $pkgJarDir]]]
- # Inspect.
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- set path1 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
- set path2 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]
-
- # Load pkgIndex.tcl data.
- catch {interp eval $i {package require NOEXIST}}
-
- # Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
- # This has no effect because the records in Pkg of these directories were from access as children of {$p(:0:)}.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $tcl_library $pkgJarDir] \
- [file join $tcl_library $pkgOptDir]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set mappB [mapList $PathMapp [dict get $confB -accessPath]]
- set path3 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
- set path4 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]
-
- # Try to load the packages and run a command from each one.
- set code3 [catch {interp eval $i {package require tcl::idna}} msg3]
- set code4 [catch {interp eval $i {package require opt}} msg4]
- set code5 [catch {interp eval $i {::tcl::Lempty {a list}}} msg5]
- set code6 [catch {interp eval $i {::tcl::idna::IDNAencode example.com}} msg6]
-
- list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
- $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 1.* 0 0.4.* --\
- {TCLLIB TCLLIB/OPTDIR TCLLIB/JARDIR*} --\
- {TCLLIB TCLLIB/JARDIR TCLLIB/OPTDIR*} --\
- 0 0 0 example.com}
-test safe-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, 9.10 without path auto0} -setup {
+test safe-9.12 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, 9.10 without path auto0, with conventional AutoPathSync} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -1420,54 +929,7 @@ test safe-9.11 {interpConfigure change the access path; pkgIndex.tcl packages un
{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
0 OK1 0 OK2}
-test safe-9.11z {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, 9.10 without path auto0; zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]]
- # Inspect.
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
-
- # Load pkgIndex.tcl data.
- catch {interp eval $i {package require NOEXIST}}
-
- # Rearrange access path. Swap tokens {$p(:1:)} and {$p(:2:)}.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto2] \
- [file join $ZipMountPoint auto0 auto1]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set mappB [mapList $PathMapp [dict get $confB -accessPath]]
- set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
-
- # Try to load the packages and run a command from each one.
- set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
- set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
- set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
- set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]
-
- list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
- $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
- 0 1.2.3 0 2.3.4 --\
- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} --\
- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*} --\
- 0 OK1 0 OK2}
-test safe-9.12 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed} -setup {
+test safe-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, with conventional AutoPathSync} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -1509,91 +971,7 @@ test safe-9.12 {interpConfigure change the access path; pkgIndex.tcl packages fa
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
1 {* not found in access path} -- 1 1 --\
{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} -- {TCLLIB*}}
-test safe-9.12z {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed; zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]]
- # Inspect.
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]
-
- # Load pkgIndex.tcl data.
- catch {interp eval $i {package require NOEXIST}}
-
- # Limit access path. Remove tokens {$p(:1:)} and {$p(:2:)}.
- safe::interpConfigure $i -accessPath [list $tcl_library]
-
- # Inspect.
- set confB [safe::interpConfigure $i]
- set mappB [mapList $PathMapp [dict get $confB -accessPath]]
- set code4 [catch {::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]} path4]
- set code5 [catch {::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]} path5]
-
- # Try to load the packages.
- set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
- set code6 [catch {interp eval $i {package require SafeTestPackage2}} msg6]
-
- list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
- $mappA -- $mappB
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
- 1 {* not found in access path} -- 1 1 --\
- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB*}}
-test safe-9.12opt {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, uses pkg opt and tcl::idna} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library \
- [file join $tcl_library $pkgOptDir] \
- [file join $tcl_library $pkgJarDir]]]
- # Inspect.
- set confA [safe::interpConfigure $i]
- set mappA [mapList $PathMapp [dict get $confA -accessPath]]
- set path1 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
- set path2 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]
-
- # Load pkgIndex.tcl data.
- catch {interp eval $i {package require NOEXIST}}
-
- # Limit access path. Remove tokens {$p(:1:)} and {$p(:2:)}.
- safe::interpConfigure $i -accessPath [list $tcl_library]
-
- # Inspect.
- set confB [safe::interpConfigure $i]
- set mappB [mapList $PathMapp [dict get $confB -accessPath]]
- set code4 [catch {::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]} path4]
- set code5 [catch {::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]} path5]
-
- # Try to load the packages.
- set code3 [catch {interp eval $i {package require opt}} msg3]
- set code6 [catch {interp eval $i {package require tcl::idna}} msg6]
-
- list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
- $mappA -- $mappB
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
- 1 {* not found in access path} -- 1 1 --\
- {TCLLIB TCLLIB/OPTDIR TCLLIB/JARDIR*} -- {TCLLIB*}}
-test safe-9.20 {check module loading} -setup {
+test safe-9.20 {check module loading, with conventional AutoPathSync} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -1647,53 +1025,7 @@ test safe-9.20 {check module loading} -setup {
# directories in the access path. Both those things must be sorted before
# comparing with expected results. The test is therefore not totally strict,
# but will notice missing or surplus directories.
-test safe-9.20z {check module loading; zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
- set oldTm [tcl::tm::path list]
- foreach path $oldTm {
- tcl::tm::path remove $path
- }
- tcl::tm::path add [file join $ZipMountPoint auto0 modules]
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library]]
-
- # Inspect.
- set confA [safe::interpConfigure $i]
- set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
- set modsA [interp eval $i {tcl::tm::path list}]
- set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Try to load the packages and run a command from each one.
- set code0 [catch {interp eval $i {package require test0}} msg0]
- set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
- set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
- set out0 [interp eval $i {test0::try0}]
- set out1 [interp eval $i {mod1::test1::try1}]
- set out2 [interp eval $i {mod2::test2::try2}]
-
- list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
- $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $out0 $out1 $out2
-} -cleanup {
- tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
- foreach path [lreverse $oldTm] {
- tcl::tm::path add $path
- }
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
- 0 0.5 0 1.0 0 2.0 --\
- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
- ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
-# See comments on lsort after test safe-9.20.
-test safe-9.21 {interpConfigure change the access path; check module loading; stale data case 1} -setup {
+test safe-9.21 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 1} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -1763,77 +1095,7 @@ test safe-9.21 {interpConfigure change the access path; check module loading; st
TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
res0 res1 res2}
# See comments on lsort after test safe-9.20.
-test safe-9.21z {interpConfigure change the access path; check module loading; stale data case 1; zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
- set oldTm [tcl::tm::path list]
- foreach path $oldTm {
- tcl::tm::path remove $path
- }
- tcl::tm::path add [file join $ZipMountPoint auto0 modules]
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library]]
-
- # Inspect.
- set confA [safe::interpConfigure $i]
- set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
- set modsA [interp eval $i {tcl::tm::path list}]
- set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Add to access path.
- # This injects more tokens, pushing modules to higher token numbers.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
- set modsB [interp eval $i {tcl::tm::path list}]
- set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Load pkg data.
- catch {interp eval $i {package require NOEXIST}}
- catch {interp eval $i {package require mod1::NOEXIST}}
- catch {interp eval $i {package require mod2::NOEXIST}}
-
- # Try to load the packages and run a command from each one.
- set code0 [catch {interp eval $i {package require test0}} msg0]
- set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
- set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
- set out0 [interp eval $i {test0::try0}]
- set out1 [interp eval $i {mod1::test1::try1}]
- set out2 [interp eval $i {mod2::test2::try2}]
-
- list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
- [lsort [list $path3 $path4 $path5]] -- $modsB -- \
- $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
- $out0 $out1 $out2
-} -cleanup {
- tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
- foreach path [lreverse $oldTm] {
- tcl::tm::path add $path
- }
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
- 0 0.5 0 1.0 0 2.0 --\
- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
- ZIPDIR/auto0/modules/mod2} --\
- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules\
- ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} --\
- res0 res1 res2}
-# See comments on lsort after test safe-9.20.
-test safe-9.22 {interpConfigure change the access path; check module loading; stale data case 0} -setup {
+test safe-9.22 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 0} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -1898,72 +1160,7 @@ test safe-9.22 {interpConfigure change the access path; check module loading; st
TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
res0 res1 res2}
# See comments on lsort after test safe-9.20.
-test safe-9.22z {interpConfigure change the access path; check module loading; stale data case 0; zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
- set oldTm [tcl::tm::path list]
- foreach path $oldTm {
- tcl::tm::path remove $path
- }
- tcl::tm::path add [file join $ZipMountPoint auto0 modules]
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library]]
-
- # Inspect.
- set confA [safe::interpConfigure $i]
- set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
- set modsA [interp eval $i {tcl::tm::path list}]
- set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Add to access path.
- # This injects more tokens, pushing modules to higher token numbers.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
- set modsB [interp eval $i {tcl::tm::path list}]
- set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Try to load the packages and run a command from each one.
- set code0 [catch {interp eval $i {package require test0}} msg0]
- set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
- set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
- set out0 [interp eval $i {test0::try0}]
- set out1 [interp eval $i {mod1::test1::try1}]
- set out2 [interp eval $i {mod2::test2::try2}]
-
- list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
- [lsort [list $path3 $path4 $path5]] -- $modsB -- \
- $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
- $out0 $out1 $out2
-} -cleanup {
- tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
- foreach path [lreverse $oldTm] {
- tcl::tm::path add $path
- }
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
- 0 0.5 0 1.0 0 2.0 --\
- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
- ZIPDIR/auto0/modules/mod2} --\
- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules\
- ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} --\
- res0 res1 res2}
-# See comments on lsort after test safe-9.20.
-test safe-9.23 {interpConfigure change the access path; check module loading; stale data case 3} -setup {
+test safe-9.23 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 3} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -2038,82 +1235,7 @@ test safe-9.23 {interpConfigure change the access path; check module loading; st
TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
res0 res1 res2}
# See comments on lsort after test safe-9.20.
-test safe-9.23z {interpConfigure change the access path; check module loading; stale data case 3; zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
- set oldTm [tcl::tm::path list]
- foreach path $oldTm {
- tcl::tm::path remove $path
- }
- tcl::tm::path add [file join $ZipMountPoint auto0 modules]
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library]]
-
- # Inspect.
- set confA [safe::interpConfigure $i]
- set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
- set modsA [interp eval $i {tcl::tm::path list}]
- set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Force the interpreter to acquire pkg data which will soon become stale.
- catch {interp eval $i {package require NOEXIST}}
- catch {interp eval $i {package require mod1::NOEXIST}}
- catch {interp eval $i {package require mod2::NOEXIST}}
-
- # Add to access path.
- # This injects more tokens, pushing modules to higher token numbers.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
- set modsB [interp eval $i {tcl::tm::path list}]
- set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Refresh stale pkg data.
- catch {interp eval $i {package require NOEXIST}}
- catch {interp eval $i {package require mod1::NOEXIST}}
- catch {interp eval $i {package require mod2::NOEXIST}}
-
- # Try to load the packages and run a command from each one.
- set code0 [catch {interp eval $i {package require test0}} msg0]
- set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
- set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
- set out0 [interp eval $i {test0::try0}]
- set out1 [interp eval $i {mod1::test1::try1}]
- set out2 [interp eval $i {mod2::test2::try2}]
-
- list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
- [lsort [list $path3 $path4 $path5]] -- $modsB -- \
- $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
- $out0 $out1 $out2
-} -cleanup {
- tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
- foreach path [lreverse $oldTm] {
- tcl::tm::path add $path
- }
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
- 0 0.5 0 1.0 0 2.0 --\
- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
- ZIPDIR/auto0/modules/mod2} --\
- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules\
- ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} --\
- res0 res1 res2}
-# See comments on lsort after test safe-9.20.
-test safe-9.24 {interpConfigure change the access path; check module loading; stale data case 2 (worst case)} -setup {
+test safe-9.24 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 2 (worst case)} -setup {
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setAutoPathSync]
@@ -2183,76 +1305,6 @@ test safe-9.24 {interpConfigure change the access path; check module loading; st
TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
res0 res1 res2}
# See comments on lsort after test safe-9.20.
-test safe-9.24z {interpConfigure change the access path; check module loading; stale data case 2 (worst case); zipfs} -setup {
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 1
- }
- set oldTm [tcl::tm::path list]
- foreach path $oldTm {
- tcl::tm::path remove $path
- }
- tcl::tm::path add [file join $ZipMountPoint auto0 modules]
-} -body {
- set i [safe::interpCreate -accessPath [list $tcl_library]]
-
- # Inspect.
- set confA [safe::interpConfigure $i]
- set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
- set modsA [interp eval $i {tcl::tm::path list}]
- set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Force the interpreter to acquire pkg data which will soon become stale.
- catch {interp eval $i {package require NOEXIST}}
- catch {interp eval $i {package require mod1::NOEXIST}}
- catch {interp eval $i {package require mod2::NOEXIST}}
-
- # Add to access path.
- # This injects more tokens, pushing modules to higher token numbers.
- safe::interpConfigure $i -accessPath [list $tcl_library \
- [file join $ZipMountPoint auto0 auto1] \
- [file join $ZipMountPoint auto0 auto2]]
- # Inspect.
- set confB [safe::interpConfigure $i]
- set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
- set modsB [interp eval $i {tcl::tm::path list}]
- set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
- set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
- set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]
-
- # Try to load the packages and run a command from each one.
- set code0 [catch {interp eval $i {package require test0}} msg0]
- set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
- set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
- set out0 [interp eval $i {test0::try0}]
- set out1 [interp eval $i {mod1::test1::try1}]
- set out2 [interp eval $i {mod2::test2::try2}]
-
- list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
- [lsort [list $path3 $path4 $path5]] -- $modsB -- \
- $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
- $out0 $out1 $out2
-} -cleanup {
- tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
- foreach path [lreverse $oldTm] {
- tcl::tm::path add $path
- }
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
- 0 0.5 0 1.0 0 2.0 --\
- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1\
- ZIPDIR/auto0/modules/mod2} --\
- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules\
- ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} --\
- res0 res1 res2}
-# See comments on lsort after test safe-9.20.
catch {teststaticpkg Safepkg1 0 0}
test safe-10.1 {testing statics loading} -constraints TcltestPackage -setup {
@@ -2549,7 +1601,7 @@ test safe-13.7 {mimic the glob call by tclPkgUnknown in a safe interpreter [Bug
safe::interpDelete $i
removeDirectory $testdir
} -result {EXPECTED/deletemetoo/pkgIndex.tcl}
-test safe-13.7a {mimic the glob call by tclPkgUnknown in a safe interpreter with multiple subdirectories} -setup {
+test safe-13.7.1 {mimic the glob call by tclPkgUnknown in a safe interpreter with multiple subdirectories} -setup {
set i [safe::interpCreate]
buildEnvironment2 pkgIndex.tcl
} -body {
@@ -2824,74 +1876,6 @@ test safe-18.1 {cf. safe-7.1 - tests that everything works at high level without
safe::setAutoPathSync $SyncVal_TMP
}
} -match glob -result 1.2.3
-test safe-18.1z {cf. safe-7.1 - tests that everything works at high level without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 0
- } else {
- error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
- }
-
- # Without AutoPathSync, we need a more complete auto_path,
- # because the slave will use the same value.
- set lib1 [info library]
- set lib2 [file join $ZipMountPoint auto0]
- set ::auto_TMP $::auto_path
- set ::auto_path [list $lib1 $lib2]
-
- set i [safe::interpCreate]
- set ::auto_path $::auto_TMP
-} -body {
- # no error shall occur:
- # (because the default access_path shall include 1st level sub dirs so
- # package require in a slave works like in the master)
- set v [interp eval $i {package require SafeTestPackage1}]
- # no error shall occur:
- interp eval $i HeresPackage1
- set v
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result 1.2.3
-test safe-18.1opt {cf. safe-7.1opt - tests that everything works at high level without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 0
- } else {
- error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
- }
-
- # Without AutoPathSync, we need a more complete auto_path,
- # because the slave will use the same value.
- set lib1 [info library]
- set lib2 [file dirname $lib1]
- set ::auto_TMP $::auto_path
- set ::auto_path [list $lib1 $lib2]
-
- set i [safe::interpCreate]
- set ::auto_path $::auto_TMP
-} -body {
- # no error shall occur:
- # (because the default access_path shall include 1st level sub dirs so
- # package require in a slave works like in the master)
- set v [interp eval $i {package require opt}]
- # no error shall occur:
- interp eval $i {::tcl::Lempty {a list}}
- set v
-} -cleanup {
- safe::interpDelete $i
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result 0.4.*
test safe-18.2 {cf. safe-7.2 - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync} -constraints AutoSyncDefined -setup {
# All ::safe commands are loaded at start of file.
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
@@ -2928,73 +1912,6 @@ test safe-18.2 {cf. safe-7.2 - tests specific path and interpFind/AddToAccessPat
*/dummy/unixlike/test/path \
$TestsDir/auto0]}\
-statics 0 -nested 1 -deleteHook {} -autoPath [list $tcl_library]} {}"
-test safe-18.2z {cf. safe-7.2 - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 0
- } else {
- error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
- }
-} -body {
- set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
- set auto1 [interp eval $i {set ::auto_path}]
- interp eval $i {set ::auto_path [list {$p(:0:)}]}
- # should not add anything (p0)
- set token1 [safe::interpAddToAccessPath $i [info library]]
- # should add as p* (not p1 if master has a module path)
- set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
- # should add as p* (not p2 if master has a module path)
- set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
- # an error shall occur (SafeTestPackage1 is not anymore in the secure 0-level
- # provided deep path)
- list $auto1 $token1 $token2 $token3 \
- [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg \
- [safe::interpConfigure $i]\
- [safe::interpDelete $i]
-} -cleanup {
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)}\
- 1 {can't find package SafeTestPackage1}\
- {-accessPath {[list $tcl_library \
- */dummy/unixlike/test/path \
- $ZipMountPoint/auto0]}\
- -statics 0 -nested 1 -deleteHook {} -autoPath [list $tcl_library]} {}"
-test safe-18.2opt {cf. safe-7.2opt - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 0
- } else {
- error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
- }
-} -body {
- set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
- set auto1 [interp eval $i {set ::auto_path}]
- interp eval $i {set ::auto_path [list {$p(:0:)}]}
- # should not add anything (p0)
- set token1 [safe::interpAddToAccessPath $i [info library]]
- # should add as p* (not p1 if master has a module path)
- set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
- # an error shall occur (opt is not anymore in the secure 0-level
- # provided deep path)
- list $auto1 $token1 $token2 \
- [catch {interp eval $i {package require opt}} msg] $msg \
- [safe::interpConfigure $i]\
- [safe::interpDelete $i]
-} -cleanup {
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} 1 {$pkgOptErrMsg}\
- {-accessPath {[list $tcl_library */dummy/unixlike/test/path]}\
- -statics 0 -nested 1 -deleteHook {} -autoPath [list $tcl_library]} {}"
test safe-18.3 {Check that default auto_path is the same as in the master interpreter without conventional AutoPathSync} -constraints AutoSyncDefined -setup {
# All ::safe commands are loaded at start of file.
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
@@ -3068,90 +1985,6 @@ test safe-18.4 {cf. safe-7.4 - tests specific path and positive search and auto_
{-accessPath {[list $tcl_library *$TestsDir/auto0 $TestsDir/auto0/auto1]}\
-statics 0 -nested 1 -deleteHook {}\
-autoPath {[list $tcl_library $TestsDir/auto0]}} {}"
-test safe-18.4z {cf. safe-7.4 - tests specific path and positive search and auto_path without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 0
- } else {
- error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
- }
-} -body {
- set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
-
- # should not have been set by Safe Base:
- set auto1 [interp eval $i {set ::auto_path}]
-
- interp eval $i {set ::auto_path [list {$p(:0:)}]}
-
- # should not add anything (p0)
- set token1 [safe::interpAddToAccessPath $i [info library]]
-
- # should add as p* (not p1 if master has a module path)
- set token2 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
-
- # should add as p* (not p2 if master has a module path)
- set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0 auto1]]
-
- # should not have been changed by Safe Base:
- set auto2 [interp eval $i {set ::auto_path}]
-
- set auto3 [interp eval $i [list set ::auto_path [list {$p(:0:)} $token2]]]
-
- # This time, unlike test safe-18.2 and the try above, SafeTestPackage1 should be found:
- list $auto1 $auto2 $token1 $token2 $token3 \
- [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg \
- [safe::interpConfigure $i]\
- [safe::interpDelete $i]
-} -cleanup {
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)} 0 1.2.3\
- {-accessPath {[list $tcl_library *$ZipMountPoint/auto0 $ZipMountPoint/auto0/auto1]}\
- -statics 0 -nested 1 -deleteHook {}\
- -autoPath {[list $tcl_library $ZipMountPoint/auto0]}} {}"
-test safe-18.4opt {cf. safe-7.4opt - tests specific path and positive search and auto_path without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
- # All ::safe commands are loaded at start of file.
- set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
-
- if {$SyncExists} {
- set SyncVal_TMP [safe::setAutoPathSync]
- safe::setAutoPathSync 0
- } else {
- error {This test is meaningful only if the command ::safe::setAutoPathSync is defined}
- }
-} -body {
- set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
-
- # should not have been set by Safe Base:
- set auto1 [interp eval $i {set ::auto_path}]
-
- interp eval $i {set ::auto_path [list {$p(:0:)}]}
-
- # should not add anything (p0)
- set token1 [safe::interpAddToAccessPath $i [info library]]
-
- # should add as p* (not p1 if master has a module path)
- set token2 [safe::interpAddToAccessPath $i [file join [info library] $pkgOptDir]]
-
- # should not have been changed by Safe Base:
- set auto2 [interp eval $i {set ::auto_path}]
-
- # This time, unlike test safe-18.2opt and the try above, opt should be found:
- list $auto1 $auto2 $token1 $token2 \
- [catch {interp eval $i {package require opt}} msg] $msg \
- [safe::interpConfigure $i]\
- [safe::interpDelete $i]
-} -cleanup {
- if {$SyncExists} {
- safe::setAutoPathSync $SyncVal_TMP
- }
-} -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} 0 0.4.*\
- {-accessPath {[list $tcl_library *$tcl_library/$pkgOptDir]}\
- -statics 0 -nested 1 -deleteHook {} -autoPath [list $tcl_library]} {}"
test safe-18.5 {cf. safe-7.5 - tests positive and negative module loading without conventional AutoPathSync} -setup {
# All ::safe commands are loaded at start of file.
set SyncExists [expr {[info commands ::safe::setAutoPathSync] ne {}}]
@@ -3222,8 +2055,7 @@ test safe-19.2 {Check that each directory of the module path is a valid token} -
} -result {}
set ::auto_path $SaveAutoPath
-zipfs unmount ${ZipMountPoint}
-unset pkgOptErrMsg pkgOptDir pkgJarDir SaveAutoPath TestsDir ZipMountPoint PathMapp
+unset SaveAutoPath TestsDir PathMapp
rename mapList {}
rename mapAndSortList {}
# cleanup