35 lines
1.6 KiB
Markdown
35 lines
1.6 KiB
Markdown
# Clojure — CWE-407 Diamond Recursion Scan: CLEAN
|
||
|
||
## Scan Date
|
||
2026-03-29
|
||
|
||
## Targets Checked
|
||
|
||
### 1. Namespace loading (`require` / `load-libs`)
|
||
- **File:** `src/clj/clojure/core.clj`, `load-lib` (line ~5981)
|
||
- **Guard:** `*loaded-libs*` is a `ref`-backed `sorted-set`; `contains? @*loaded-libs* lib` check
|
||
on every `load-lib` call skips already-loaded namespaces.
|
||
- **Result:** CLEAN — O(1) set membership, no re-traversal.
|
||
|
||
### 2. Hierarchy traversal (`isa?`, `ancestors`, `derive`)
|
||
- **File:** `src/clj/clojure/core.clj`, lines 5585–5713
|
||
- **Data structure:** `make-hierarchy` stores `{:parents {} :descendants {} :ancestors {}}`
|
||
where `:ancestors` is a precomputed set maintained eagerly on every `derive` call.
|
||
- **`isa?`:** Uses `contains?` on the precomputed `:ancestors` set — O(1).
|
||
- **`ancestors`:** Returns the precomputed set directly — O(1).
|
||
- **`derive`:** Updates `:ancestors` and `:descendants` sets eagerly — O(N) at
|
||
derive-time but no recursion on query.
|
||
- **Result:** CLEAN — all ancestor queries use precomputed sets.
|
||
|
||
### 3. Protocol dispatch (`find-protocol-impl`)
|
||
- **File:** `src/clj/clojure/core_deftype.clj`, lines 527–546
|
||
- **`super-chain`:** Walks `.getSuperclass` chain — linear, no diamond possible in
|
||
Java single-inheritance.
|
||
- **`supers`:** Java's `Class.getInterfaces()` returns a precomputed interface set.
|
||
- **`find-protocol-impl`:** Looks up `:impls` map directly — O(1) hash lookup.
|
||
- **Result:** CLEAN — no recursive graph traversal.
|
||
|
||
## Conclusion
|
||
|
||
No CWE-407 diamond recursion defects found in Clojure. All hierarchy and namespace
|
||
traversals use precomputed sets or linear single-parent chains.
|