[Arjen Markus] (12 november 2003) In response to a recent discussion on the c.l.t. about a problem that arose in the context of regular expressions, I have started this page. Its sole purpose: ''document dangerous constructs in Tcl'' ---- '''Using the subst command on arbitrary data:''' set a "Hello," set b "world!" set string "\$a \$b" puts [subst $string] gives: Hello, world! but: set string "\[exit\]" puts [subst $string] stops your program! The subst command allows you to suppress the execution of commands: puts [subst -nocommands $string] gives: [exit] ---- '''Unexpected 0ctals''' Remember that if Tcl is expecting an integer, and the value begins with a 0 (zero), it will interpret it as an octal number. This bug is triggered most often when trying to do arithmetic on date and time values obtained from [[clock format]]. This is especially dangerous since you can (e.g.) write a program in January that works just fine for months, then crashes in August and September. Solution : The [scan] page recommends: set cleanInteger [scan $possiblyZeroedDecimal %d] ---- [RS]: A simple error that will appear only at runtime is not protecting a [switch] command with --: switch $input {...} The error will occur if $input starts with a minus (-) sign. So best always use switch -- $input {...} [LV] There are a number of other tcl commands which also support '''--''' ; if the command supports it, and you are using ''random'' input from users or input files, you probably should use it. ---- [TV] opening any server socket, expecting a certain other party to connect. For instance a file transfer �� la ftp where a control connection triggers a file transfer over a separate socket pair. ---- Please: the next! ---- See also the Frequently Made Mistakes [FMM] page. ---- [[Mention un-braced expr use.]] What's ''dangerous'' about unbraced expr? Short answer: # Uh-oh; what if it's "exec rm -rf ..." rather than "exec touch ..."? set a {[exec touch /tmp/77]} set b {[exec touch /tmp/78]} catch {expr $a + 4} catch {expr {$b + 4}} ---- Also see, "[Update considered harmful]", ... [[and FMM]] ---- [AM] Here is another one: set list {A B C D E} set elem B set a [lsearch $list $elem] This will work nicely, unless you have a list like this: set list {A B ? D E} and you look for "?". This will in fact return 0, not 2! You should use: set a [lsearch -exact $list $elem] as [lsearch] uses glob patterns by default [DKF]: Sometimes in 8.5, it is better to say: if {$elem in $list} { ... } ---- [RS] once had to debug this: proc foo max { for {set i 0} {$i<=$max} {incr i} { #do something with $i } } Harmless enough. But if called with a nonnumeric argument ''max'', say ''foo bar'', it will never terminate, because any integer value of ''i'', in string comparison that is forced in this case, is less than ''bar''. Simple remedy: add incr max 0 before the [for] loop - that will throw an error ''expected integer but got bar'' which is better to understand and fix than an endless loop somewhere deep in the code.... ---- [[ [Arts and crafts of Tcl-Tk programming] [Category Discussion] ]]