Runtime evaluation: Difference between revisions
Content added Content deleted
(→{{header|Tcl}}: better term) |
(→{{header|Tcl}}: Show off much of the advanced goodness we've got in this area) |
||
Line 97: | Line 97: | ||
set result2 [eval [list expr [list $four + 5]]] ;# list input</lang> |
set result2 [eval [list expr [list $four + 5]]] ;# list input</lang> |
||
Tcl handles sandboxing by creating new interpreters. Each interpreter is strongly isolated from all other interpreters except in that the interpreter that creates a sub-interpreter retains management control over that “slave” interpreter. The exact capabilities exposed in the slave are controlled by what commands exist in it; commands in the slave may be aliases for other commands in the master interpreter, which allows for trapping into a more highly authorized context (which can be considered analogous to a system call to an OS kernel). |
|||
Evaluation in a child interpreter, demonstrated in an interactive [[tclsh]]: |
|||
<lang tcl># Create an interpreter with a default set of restrictions |
|||
⚫ | |||
interp create -safe restrictedContext |
|||
set v "secret" |
|||
helper |
|||
interp alias restrictedContext doubleSecret {} example |
|||
% helper eval {set four 4} |
|||
proc example {} { |
|||
4 |
|||
global v |
|||
% set r1 [helper eval {expr $four + 5}] |
|||
lappend v $v |
|||
9</lang> |
|||
return |
|||
} |
|||
puts [restrictedContext eval { |
|||
append v " has been leaked" |
|||
catch {file delete yourCriticalFile.txt} ;# Will be denied! |
|||
doubleSecret |
|||
expr {4 + 5} |
|||
}]; # --> 9 |
|||
puts $v; # --> secret secret</lang> |
|||
As can be seen, the result of the overall evaluation is the same as the result of the evaluation in the slave. |
|||
{{works with|Tcl|8.5}}<br> |
|||
There are resource limits available which allow preventing the evaluated script from going berserk: |
|||
<lang tcl>set i [interp create] |
|||
interp limit $i commands -value [expr [$i eval info cmdcount]+20] -granularity 1 |
|||
interp eval $i { |
|||
set x 0 |
|||
while {1} { |
|||
puts "Counting up... [incr x]" |
|||
} |
|||
⚫ | |||
This produces the output (the last line is an error message): |
|||
<pre>Counting up... 1 |
|||
Counting up... 2 |
|||
Counting up... 3 |
|||
Counting up... 4 |
|||
Counting up... 5 |
|||
Counting up... 6 |
|||
Counting up... 7 |
|||
Counting up... 8 |
|||
Counting up... 9 |
|||
Counting up... 10 |
|||
command count limit exceeded</pre> |
|||
{{Omit From|C}} |
{{Omit From|C}} |
||
{{Omit From|C++}} |
{{Omit From|C++}} |