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 $ . 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 however 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 % set ans [read stdin] This is a test with $ and { and even ] in it. ^D This is a test with $ and { and even ] in it. % lindex $ans 0 unmatched open brace in list % 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. Now, of course the response is "well, that input wasn't a list". The point here is that 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'. ---- Important commands to handle data from users for further processing: * [file] and it's 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: * [eval], [uplevel], [namespace eval], [interp eval] * [subst] and unbraced [expr]essions * [exec] * [open] "|$data" * [socket] can be a potential problem too; sending arbitrary data to an arbitrary port on an arbitrary host isn't good... ---- [Category Tutorial] | [Category Security]