mirror of
https://github.com/penpot/penpot.git
synced 2026-08-06 21:08:34 +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
|
1 :move-to
|
||||||
2 :line-to
|
2 :line-to
|
||||||
3 :curve-to
|
3 :curve-to
|
||||||
4 :close-path)
|
4 :close-path
|
||||||
res (f type c1x c1y c2x c2y x y)]
|
nil)
|
||||||
|
res (when (some? type)
|
||||||
|
(f type c1x c1y c2x c2y x y))]
|
||||||
(recur (inc index)
|
(recur (inc index)
|
||||||
(if (some? res)
|
(if (some? res)
|
||||||
(conj! result res)
|
(conj! result res)
|
||||||
@ -156,8 +158,11 @@
|
|||||||
1 :move-to
|
1 :move-to
|
||||||
2 :line-to
|
2 :line-to
|
||||||
3 :curve-to
|
3 :curve-to
|
||||||
4 :close-path)
|
4 :close-path
|
||||||
result (f result index type c1x c1y c2x c2y x y)]
|
nil)
|
||||||
|
result (if (some? type)
|
||||||
|
(f result index type c1x c1y c2x c2y x y)
|
||||||
|
result)]
|
||||||
(if (reduced? result)
|
(if (reduced? result)
|
||||||
result
|
result
|
||||||
(recur (inc index) result)))
|
(recur (inc index) result)))
|
||||||
@ -177,9 +182,11 @@
|
|||||||
1 :move-to
|
1 :move-to
|
||||||
2 :line-to
|
2 :line-to
|
||||||
3 :curve-to
|
3 :curve-to
|
||||||
4 :close-path)]
|
4 :close-path
|
||||||
#?(:clj (f type c1x c1y c2x c2y x y)
|
nil)]
|
||||||
:cljs (^function f type c1x c1y c2x c2y x y))))
|
(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*
|
(defn- to-string-segment*
|
||||||
[buffer offset type ^StringBuilder builder]
|
[buffer offset type ^StringBuilder builder]
|
||||||
@ -219,7 +226,10 @@
|
|||||||
(.append ",")
|
(.append ",")
|
||||||
(.append y)))
|
(.append y)))
|
||||||
4 (doto builder
|
4 (doto builder
|
||||||
(.append "Z"))))
|
(.append "Z"))
|
||||||
|
|
||||||
|
;; Skip corrupted/unknown segment types
|
||||||
|
nil))
|
||||||
|
|
||||||
(defn- to-string
|
(defn- to-string
|
||||||
"Format the path data structure to string"
|
"Format the path data structure to string"
|
||||||
@ -236,7 +246,8 @@
|
|||||||
(.toString builder)))
|
(.toString builder)))
|
||||||
|
|
||||||
(defn- read-segment
|
(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]
|
[buffer index]
|
||||||
(let [offset (* index SEGMENT-U8-SIZE)
|
(let [offset (* index SEGMENT-U8-SIZE)
|
||||||
type (buf/read-short buffer offset)]
|
type (buf/read-short buffer offset)]
|
||||||
@ -268,7 +279,10 @@
|
|||||||
:c2y (double c2y)}})
|
:c2y (double c2y)}})
|
||||||
|
|
||||||
4 {:command :close-path
|
4 {:command :close-path
|
||||||
:params {}})))
|
:params {}}
|
||||||
|
|
||||||
|
;; Return nil for corrupted/unknown segment types
|
||||||
|
nil)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; TYPE: PATH-DATA
|
;; TYPE: PATH-DATA
|
||||||
@ -320,8 +334,10 @@
|
|||||||
(when (pos? size)
|
(when (pos? size)
|
||||||
((fn next-seq [i]
|
((fn next-seq [i]
|
||||||
(when (< i size)
|
(when (< i size)
|
||||||
(cons (read-segment buffer i)
|
(let [segment (read-segment buffer i)]
|
||||||
(lazy-seq (next-seq (inc i))))))
|
(if (some? segment)
|
||||||
|
(cons segment (lazy-seq (next-seq (inc i))))
|
||||||
|
(next-seq (inc i))))))
|
||||||
0)))
|
0)))
|
||||||
|
|
||||||
clojure.lang.IReduceInit
|
clojure.lang.IReduceInit
|
||||||
@ -329,7 +345,10 @@
|
|||||||
(loop [index 0
|
(loop [index 0
|
||||||
result start]
|
result start]
|
||||||
(if (< index size)
|
(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)
|
(if (reduced? result)
|
||||||
@result
|
@result
|
||||||
(recur (inc index) result)))
|
(recur (inc index) result)))
|
||||||
@ -407,7 +426,10 @@
|
|||||||
(read-segment buffer 0)
|
(read-segment buffer 0)
|
||||||
nil)]
|
nil)]
|
||||||
(if (< index size)
|
(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)
|
(if (reduced? result)
|
||||||
@result
|
@result
|
||||||
(recur (inc index) result)))
|
(recur (inc index) result)))
|
||||||
@ -417,7 +439,10 @@
|
|||||||
(loop [index 0
|
(loop [index 0
|
||||||
result start]
|
result start]
|
||||||
(if (< index size)
|
(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)
|
(if (reduced? result)
|
||||||
@result
|
@result
|
||||||
(recur (inc index) result)))
|
(recur (inc index) result)))
|
||||||
@ -446,8 +471,10 @@
|
|||||||
(when (pos? size)
|
(when (pos? size)
|
||||||
((fn next-seq [i]
|
((fn next-seq [i]
|
||||||
(when (< i size)
|
(when (< i size)
|
||||||
(cons (read-segment buffer i)
|
(let [segment (read-segment buffer i)]
|
||||||
(lazy-seq (next-seq (inc i))))))
|
(if (some? segment)
|
||||||
|
(cons segment (lazy-seq (next-seq (inc i))))
|
||||||
|
(next-seq (inc i))))))
|
||||||
0)))
|
0)))
|
||||||
|
|
||||||
cljs.core/IPrintWithWriter
|
cljs.core/IPrintWithWriter
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user