Dangerous constructs

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]

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.

Anything goes (in a switch)

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.

DKF: The exact semantics of switch were changed (in 8.6?) to ease this. Now, if called with only two arguments, switch assumes the first is a value to switch on and the second is a collection of patterns and bodies. (The compiler then issues a jump table to implement it, which is rather fast.)

Expecting that only one other party can predict a socket

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.

DKF: Fixing this requires that you do an identification exchange after opening the socket. And possibly that you use tls::socket to open the socket in the first place. FTP is unfixable without going to major effort (FTPS is rarely deployed, and sftp works in a totally different way under the covers).

Comparisons also handle strings

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....