From afb632b8a8c37ecbaddc76da9436772f7c3a9a4f Mon Sep 17 00:00:00 2001 From: Evan Chen Date: Thu, 10 Sep 2026 10:40:25 -0700 Subject: [PATCH] Fix workspace URI paths with square brackets --- CHANGELOG.md | 1 + src/eca/shared.clj | 10 ++++++++++ test/eca/shared_test.clj | 7 ++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bde4b5679..1f8d934d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Accept unescaped square brackets in workspace file URI paths. #594 - Recover Anthropic streaming responses interrupted by transient TLS `bad_record_mac` failures. - BREAKING: `plugins.install` now appends across config layers. Set `plugins.installMode` to `replace` beside the list to exclude inherited plugins as before. diff --git a/src/eca/shared.clj b/src/eca/shared.clj index 35d7e31c8..302b40de0 100644 --- a/src/eca/shared.clj +++ b/src/eca/shared.clj @@ -203,9 +203,19 @@ (string/blank? path) base :else (str base "/" path)))) +(defn ^:private escape-raw-file-uri-path-brackets [uri] + (let [[_ prefix path] (re-matches #"(?is)(file:(?://[^/]*)?)(/.*)" uri) + escape-brackets #(-> % + (string/replace "[" "%5B") + (string/replace "]" "%5D"))] + (if path + (str prefix (escape-brackets path)) + (escape-brackets uri)))) + (defn uri->filename [uri] (let [^URI uri (-> uri (string/replace " " "%20") + escape-raw-file-uri-path-brackets (URI.))] (-> (Paths/get uri) .toString ;; WINDOWS drive letters diff --git a/test/eca/shared_test.clj b/test/eca/shared_test.clj index d6286eb1b..a5c34573b 100644 --- a/test/eca/shared_test.clj +++ b/test/eca/shared_test.clj @@ -19,7 +19,12 @@ (when h/windows? (shared/uri->filename "file:///c:/c.clj"))))) (testing "Spaces" (is (= (h/file-path "/Users/foo/Library/Some Document/comappleCloudDocs") - (shared/uri->filename (h/file-uri "file:///Users/foo/Library/Some Document/comappleCloudDocs")))))) + (shared/uri->filename (h/file-uri "file:///Users/foo/Library/Some Document/comappleCloudDocs"))))) + (testing "Raw square brackets" + (is (= (h/file-path "/path/[workspace") + (shared/uri->filename (h/file-uri "file:///path/[workspace")))) + (is (= (h/file-path "/path/workspace]") + (shared/uri->filename (h/file-uri "file:///path/workspace]")))))) (deftest assoc-some-test (testing "single association"