From e4be23a9157de6ab1b02daf60bd61917a41218f0 Mon Sep 17 00:00:00 2001
From: Janusz Kaczmarek <januszop@gmail.com>
Date: Mon, 22 Jul 2024 12:01:40 +0000
Subject: [PATCH] Bug 37430: (Bug 33407 follow-up) ISBD punctuation removal in
 ES searches

Tiny adjustment for very special and malicious cases needed in
Koha::SearchEngine::Elasticsearch::QueryBuilder::clean_search_term.

Extended unit tests added following Nick's suggestions in
Bug 33407 discussion.

Test plan
=========
1. Use ktd with Elasticsearch and ktd's test data.
2. Edit the 4th record (The C programming language) and add a semicolon
   followed by a space before the slash in 245 $a to have:
   The C programming language ; /
3. Make a search for the first ISBD zone taken verbatim from the forth
   record:
   The C programming language ; / Brian W. Kernighan, Dennis M. Ritchie

   There should be no result.
4. Apply the patch, restart plack.
5. Repeat the search. You should get the record.

Sponsored-by: Ignatianum University in Cracow
Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
---
 Koha/SearchEngine/Elasticsearch/QueryBuilder.pm | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm
index bd0ba281971..b641e97404b 100644
--- a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm
+++ b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm
@@ -1026,8 +1026,13 @@ sub clean_search_term {
     # screen all brackets with backslash
     $term =~ s/(?<!\\)(?:[\\]{2})*([\{\}\[\]])$lookahead/\\$1/g;
 
-    # remove problematic punctuation and escaped slashes surrounded by spaces if truncate
-    $term =~ s/\s+(\s*[&;,:\.=\-\/]|(\\\/)\s*)+\s$lookahead/ /g if $truncate;
+    # Remove problematic punctuation  and escaped slashes surrounded by spaces if truncate.
+    # This mainly relates to ISBD punctuation.
+    # Note that slashes identified as RE limits will not be removed nor the contents of RE
+    # will be altered (cf. @saved_regexes).  In other cases (i.e. escaped slashes
+    # (cf. QueryRegexEscapeOptions) and unescaped slashes not identified as being limits
+    # to a RE, i.e. the last odd unescaped slash), the slashes will be removed.
+    $term =~ s/\s([&;,:\.=\-\/\s]|(\\\/))+\s$lookahead/ /g if $truncate;
 
     # restore all regex contents after escaping brackets:
     for (my $i = 0; $i < @saved_regexes; $i++) {
-- 
2.39.5