1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
|
# safe-stock.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-stock.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 © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
if {"::tcltest" ni [namespace children]} {
package require tcltest 2.5
namespace import -force ::tcltest::*
}
foreach i [interp children] {
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 lib9.0/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 unexported (and
# thus unautoindexed) APIs in this test result arguments:
catch {safe::interpConfigure}
testConstraint AutoSyncDefined 1
# high level general test
test safe-stock-7.1 {tests that everything works at high level with conventional AutoPathSync, use pkg opt} -setup {
set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 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 child works like in the parent)
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::setSyncMode $SyncVal_TMP
}
} -match glob -result 0.4.*
test safe-stock-7.2 {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync, use pkg opt} -setup {
set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 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 parent 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::setSyncMode $SyncVal_TMP
}
} -match glob -result "{\$p(:0:)} {\$p(:*:)} -- 1 {$pkgOptErrMsg} --\
{TCLLIB */dummy/unixlike/test/path} -- {}"
test safe-stock-7.4 {tests specific path and positive search with conventional AutoPathSync, use pkg opt} -setup {
set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 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 parent 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-stock-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::setSyncMode $SyncVal_TMP
}
} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 0.4.* --\
{TCLLIB * TCLLIB/OPTDIR} -- {}}
test safe-stock-7.5 {tests positive and negative module loading with conventional AutoPathSync} -setup {
set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 1
}
set i [safe::interpCreate]
interp eval $i {
package forget platform::shell
package forget platform
catch {namespace delete ::platform}
}
} -body {
# Should raise an error (module ancestor directory issue)
set code1 [catch {interp eval $i {package require shell}} msg1]
# Should not raise an error
set code2 [catch {interp eval $i {package require platform::shell}} msg2]
return [list $code1 $msg1 $code2]
} -cleanup {
safe::interpDelete $i
if {$SyncExists} {
safe::setSyncMode $SyncVal_TMP
}
} -result {1 {can't find package shell} 0}
# 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-stock-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-stock-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::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 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::setSyncMode $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-stock-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::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 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::setSyncMode $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-stock-18.1 {cf. safe-stock-7.1opt - tests that everything works at high level without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 0
} else {
error {This test is meaningful only if the command ::safe::setSyncMode is defined}
}
# Without AutoPathSync, we need a more complete auto_path,
# because the child 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 child works like in the parent)
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::setSyncMode $SyncVal_TMP
}
} -match glob -result 0.4.*
test safe-stock-18.2 {cf. safe-stock-7.2opt - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 0
} else {
error {This test is meaningful only if the command ::safe::setSyncMode is defined}
}
} -body {
set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
set auto1 [interp eval $i {set ::auto_path}]
# This will differ from the value -autoPath {}
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 parent 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::setSyncMode $SyncVal_TMP
}
} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} 1 {$pkgOptErrMsg}\
{-accessPath {[list $tcl_library */dummy/unixlike/test/path]}\
-statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
test safe-stock-18.4 {cf. safe-stock-7.4opt - tests specific path and positive search and auto_path without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 0
} else {
error {This test is meaningful only if the command ::safe::setSyncMode 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}]
# This will differ from the value -autoPath {}
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 parent 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-stock-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::setSyncMode $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 {}} {}"
test safe-stock-18.5 {cf. safe-stock-7.5 - tests positive and negative module loading without conventional AutoPathSync} -setup {
set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
if {$SyncExists} {
set SyncVal_TMP [safe::setSyncMode]
safe::setSyncMode 0
} else {
error {This test is meaningful only if the command ::safe::setSyncMode is defined}
}
set i [safe::interpCreate]
interp eval $i {
package forget platform::shell
package forget platform
catch {namespace delete ::platform}
}
} -body {
# Should raise an error (tests module ancestor directory rule)
set code1 [catch {interp eval $i {package require shell}} msg1]
# Should not raise an error
set code2 [catch {interp eval $i {package require platform::shell}} msg2]
return [list $code1 $msg1 $code2]
} -cleanup {
safe::interpDelete $i
if {$SyncExists} {
safe::setSyncMode $SyncVal_TMP
}
} -result {1 {can't find package shell} 0}
set ::auto_path $SaveAutoPath
unset pkgOptErrMsg pkgOptDir pkgJarDir SaveAutoPath TestsDir PathMapp
rename mapList {}
rename mapAndSortList {}
# cleanup
::tcltest::cleanupTests
return
# Local Variables:
# mode: tcl
# End:
|