From 5d5f7fcc1455077af699f7813bb02cef7aa9e6de Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 14 Sep 2026 14:28:21 +0000 Subject: [PATCH] :bug: Fix workspace crash on non-string thumbnail URIs Thumbnail :uri values arrive from the server over transit, so media-ids decode to UUID objects instead of strings. The resolved-uri? helper added in #11563 called clojure.string/starts-with? on them unconditionally, raising TypeError: str.lastIndexOf is not a function and crashing the workspace on frame render. Guard with string? so non-string URIs fall through to resolve-media, which stringifies them. AI-assisted-by: muse-spark-1.3-contributor --- frontend/src/app/main/refs.cljs | 5 ++-- .../test/frontend_tests/main/refs_test.cljs | 30 +++++++++++++++++++ frontend/test/frontend_tests/runner.cljs | 2 ++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 frontend/test/frontend_tests/main/refs_test.cljs diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 0dae7a5bfd..5d8a6b9824 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -587,8 +587,9 @@ (defn- resolved-uri? "Returns true if the uri is already a fully resolved URI (blob or data)." [uri] - (or (str/starts-with? uri "blob:") - (str/starts-with? uri "data:"))) + (and (string? uri) + (or (str/starts-with? uri "blob:") + (str/starts-with? uri "data:")))) (defn workspace-thumbnail-by-id [object-id] diff --git a/frontend/test/frontend_tests/main/refs_test.cljs b/frontend/test/frontend_tests/main/refs_test.cljs new file mode 100644 index 0000000000..99c9f57657 --- /dev/null +++ b/frontend/test/frontend_tests/main/refs_test.cljs @@ -0,0 +1,30 @@ +;; 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 SUBSIDIARY SL + +(ns frontend-tests.main.refs-test + (:require + [app.common.uuid :as uuid] + [app.main.refs :as refs] + [cljs.test :as t :include-macros true])) + +(def ^:private resolved-uri? @#'refs/resolved-uri?) + +(t/deftest resolved-uri-detects-blob-and-data-uris + (t/is (true? (resolved-uri? "blob:http://localhost/thumb"))) + (t/is (true? (resolved-uri? "data:image/png;base64,iVBOR")))) + +(t/deftest resolved-uri-rejects-plain-media-ids + (t/is (false? (resolved-uri? "275c9c60-7f5e-4a2b-9f1c-2d3e4f5a6b7c"))) + (t/is (false? (resolved-uri? "")))) + +(t/deftest resolved-uri-tolerates-non-string-uris + ;; Thumbnail :uri values arrive from the server over transit, so + ;; media-ids decode to UUID objects instead of strings. These must + ;; fall through to resolve-media instead of raising a TypeError + ;; (str.lastIndexOf is not a function) that crashes the workspace. + (t/is (false? (resolved-uri? (uuid/next)))) + (t/is (false? (resolved-uri? nil))) + (t/is (false? (resolved-uri? 42)))) diff --git a/frontend/test/frontend_tests/runner.cljs b/frontend/test/frontend_tests/runner.cljs index 5927bfabfd..f62963d534 100644 --- a/frontend/test/frontend_tests/runner.cljs +++ b/frontend/test/frontend_tests/runner.cljs @@ -41,6 +41,7 @@ [frontend-tests.logic.update-position-test] [frontend-tests.logic.wasm-modifiers-nil-id-test] [frontend-tests.main-errors-test] + [frontend-tests.main.refs-test] [frontend-tests.plugins.comments-test] [frontend-tests.plugins.context-shapes-test] [frontend-tests.plugins.file-test] @@ -138,6 +139,7 @@ 'frontend-tests.logic.groups-test 'frontend-tests.logic.nudge-selected-shapes-test 'frontend-tests.logic.pasting-in-containers-test + 'frontend-tests.main.refs-test 'frontend-tests.main-errors-test 'frontend-tests.logic.sidebar-transform-coalescing-test 'frontend-tests.logic.update-position-test