跳转到内容

eval

维基百科,自由的百科全书

这是本页的一个历史版本,由Sky6t留言 | 贡献2013年5月12日 (日) 13:29 ActionScript编辑。这可能和当前版本存在着巨大的差异。

在一些程序语言中,eval 是一个把字符串当作表达式执行而返回一个结果的函数;在另一些之中,它执行多行的代码就好像它们被包括在其中,而不是包括 eval 的这一行。eval 的输入不一定是字符串;在支持句法抽象的语言(如 Lisp)中,eval 的输入将会由抽象句法形式组成。

安全风险

当使用 eval 而数据来自不可信任的来源时,一定要特别的注意。比如说,假设 get_data() 函数从 Internet 获取数据,这个 Python 代码就是不安全的:

session['authenticated'] = False
data = get_data()
foo = eval(data)

一个攻击者可以让字符串 "session.update(authenticated=True)" 作为数据提供给这个程序,它将会更新 session 字典以设定一个通过身份验证的键为 True。为了补救这一点,所有将会被 eval 使用的数据必须被转义,或者必须运行于无法访问可能有害的函数的环境下。

使用

eval 的调用有时被没经验的程序员在所有种类的事物上使用。在绝大多数情况下,有更加灵活而不会造成解析代码时速度损失的可替代的方法。

比如说,eval 有时被用于一个简单的邮件合并英语Mail merge设施上,就像如下 PHP 代码所示:

$name = 'John Doe';
$greeting = 'Hello';
$template = '"$greeting,  $name! How can I help you today?"';
print eval("return $template;");

尽管这确实有用,它可能导致一些安全问题 (见安全风险),而且比其它的解决方案慢很多。一个更快和更安全的解决方案可以是改变最后一行为 print $template; 和移除前一行的单引号,或者使用 printf

eval 有时也被用于需要对数学表达式求值的应用中,如电子试算表。这比写一个表达式解析器简单多了,但是发现或者写出一个表达式解析器通常是一个更好的选择。除了可修复的安全风险,使用这种语言的求值特性通常很有可能更慢,也没有那么高的可定制性。

也许 eval 的最佳使用是在 bootstrapping英语Bootstrapping (compilers) 一个新的语言的过程中 (就像 Lisp 那样),以及作为语言的允许用户在受控制的环境下运行他们自己的程序的指导程序。

出于表达式求值的目的,eval 相比表达式解析器的主要优势在于,在 eval 受支持的绝大多数编程环境下,这个表达式可能是任意的复杂,而且可能包括对使用者所写的不可能被解析器的创造者所预先知道的函数的调用。这个能力允许你用一个你可以按需要增强的函数库有效的增加 eval() 引擎,而不必持续的维持一个表达式解析器。然而,如果你不需要这么终极的灵活性,表达式解析器远远更加有效和轻量。

实施

直译语言中,eval 几乎总是被和正常的代码使用一样的解析器实现。在编译语言中,用于编译程序的编译器可能被嵌入在使用 eval 的程序中; 分开来的解释器有时也被使用,尽管这可能会导致重复代码

程序语言

JavaScript

JavaScript 中,eval 是某种介于表达式求值器和语句执行器的混合体。它返回最后一个被求值的表达式的值 (在 JavaScript 中,所有语句都是表达式),也允许最后一个分号省略。

如下示例是一个表达式求值器:

foo = 2;
alert(eval('foo + 2'));

如下示例则是一个语句执行器。

foo = 2;
eval('foo = foo + 2;alert(foo);');

JavaScript 的 eval 的一个应用是解析 JSON 文本,也许是作为 Ajax 框架中的一部分。然而,现代的浏览器提供 JSON.parse 作为这个任务的一个更加安全的替代品。

ActionScript

ActionScript (Flash 的编程语言) 中,eval 不能用于计算任意的表达式。根据 Flash 8 文档,它的使用仅限于代表“变量名,属性,对象或者要检索的影片剪辑。这个参数可以是一个字符串或者对对象实例的一个直接引用”的表达式。[1]

ActionScript 3 不支持 eval。

ActionScript 3 Eval Library[2] 和 D.eval API[3] 是进行中的用以在 ActionScript 3 中创建 eval 的等价物开发项目。

Lisp

  1. ^ http://livedocs.macromedia.com/flash/8/index.html
  2. ^ AS3 Eval Library
  3. ^ D.eval API