4

我正在学习 Clojure 的工作原理,我想知道是否有可能(只是为了了解 Clojure 和 Lisps 方言的一般工作原理)编译一个 Clojure 程序,然后在运行时运行它“禁止”使用eval

请注意,我不是在问技术上是否可行,例如,对正在运行的 Clojure 程序进行热补丁,以便一旦编译了 Clojure 程序,一旦调用eval就会抛出异常。

我要问的是,如果在技术上可以禁止使用eval,那么大多数不使用 REPL 而不是专门eval的 Clojure 程序是否仍然有效?

还是默认/内置 API/宏/函数在运行时在后台使用eval

4

3 回答 3

10

eval是什么将交互式编程带到了 Clojure(和 Lisps)。一旦你将 Clojure 代码编译为 jvm 字节码(它不会在任何地方使用 eval 函数调用),或者将其他 Lisp 方言编译到它们的目标运行时(主要是本机代码),你就不需要 eval 了。

eval应用程序的主要目的是在运行时生成代码并执行它,基本上它允许创建“运行时宏”,这不是该语言的核心 API 需要做的事情。

于 2012-12-02T15:36:06.010 回答
1

我很久以前就问过这个问题,我正在回答我自己的问题,因为出现了额外的信息并且也出现了漏洞,而另一个问题没有正确解决这个问题。

基本上默认的读取函数是不安全的。

2013 年,在所有 Ruby 漏洞利用(人们突然对安全隐患感到担忧)之后,Clojure 小组就这个问题展开了激烈的讨论,在一个名为:

" read-eval默认为 false"

Clojure 文档本身明确指出:

http://clojuredocs.org/clojure_core/clojure.core/read

;; WARNING: You SHOULD NOT use clojure.core/read or
;; clojure.core/read-string to read data from untrusted sources.  They
;; were designed only for reading Clojure code and data from trusted
;; sources

请注意,即使将read-eval设置为false也是不够的(至少在 Clojure 1.5 之前是这样),因为某些 Java 构造函数可能会被强制调用并通过精心制作恶意输入而产生副作用。

这在名为“Clojure 的阅读器不安全”的博客条目中进行了详细解释

http://www.learningclojure.com/2013/02/clojures-reader-is-unsafe.html

长话短说:使用别的东西,比如clojure.edn.

于 2013-03-08T16:14:40.710 回答
0

可以这样说:

  • 大多数使用eval是交互完成的(在 REPL 中)或在编译时完成(例如在宏的扩展和执行期间)
  • eval 的某些用途发生在常规代码中。这可能是一个有用的技巧,例如在电子表格程序中执行动态生成的数学公式时。

由于第二个原因,如果您在全局范围内禁止使用 eval,即使所有内容都已编译,您也会在运行时破坏大量代码/库。

于 2012-12-10T04:01:10.770 回答