mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
🐛 Handle corrupted PathData segments gracefully instead of crashing
Add nil defaults to all case expressions that match binary segment type codes so that corrupted/unknown values are skipped instead of throwing 'No matching clause'. This prevents a React render crash (triggered via shape-with-open-path? -> get-subpaths -> reduce) when a PathData buffer contains invalid bytes, e.g. from a WASM data transfer or deserialization of damaged stored data. Affected functions: read-segment, impl-walk, impl-reduce, impl-lookup, to-string-segment*, and the seq/reduce protocol implementations on both JVM and CLJS PathData types. Signed-off-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
0dfa450cc8
commit
2eaa2dc807
@ -131,8 +131,10 @@
|
||||
1 :move-to
|
||||
2 :line-to
|
||||
3 :curve-to
|
||||
4 :close-path)
|
||||
res (f type c1x c1y c2x c2y x y)]
|
||||
4 :close-path
|
||||
nil)
|
||||
res (when (some? type)
|
||||
(f type c1x c1y c2x c2y x y))]
|
||||
(recur (inc index)
|
||||
(if (some? res)
|
||||
(conj! result res)
|
||||
@ -156,8 +158,11 @@
|
||||
1 :move-to
|
||||
2 :line-to
|
||||
3 :curve-to
|
||||
4 :close-path)
|
||||
result (f result index type c1x c1y c2x c2y x y)]
|
||||
4 :close-path
|
||||
nil)
|
||||
result (if (some? type)
|
||||
(f result index type c1x c1y c2x c2y x y)
|
||||
result)]
|
||||
(if (reduced? result)
|
||||
result
|
||||
(recur (inc index) result)))
|
||||
@ -177,9 +182,11 @@
|
||||
1 :move-to
|
||||
2 :line-to
|
||||
3 :curve-to
|
||||
4 :close-path)]
|
||||
#?(:clj (f type c1x c1y c2x c2y x y)
|
||||
:cljs (^function f type c1x c1y c2x c2y x y))))
|
||||
4 :close-path
|
||||
nil)]
|
||||
(when (some? type)
|
||||
#?(:clj (f type c1x c1y c2x c2y x y)
|
||||
:cljs (^function f type c1x c1y c2x c2y x y)))))
|
||||
|
||||
(defn- to-string-segment*
|
||||
[buffer offset type ^StringBuilder builder]
|
||||
@ -219,7 +226,10 @@
|
||||
(.append ",")
|
||||
(.append y)))
|
||||
4 (doto builder
|
||||
(.append "Z"))))
|
||||
(.append "Z"))
|
||||
|
||||
;; Skip corrupted/unknown segment types
|
||||
nil))
|
||||
|
||||
(defn- to-string
|
||||
"Format the path data structure to string"
|
||||
@ -236,7 +246,8 @@
|
||||
(.toString builder)))
|
||||
|
||||
(defn- read-segment
|
||||
"Read segment from binary buffer at specified index"
|
||||
"Read segment from binary buffer at specified index. Returns nil for
|
||||
corrupted/invalid segment types."
|
||||
[buffer index]
|
||||
(let [offset (* index SEGMENT-U8-SIZE)
|
||||
type (buf/read-short buffer offset)]
|
||||
@ -268,7 +279,10 @@
|
||||
:c2y (double c2y)}})
|
||||
|
||||
4 {:command :close-path
|
||||
:params {}})))
|
||||
:params {}}
|
||||
|
||||
;; Return nil for corrupted/unknown segment types
|
||||
nil)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; TYPE: PATH-DATA
|
||||
@ -320,8 +334,10 @@
|
||||
(when (pos? size)
|
||||
((fn next-seq [i]
|
||||
(when (< i size)
|
||||
(cons (read-segment buffer i)
|
||||
(lazy-seq (next-seq (inc i))))))
|
||||
(let [segment (read-segment buffer i)]
|
||||
(if (some? segment)
|
||||
(cons segment (lazy-seq (next-seq (inc i))))
|
||||
(next-seq (inc i))))))
|
||||
0)))
|
||||
|
||||
clojure.lang.IReduceInit
|
||||
@ -329,7 +345,10 @@
|
||||
(loop [index 0
|
||||
result start]
|
||||
(if (< index size)
|
||||
(let [result (f result (read-segment buffer index))]
|
||||
(let [segment (read-segment buffer index)
|
||||
result (if (some? segment)
|
||||
(f result segment)
|
||||
result)]
|
||||
(if (reduced? result)
|
||||
@result
|
||||
(recur (inc index) result)))
|
||||
@ -407,7 +426,10 @@
|
||||
(read-segment buffer 0)
|
||||
nil)]
|
||||
(if (< index size)
|
||||
(let [result (f result (read-segment buffer index))]
|
||||
(let [segment (read-segment buffer index)
|
||||
result (if (some? segment)
|
||||
(f result segment)
|
||||
result)]
|
||||
(if (reduced? result)
|
||||
@result
|
||||
(recur (inc index) result)))
|
||||
@ -417,7 +439,10 @@
|
||||
(loop [index 0
|
||||
result start]
|
||||
(if (< index size)
|
||||
(let [result (f result (read-segment buffer index))]
|
||||
(let [segment (read-segment buffer index)
|
||||
result (if (some? segment)
|
||||
(f result segment)
|
||||
result)]
|
||||
(if (reduced? result)
|
||||
@result
|
||||
(recur (inc index) result)))
|
||||
@ -446,8 +471,10 @@
|
||||
(when (pos? size)
|
||||
((fn next-seq [i]
|
||||
(when (< i size)
|
||||
(cons (read-segment buffer i)
|
||||
(lazy-seq (next-seq (inc i))))))
|
||||
(let [segment (read-segment buffer i)]
|
||||
(if (some? segment)
|
||||
(cons segment (lazy-seq (next-seq (inc i))))
|
||||
(next-seq (inc i))))))
|
||||
0)))
|
||||
|
||||
cljs.core/IPrintWithWriter
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user