2024 Clojure 状态调查! 中分享您的想法。

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

+6
Collections
编辑

这是预期行为吗?

clj
Clojure 1.10.3
user=> (get [1 2 42] 4294967295)
nil
user=> (get [1 2 42] 4294967296)
1
user=> (get [1 2 42] 4294967297)
2
user=> (get [1 2 42] 4294967298)
42
user=> (assoc [1 2 42] 4294967298 :wow)
[1 2 :wow]
user=> (find [1 2 42] 4294967298)
[4294967298 42]
user=> (.intValue 4294967298)
2

(注意这是在 Clojure 1.10.3 中,但语法高亮似乎截断了一部分)

AFAICT,get 与 APersistentVector 中的这一行有关。其他两个是由类似周围的行引起的。

2 答案

+1

选定
 
最佳答案

Java 集合接口是按 int 索引的(最大计数 = 2147483647)。一般来说,如果您在集合中有超过 20 亿个元素,您可能还有其他问题。

我认为索引超出范围(0 Integer/MAX_VALUE)的行为是未定义的。

同意,但这个集合中只有3个项目,所以也许这个传统智慧的先决条件在这里不成立?(对第一句话的回应)
好的,谢谢考虑!
顺便说一句,对于字符串/数组也存在类似的行为

Clojure 1.10.3
user=> (get (into-array [1 2 42]) 4294967296)
1
user=> (get "123" 4294967296)
\1
user=> (get (into-array [1 2 42]) 4294967296 :not-found)
1
user=> (get "123" 4294967296 :not-found)
\1
+6

我相信这份报告可以在代码库中导致更严重的问题,尤其是在比如 get 的文档字符串中没有给出任何警告的情况下。

在我看来,以下成语在社区中非常常见

(get [1 2 3] 5)
;;=> nil

(get [1 2 3] 5 100)
;;=> 100

如果上面5的值是用户提供的或者是可能导致错误的一些数学操作的结果,我们将导致难以找到的bug甚至安全漏洞。

这种索引越界错误可能导致各种问题,这个CVE对这些情况有一些担忧https://cwe.mitre.org/data/definitions/129.html

我知道这并不是完全相同的问题,但我觉得这个条目在这里这里的情况中是适用的。

范围
保密性
完整性

“使用超出数组范围的索引可以触发越界读取或写入操作,或者操作错误的对象;即,“缓冲区溢出”不总是结果。这可能导致敏感数据的泄露或修改。”

我期望在访问超出其范围时使用索引访问数组时,将 nil 值作为答案。

...