From 6c060848d3155f416ffa4a53173ac184adc67faa Mon Sep 17 00:00:00 2001 From: Jannis Mohlin Tsiroyannis Date: Fri, 20 Feb 2026 14:18:55 +0100 Subject: [PATCH 1/3] Retry a broken query as straigh string query, disregarding any syntax. --- rest/src/main/groovy/whelk/rest/api/SiteSearch.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/rest/src/main/groovy/whelk/rest/api/SiteSearch.java b/rest/src/main/groovy/whelk/rest/api/SiteSearch.java index 8c97eab911..c03103341b 100644 --- a/rest/src/main/groovy/whelk/rest/api/SiteSearch.java +++ b/rest/src/main/groovy/whelk/rest/api/SiteSearch.java @@ -135,7 +135,16 @@ Map findData(Map queryParameters, String baseUri, String path) Map findDesc = getAndIndexDescription(appId + "find"); queryParameters.put("_appConfig", new String[]{mapper.writeValueAsString(search2.buildAppConfig(findDesc))}); } - return search2.doSearch(queryParameters); + try { + return search2.doSearch(queryParameters); + } catch (InvalidQueryException re) { + // The query is broken. Often this means a bit of text (like a title) was copy-pasted as a query + // without regard for query language syntax. Let's just run the whole thing as a string search. + String[] qArr = queryParameters.get("_q"); + qArr[0] = qArr[0].replaceAll("\"", "\\\""); // escape any qutoes + qArr[0] = "\"" + qArr[0] + "\""; // quote as a whole + return search2.doSearch(queryParameters); // It throws again? So be it - let the crud code return an error. + } } else { if (queryParameters.get("_statsrepr") == null && searchSettings.get("statsfind") != null) { queryParameters.put("_statsrepr", new String[]{mapper.writeValueAsString(searchSettings.get("statsfind"))}); From e8a50b9f14b1ca6a870bfe7ba2d66b070514fd97 Mon Sep 17 00:00:00 2001 From: Jannis Mohlin Tsiroyannis Date: Fri, 20 Feb 2026 15:07:39 +0100 Subject: [PATCH 2/3] Handle (one level of) escaping when turning bad query into just a string. --- rest/src/main/groovy/whelk/rest/api/SiteSearch.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rest/src/main/groovy/whelk/rest/api/SiteSearch.java b/rest/src/main/groovy/whelk/rest/api/SiteSearch.java index c03103341b..7891c774cf 100644 --- a/rest/src/main/groovy/whelk/rest/api/SiteSearch.java +++ b/rest/src/main/groovy/whelk/rest/api/SiteSearch.java @@ -141,7 +141,8 @@ Map findData(Map queryParameters, String baseUri, String path) // The query is broken. Often this means a bit of text (like a title) was copy-pasted as a query // without regard for query language syntax. Let's just run the whole thing as a string search. String[] qArr = queryParameters.get("_q"); - qArr[0] = qArr[0].replaceAll("\"", "\\\""); // escape any qutoes + // Escape any unquoted quotes. Totally intuitive, right? And yet not watertight, will actually fail on escaped backslash before quote in query. + qArr[0] = qArr[0].replaceAll("[^\\\\]\"", "\\\\\""); qArr[0] = "\"" + qArr[0] + "\""; // quote as a whole return search2.doSearch(queryParameters); // It throws again? So be it - let the crud code return an error. } From 047af3e997915aa5bf70839fcda9957bc7e40e4c Mon Sep 17 00:00:00 2001 From: Jannis Mohlin Tsiroyannis Date: Fri, 20 Feb 2026 15:11:19 +0100 Subject: [PATCH 3/3] Fix comment. --- rest/src/main/groovy/whelk/rest/api/SiteSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest/src/main/groovy/whelk/rest/api/SiteSearch.java b/rest/src/main/groovy/whelk/rest/api/SiteSearch.java index 7891c774cf..1181234a49 100644 --- a/rest/src/main/groovy/whelk/rest/api/SiteSearch.java +++ b/rest/src/main/groovy/whelk/rest/api/SiteSearch.java @@ -141,7 +141,7 @@ Map findData(Map queryParameters, String baseUri, String path) // The query is broken. Often this means a bit of text (like a title) was copy-pasted as a query // without regard for query language syntax. Let's just run the whole thing as a string search. String[] qArr = queryParameters.get("_q"); - // Escape any unquoted quotes. Totally intuitive, right? And yet not watertight, will actually fail on escaped backslash before quote in query. + // Escape any un-escaped quotes. Totally intuitive, right? And yet not watertight, will actually fail on escaped backslash before quote in query. qArr[0] = qArr[0].replaceAll("[^\\\\]\"", "\\\\\""); qArr[0] = "\"" + qArr[0] + "\""; // quote as a whole return search2.doSearch(queryParameters); // It throws again? So be it - let the crud code return an error.