Compare commits

...
1 Commits
Author SHA1 Message Date
Andrey Antukh 9e0a9905bd 🐛 Add bounds checking to remove-interaction to prevent crashes
The remove-interaction function used subvec without validating that
the index was within bounds, causing 'Index out of bounds' errors
when removing multiple interactions in rapid succession.

Add bounds validation to return the unchanged interactions vector
when an invalid index is provided. This prevents crashes while
maintaining data integrity and idempotent behavior.

Closes #11546

AI-assisted-by: qwen3.7-plus
2026-09-08 08:33:42 +00:00
2 changed files with 35 additions and 2 deletions

No files matched your search

@@ -714,8 +714,10 @@
(defn remove-interaction
[interactions index]
(let [interactions (or interactions [])]
(into (subvec interactions 0 index)
(subvec interactions (inc index)))))
(if (and (>= index 0) (< index (count interactions)))
(into (subvec interactions 0 index)
(subvec interactions (inc index)))
interactions)))
(defn update-interaction
[interactions index update-fn]
@@ -861,6 +861,37 @@
(t/is (= (:action-type (last new-interactions)) :open-url))))))
(t/deftest remove-interaction-bounds-check
(let [i1 (ctsi/set-action-type ctsi/default-interaction :open-overlay)
i2 (ctsi/set-action-type ctsi/default-interaction :close-overlay)
i3 (ctsi/set-action-type ctsi/default-interaction :prev-screen)
interactions [i1 i2 i3]]
(t/testing "Remove interaction with valid index"
(let [new-interactions (ctsi/remove-interaction interactions 1)]
(t/is (= 2 (count new-interactions)))
(t/is (= :open-overlay (:action-type (first new-interactions))))
(t/is (= :prev-screen (:action-type (second new-interactions))))))
(t/testing "Remove interaction with index out of bounds (too high)"
(let [new-interactions (ctsi/remove-interaction interactions 10)]
(t/is (= 3 (count new-interactions)))
(t/is (= interactions new-interactions))))
(t/testing "Remove interaction with negative index"
(let [new-interactions (ctsi/remove-interaction interactions -1)]
(t/is (= 3 (count new-interactions)))
(t/is (= interactions new-interactions))))
(t/testing "Remove interaction from empty vector"
(let [new-interactions (ctsi/remove-interaction [] 0)]
(t/is (= 0 (count new-interactions)))))
(t/testing "Remove interaction from nil"
(let [new-interactions (ctsi/remove-interaction nil 0)]
(t/is (= 0 (count new-interactions)))))))
(t/deftest remap-interactions
(let [frame1 (cts/setup-shape {:type :frame})
frame2 (cts/setup-shape {:type :frame})