From 88d319c767ff59c629687b598df525a78903c203 Mon Sep 17 00:00:00 2001 From: Petro Vashchuk Date: Tue, 25 May 2021 14:36:20 +0300 Subject: [PATCH] Bug 28316: screen square and curly brackets in the search query This patch screens all square and curly brackets which have no special language meaning, while keeping ranges as they are, allowing ES to search for biblios with titles that contain square and curly brackets and at the same time allows the use of range searches ([1990 TO 2000]). Previously, there was old time fix for curly brackets that replaced them with quotes which made curly brackets range functionality not working, that code was also removed with this patch Also this patch adds tests for this behavior. To reproduce: 1) with ES enabled, search for a book with tittle like "test [test]", which will result in error. 2) apply the patch. 3) search for that book again, which should work now. 4) run test QueryBuilder.t to make sure that it runs successfully. Signed-off-by: Emmi Takkinen --- Koha/SearchEngine/Elasticsearch/QueryBuilder.pm | 8 +++++++- t/Koha/SearchEngine/Elasticsearch/QueryBuilder.t | 13 ++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm index a39931ab0b..1bff8a3cba 100644 --- a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm +++ b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm @@ -930,7 +930,6 @@ sub _clean_search_term { $term =~ s/=/:/g; $term = $self->_convert_index_strings_freeform($term); - $term =~ s/[{}]/"/g; # Remove unbalanced quotes my $unquoted = $term; @@ -944,6 +943,13 @@ sub _clean_search_term { $term =~ s/(\s+)(:+)$lookahead/$1/g; $term =~ s/^://; + # replace all ranges with any square/curly brackets combinations to temporary substitutions (ex: "{a TO b]"" -> "~~LC~~a TO b~~RS~~") + $term =~ s/(\{|\[)([^\s\[\]\{\}]+ TO [^\s\[\]\{\}]+)(\}|\])/'~~L'.($1 eq '[' ? 'S':'C').'~~'.$2.'~~R'.($3 eq ']' ? 'S':'C').'~~'/ge; + # screen all brackets with backslash + $term =~ s/([\{\}\[\]])/\\$1/g; + # restore temporary weird substitutions back to normal brackets + $term =~ s/~~L(C|S)~~([^\s\[\]\{\}]+ TO [^\s\[\]\{\}]+)~~R(C|S)~~/($1 eq 'S' ? '[':'{').$2.($3 eq 'S' ? ']':'}')/ge; + $term = $self->_query_regex_escape_process($term); return $term; diff --git a/t/Koha/SearchEngine/Elasticsearch/QueryBuilder.t b/t/Koha/SearchEngine/Elasticsearch/QueryBuilder.t index b2ce6f4319..7175f63743 100755 --- a/t/Koha/SearchEngine/Elasticsearch/QueryBuilder.t +++ b/t/Koha/SearchEngine/Elasticsearch/QueryBuilder.t @@ -187,7 +187,7 @@ subtest '_split_query() tests' => sub { }; subtest '_clean_search_term() tests' => sub { - plan tests => 12; + plan tests => 13; my $qb; ok( @@ -216,11 +216,14 @@ subtest '_clean_search_term() tests' => sub { $res = $qb->_clean_search_term('test "another : query"'); is($res, 'test "another : query"', 'quoted dangling colon not removed'); - $res = $qb->_clean_search_term('test {another part}'); - is($res, 'test "another part"', 'curly brackets replaced correctly'); + $res = $qb->_clean_search_term('test [123 TO 345]'); + is($res, 'test [123 TO 345]', 'keep inculsive range untouched'); + + $res = $qb->_clean_search_term('test [test TO TEST} [and] {123 TO 456]'); + is($res, 'test [test TO TEST} \[and\] {123 TO 456]', 'keep exclusive range untouched'); - $res = $qb->_clean_search_term('test {another part'); - is($res, 'test another part', 'unbalanced curly brackets replaced correctly'); + $res = $qb->_clean_search_term('test[]test TO TEST] [ {123 to 345}}'); + is($res, 'test\[\]test TO TEST\] \[ \{123 to 345\}\}', 'screen all square and curly brackets'); $res = $qb->_clean_search_term('ti:test AND kw:test'); is($res, 'title:test AND test', 'ti converted to title, kw converted to empty string, dangling colon removed with space preserved'); -- 2.25.1