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

欢迎!请参阅 关于 页面以获取更多关于如何使用本网站的信息。

+6
集合
编辑

这是预期的行为吗?

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是用户提供的或者是一些可能出错的操作的结果,我们将会引发难以发现的错误或者甚至安全问题。

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

我知道这并不完全是一个相同的问题,但我分享这个条目中适用于我们情况的观点

范围
机密性
完整性

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

我期望在访问数组时使用超出其边界的索引时,将答案保留为 nil

...