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 的 docstrings 中没有任何警告。

在我看来,以下这些习惯用法在社区中非常普遍。

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

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

而且,如果上面的值 5 由用户提供或是由可能导致错误的某个数学运算得到,我们将产生难以找到的漏洞或甚至安全漏洞。

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

我知道这并不是完全相同的问题,但我认为这些观点适用于我们这里的情况。

范围
保密性
完整性

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

我期望在通过超出数组的索引访问数组时,答案会保持为nil

...