mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
🐛 Prevent thumbnail frame recursion overflow (#8763)
Cache in-progress frame traversals before following parent frame links so thumbnail updates stop recursing forever on cyclic or transiently inconsistent shape graphs. Add a regression test that covers cyclic frame-id chains and keeps the expected frame/component extraction behavior intact. Signed-off-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
2ca7acfca6
commit
b99157a246
@ -217,31 +217,37 @@
|
||||
|
||||
root-frame-old? (cfh/root-frame? old-objects old-frame-id)
|
||||
root-frame-new? (cfh/root-frame? new-objects new-frame-id)
|
||||
instance-root? (ctc/instance-root? new-shape)]
|
||||
instance-root? (ctc/instance-root? new-shape)
|
||||
local-result (cond-> #{}
|
||||
root-frame-old?
|
||||
(conj ["frame" old-frame-id])
|
||||
|
||||
(cond-> #{}
|
||||
root-frame-old?
|
||||
(conj ["frame" old-frame-id])
|
||||
root-frame-new?
|
||||
(conj ["frame" new-frame-id])
|
||||
|
||||
root-frame-new?
|
||||
(conj ["frame" new-frame-id])
|
||||
instance-root?
|
||||
(conj ["component" id]))]
|
||||
|
||||
instance-root?
|
||||
(conj ["component" id])
|
||||
(swap! frame-id-cache assoc id {:status :in-progress
|
||||
:result local-result})
|
||||
|
||||
(and (uuid? (:frame-id old-shape))
|
||||
(not= uuid/zero (:frame-id old-shape)))
|
||||
(into (get-frame-ids (:frame-id old-shape)))
|
||||
(let [result
|
||||
(cond-> local-result
|
||||
(and (uuid? (:frame-id old-shape))
|
||||
(not= uuid/zero (:frame-id old-shape)))
|
||||
(into (get-frame-ids-cached (:frame-id old-shape)))
|
||||
|
||||
(and (uuid? (:frame-id new-shape))
|
||||
(not= uuid/zero (:frame-id new-shape)))
|
||||
(into (get-frame-ids (:frame-id new-shape))))))
|
||||
(and (uuid? (:frame-id new-shape))
|
||||
(not= uuid/zero (:frame-id new-shape)))
|
||||
(into (get-frame-ids-cached (:frame-id new-shape))))]
|
||||
(swap! frame-id-cache assoc id {:status :done
|
||||
:result result})
|
||||
result)))
|
||||
|
||||
(get-frame-ids-cached [id]
|
||||
(or (get @frame-id-cache id)
|
||||
(let [result (get-frame-ids id)]
|
||||
(swap! frame-id-cache assoc id result)
|
||||
result)))]
|
||||
(if-let [cached (get @frame-id-cache id)]
|
||||
(:result cached)
|
||||
(get-frame-ids id)))]
|
||||
(into #{}
|
||||
(comp (mapcat extract-ids)
|
||||
(filter (fn [[page-id']] (= page-id page-id')))
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns frontend-tests.data.workspace-thumbnails-test
|
||||
(:require
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.thumbnails :as thumbnails]
|
||||
[cljs.test :as t :include-macros true]))
|
||||
|
||||
(t/deftest extract-frame-changes-handles-cyclic-frame-links
|
||||
(let [page-id (uuid/next)
|
||||
root-id (uuid/next)
|
||||
shape-a-id (uuid/next)
|
||||
shape-b-id (uuid/next)
|
||||
event {:changes [{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id shape-a-id}]}
|
||||
old-data {:pages-index
|
||||
{page-id
|
||||
{:objects
|
||||
{root-id {:id root-id :type :frame :frame-id uuid/zero}
|
||||
shape-a-id {:id shape-a-id :type :rect :frame-id shape-b-id}
|
||||
shape-b-id {:id shape-b-id :type :group :frame-id shape-a-id}}}}}
|
||||
new-data {:pages-index
|
||||
{page-id
|
||||
{:objects
|
||||
{root-id {:id root-id :type :frame :frame-id uuid/zero}
|
||||
shape-a-id {:id shape-a-id :type :rect :frame-id root-id}
|
||||
shape-b-id {:id shape-b-id :type :group :frame-id shape-a-id
|
||||
:component-root true}}}}}]
|
||||
(t/is (= #{["frame" root-id]
|
||||
["component" shape-b-id]}
|
||||
(#'thumbnails/extract-frame-changes page-id [event [old-data new-data]])))))
|
||||
@ -6,6 +6,7 @@
|
||||
[frontend-tests.data.viewer-test]
|
||||
[frontend-tests.data.workspace-colors-test]
|
||||
[frontend-tests.data.workspace-texts-test]
|
||||
[frontend-tests.data.workspace-thumbnails-test]
|
||||
[frontend-tests.helpers-shapes-test]
|
||||
[frontend-tests.logic.comp-remove-swap-slots-test]
|
||||
[frontend-tests.logic.components-and-tokens]
|
||||
@ -43,6 +44,7 @@
|
||||
'frontend-tests.data.viewer-test
|
||||
'frontend-tests.data.workspace-colors-test
|
||||
'frontend-tests.data.workspace-texts-test
|
||||
'frontend-tests.data.workspace-thumbnails-test
|
||||
'frontend-tests.helpers-shapes-test
|
||||
'frontend-tests.logic.comp-remove-swap-slots-test
|
||||
'frontend-tests.logic.components-and-tokens
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user