Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
306 views
in Technique[技术] by (71.8m points)

tcl - Why do Tcler suggest to brace your `expr`essions?

We can evaluate the two expression in two possible ways:

   set a 1
   set b 1
   puts [expr $a + $b ]
   puts [expr {$a + $b } ]

But why hate experienced Tclers the first one, and consider it as bad practice? Does the first usage of expr has some security concern?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The "problem" with expr is that it implements its own "mini language", which includes, among other things, variable substitution (replacing those $a-s with their values) and command substitution (replacing those [command ...] things with the results of running commands), so basically the process of evaluating expr $a + $b goes like this:

  1. The Tcl interpreter parses out four words — expr, $a, + and $b out of the source string. Since two of these words begin with $, variable substitution takes place so really there will be expr, 1, +, and 2.
  2. As usually, the first word is taken to be the name of a command, and others are arguments to it, so the Tcl interpreter looks up a command named expr, and executes it passing it the three arguments: 1, +, and 2.
  3. The implementation if expr then concatenates all the arguments passed to it interpreting them as strings, obtaining a string 1 + 2.
  4. This string is then parsed again — this time by the expr machinery, according to its own rules which include variable- and command substitutions, as already mentioned.

What follows:

  • If you brace your expressions, like in expr {$a + $b}, grouping provided by those curly braces inhibits interpretation by the Tcl interpreter1 of the script intended to be parsed by expr itself. This means in our toy example the expr command would see exactly one argument, $a + $b, and will perform substitutions itself.
  • "Double parsing" explained above might lead to security problems.

    For example, in the following code

    set a {[exec echo rm -rf $::env(HOME)]}
    set b 2
    expr $a + $b
    

    The expr command will itself parse a string [exec echo rm -rf $::env(HOME)] + 2. Its evaluation will fail, but by that time, the contents of your home directory will be supposedly gone. (Note that a kind Tcler placed echo in front of rm in a later edit to my answer in an attempt to save the necks of random copypasters, so the command as written won't call rm but if you remove echo from it, it will.)

  • Double parsing inhibits certain optimisations the Tcl engine can do when dealing with calls to expr.

1 Well, almost — "backslash+newline" sequences are still processed even inside {...} blocks.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...