How can I get input from a user and then safely make use of it?

Purpose: discuss general guidelines for gathering input and then making use of it in Tcl.

A new tcl developer often finds s/he has a problem when dealing with text entered by a user into a specific application.

Sometimes, the problem appears when the user's input is a file name with a space in it. Sometimes, the problem appears when the user inputs a string with some special character like [ or $ or { .

On this page, please add notes and specific best practices samples of code to help a new Tcl programmer avoid these problems.

An observation that can be made is that Tcl actually is a lot better at safely handling data than many other scripting languages (shell scripts, m4, ...) are. When you get into trouble, it is usually because your program is wrong (doing something different than what was intended) but somehow happens to produce the expected results in "simple" cases.

One important thing is to keep the type of the input string in mind as you code. While Tcl has the reputation of everything is a string, not every command expects all its arguments to be arbitrary strings. In the most obvious example, Tcl input or output commands which require a file handle expects that argument to be a string returned from an open type command. Just handing some arbitrary string is very likely not going to work.

Similarly, handing an arbitrary string to a command which expects an argument in a list format may very well not work either.

[Perhaps a real example of this will eventually surface, replacing this comment, since my last attempt failed so miserably...]

02 Sept 2003 Mike Tuxford: Perhaps your mention of showing an example would indeed help. I am confused about what you mean by getting Tcl user input. If this means using an event handler to get stdin input then the braces, brackets, semi-colons will all be escaped properly in the 'string' and there is no danger of the user executing something that way. User input of filenames or paths can be tested using the various file options, etc. You touch on many issues that may have no generic answer but rather answers for specific cases.

LV Okay, here's an example:

 $ tclsh
 % gets stdin ans
 This is a test with $ and { and even ] in it.
 % glob $ans
unmatched open-brace in file name

This is an example of getting input from a user, performing a Tcl action upon it, and finding that the string value results in an error.

A developer has to code in a defensive manner when handing input out of his/her control, so as to not end up with errors being raised when they would be inconvenient or even 'disasterous'.

Another example would be attempting to perform a Tcl operation expecting a list as an argument, but handing it an input string. Many times one may find that the input string qualifies as a list. But, not every string is a valid list - one should ensure that one uses split on an input string if they want to use it as a list.

Important commands to handle data from users for further processing:

  • file and its subcommands for handling filenames in a cross platform style
  • scan to guarantee well-formedness of input data and to avoid the octal trap
  • string is in all its variations to check if input data is what you expect it to be
  • string map is valuable to escape special characters in input data
  • split to properly get a list from string data even if it contains things like {
  • regexp is also useful for pulling apart user input if you know what you're doing with REs
  • interp create -safe for creation of safe interpreters to handle unsafe code/data

Things that should be thought about twice or even more often before it is applied to user data:

[ It would be wonderful if people added to this page more information on things to consider when handling user input.]