请分享您对 2024 Clojure 状态调查 的看法!

欢迎!请参阅 关于 页面了解此处的更多信息。

+3
语法和读取器
重新标记

我本以为 Clojure 会自动加载用于在源代码中读取标记文本的 vars 的命名空间,但实际上并非如此。

给定一个定义有 data_readers.clj 的库,其内容如下所示

{foo/bar my.library.foo/bar
 foo/baz my.library/baz}

尝试读取 #foo/bar [1 2 3] 将会产生这个异常

Syntax error reading source at (REPL:1:69).
Attempting to call unbound fn: #'my.library.foo/bar

为了避免此异常,您需要在使用读取器标签之前 require 库的命名空间。

能够在不进行显式 require 步骤的情况下,仅通过将其添加到类路径来使用库读取器标签将更为方便。

我不清楚为什么这样设计...

如果这是出于 clojure.core 启动时间的考量,或许实际的 var 命名空间加载可以在首次读取标记文本时发生?
如果这是出于意外代码执行的安全影响考虑,也许可以通过 *read-eval* 配置要求数据读取器命名空间的行为?

2 答案

0
by
关于安全影响的说明:我的理解是,这里的威胁是一个恶意的类路径包,当易受攻击的系统读取用户输入时(由攻击者提供)会被激活。我认为虽然这很危险,但是在类路径上存在恶意包本身就足以成为安全漏洞 —— 它可以加载它自己的 `clojure.core` 命名空间,而不是由 `org.clojure/clojure` 艺术品提供的。

因此,攻击者没有必要使用读取标签进行攻击,因为最终落入类路径已经足够了。

因此,可能总是需要要求读取标签 nses,并且,而不是使用 `*read-eval*` 来控制这种加载,只需建议用户使用绑定到 `default-data-readers` 的 `*data-readers*` 进行读取就足够了,这个已经存在...
0
by

如果这种行为改变或者可以配置的话,那就太好了。

目前很难使用开发时间工具,如 haspdebux,因为您必须要求它们在所有地方都可以使用,或者使用工作代码来获取 require 的填补,如 user.clj 注入

...