From ac7014f2623900374cc20d7fb286009791897028 Mon Sep 17 00:00:00 2001
From: Ere Maijala <ere.maijala@helsinki.fi>
Date: Tue, 15 Jan 2019 13:54:17 +0200
Subject: [PATCH] Bug 13937: Fix RPN conversion
Fixes handling of quotes and parenthesis.
---
Koha/Z3950Responder/RPN.pm | 22 ++++++++++++-------
.../Koha/Z3950Responder/GenericSession.t | 4 ++--
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/Koha/Z3950Responder/RPN.pm b/Koha/Z3950Responder/RPN.pm
index ea8ca37f98..377c5e3d0d 100644
--- a/Koha/Z3950Responder/RPN.pm
+++ b/Koha/Z3950Responder/RPN.pm
@@ -71,9 +71,10 @@ sub to_koha {
$word =~ s/^[\,\.;:\\\/\"\'\-\=]+//g;
$word =~ s/[\,\.;:\\\/\"\'\-\=]+$//g;
next if (!$word);
+ $word = $self->escape($word);
my @words;
foreach my $field (@{$fields}) {
- push(@words, "$field:($prefix$word$suffix)");
+ push(@words, "$field:($quote$prefix$word$suffix$quote)");
}
push (@terms, join(' OR ', @words));
}
@@ -81,15 +82,22 @@ sub to_koha {
}
my @terms;
+ $term = $self->escape($term);
foreach my $field (@{$fields}) {
- push(@terms, "$field:($prefix$term$suffix)");
+ push(@terms, "$field:($quote$prefix$term$suffix$quote)");
}
return '(' . join(' OR ', @terms) . ')';
}
+sub escape {
+ my ($self, $term) = @_;
+
+ $term =~ s/([()])/\\$1/g;
+ return $term;
+}
+
package Net::Z3950::RPN::And;
-sub to_koha
-{
+sub to_koha {
my ($self, $mappings) = @_;
return '(' . $self->[0]->to_koha($mappings) . ' AND ' .
@@ -97,8 +105,7 @@ sub to_koha
}
package Net::Z3950::RPN::Or;
-sub to_koha
-{
+sub to_koha {
my ($self, $mappings) = @_;
return '(' . $self->[0]->to_koha($mappings) . ' OR ' .
@@ -106,8 +113,7 @@ sub to_koha
}
package Net::Z3950::RPN::AndNot;
-sub to_koha
-{
+sub to_koha {
my ($self, $mappings) = @_;
return '(' . $self->[0]->to_koha($mappings) . ' NOT ' .
diff --git a/t/db_dependent/Koha/Z3950Responder/GenericSession.t b/t/db_dependent/Koha/Z3950Responder/GenericSession.t
index 164f53e059..c1bb131cea 100644
--- a/t/db_dependent/Koha/Z3950Responder/GenericSession.t
+++ b/t/db_dependent/Koha/Z3950Responder/GenericSession.t
@@ -68,7 +68,7 @@ subtest 'test_search' => sub {
$search->mock('simple_search_compat', sub {
my ( $self, $query ) = @_;
- return (1, undef, 0) unless $query eq '((author:(author)) AND (title:(title)))';
+ return (1, undef, 0) unless $query eq '((author:("author")) AND ((title:(title\(s\))) OR (title:(another))))';
my @records = ($marc_record_1, $marc_record_2);
return (undef, \@records, 2);
@@ -97,7 +97,7 @@ subtest 'test_search' => sub {
$Zconn->connect('127.0.0.1:42111', 0);
is($Zconn->errcode(), 0, 'Connection is successful: ' . $Zconn->errmsg());
- my $rs = $Zconn->search_pqf('@and @attr 1=1 author @attr 1=4 title');
+ my $rs = $Zconn->search_pqf('@and @attr 1=1 @attr 4=1 author @or @attr 1=4 title(s) @attr 1=4 another');
is($Zconn->errcode(), 0, 'Search is successful: ' . $Zconn->errmsg());
is($rs->size(), 2, 'Two results returned');
--
2.17.1