From c2da119dc0808ebcc80c4bc7f21ede4a309ef786 Mon Sep 17 00:00:00 2001 From: Shallow Date: Sat, 4 Jul 2026 07:30:33 +0800 Subject: [PATCH] Only deproxify duplicate lookup URLs when proxy matches Proxy.toProper() normalizes non-matching URLs through new URL().href, which appends a trailing slash to bare host URLs (https://example.com -> https://example.com/). Since the duplicate lookup matches stored URLs by exact equality, a translator-supplied canonical URL that does not actually match the proxy scheme would be looked up under the normalized form and silently miss the existing item. Only call toProper() when the proxy regexp actually matches the URL; otherwise keep the URL as the translator supplied it. --- chrome/content/zotero/xpcom/server/server_connector.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/xpcom/server/server_connector.js b/chrome/content/zotero/xpcom/server/server_connector.js index 019f2aa721..322207d6ea 100644 --- a/chrome/content/zotero/xpcom/server/server_connector.js +++ b/chrome/content/zotero/xpcom/server/server_connector.js @@ -340,7 +340,14 @@ Zotero.Server.Connector._getItemIdentifiers = function (data) { let addURL = (url) => { if (proxy && url) { try { - url = proxy.toProper(url); + // Only deproxify when the proxy regexp actually matches. + // toProper() normalizes non-matching URLs through new URL().href, + // which can break exact-match lookups against values stored from + // the translator (e.g. https://example.com vs https://example.com/). + let normalized = new URL(url).href; + if (proxy.regexp.test(normalized)) { + url = proxy.toProper(normalized); + } } catch (e) { Zotero.debug(`Could not deproxify item URL for duplicate lookup: ${e.message}`);