为什么 Tcler 建议支持你的“表达"? [英] Why do Tcler suggest to brace your `expr`essions?

查看:24
本文介绍了为什么 Tcler 建议支持你的“表达"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们可以用两种可能的方式评估这两个表达式:

We can evaluate the two expression in two possible ways:

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

但是为什么讨厌有经验的 Tclers 第一个,并将其视为不好的做法?expr 的第一次使用是否有一些安全问题?

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

推荐答案

expr 的问题"在于它实现了自己的迷你语言",其中包括变量替换等(用它们的值替换那些 $a-s)和命令替换(用运行 command[command ...] 东西>s),所以基本上计算 expr $a + $b 的过程是这样的:

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. Tcl 解释器解析出四个单词 —expr$a+$b 在源字符串之外.由于其中两个词以 $ 开头,因此会发生变量替换,因此实际上会有 expr, 1, +> 和 2.
  2. 通常,第一个单词是命令的名称,其他单词是它的参数,因此 Tcl 解释器查找名为 expr 的命令,并执行它并传递给它三个参数:1+2.
  3. 实现 if expr then concatenates 所有传递给它的参数,将它们解释为字符串,得到一个字符串 1 + 2.
  4. 然后这个字符串被再次解析 —这次由 expr 机器根据自己的规则,包括变量和命令替换,如前所述.
  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.

以下内容:

  • 如果你支持你的expr会话,就像在expr{$a + $b},这些花括号提供的分组禁止 Tcl 解释器1 解释旨在由 expr 本身解析的脚本.这意味着在我们的玩具示例中,expr 命令只会看到一个参数,$a + $b,并且会自行执行替换.
  • 上面解释的双重解析"可能会导致安全问题.

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

例如在下面的代码中

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

expr 命令本身会解析一个字符串 [exec echo rm -rf $::env(HOME)] + 2.它的评估将失败,但到那时,您的主目录的内容应该已经消失了.(请注意,在稍后对我的答案进行编辑时,一位好心的 Tcler 将 echo 放在了 rm 前面,以试图挽救随机复制者的脖子,因此所写的命令赢得了't call rm 但如果你从中删除 echo ,它会.)

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

1 好吧,几乎是—"backslash+newline" 序列即使在 {...}.

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

这篇关于为什么 Tcler 建议支持你的“表达"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆