An unclosed phrase search that has a modifier can cause QueryParser to
enter an infinite loop, tying up open-ils.storage backends.
Examples of such searches include:
-"cats and dogs
subject:+"physical chemistry
This patch fixes the bug by allowing the end of the query string
to terminate a phrase (in addition to a quotation mark).
To test:
[1] Verify that the t/21-QueryParser.t unit test passes
[2] To test in a *development* database, before applying the patch
run one of the example queries. Observe that no
results are returned, and that one of the open-ils.storage
drones is running at 100% CPU.
[3] Apply the patch and restart the open-ils.storage service.
[4] Try the query again; this time, it should return results
immediately without causing an open-ils.storage drone to
peg a CPU.
Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Signed-off-by: Dan Scott <dscott@laurentian.ca>
$_ = $';
$last_type = 'CLASS';
- } elsif (/^\s*($$r{required_re}|$$r{disallowed_re}|$$r{negated_re})?"([^"]+)"/) { # phrase, always anded
+ } elsif (/^\s*($$r{required_re}|$$r{disallowed_re}|$$r{negated_re})?"([^"]+)(?:"|$)/) { # phrase, always anded
warn ' 'x$recursing.'Encountered' . ($1 ? " ['$1' modified]" : '') . " phrase: $2\n" if $self->debug;
my $req_ness = $1 || '';
is($QParser->superpage_size(1000), 1000, 'Superpage size setting works');
is($QParser->superpage_size(), 1000, 'Superpage size stays set');
+init_qp();
+eval {
+ local $SIG{ALRM} = sub { die "timed out!\n" };
+ alarm 1;
+ $QParser->parse('-"unclosed phrase');
+};
+if ($@) {
+ fail('parsing modified unclosed phrase query timed out');
+} else {
+ pass('successfully parsed modified unclosed phrase query');
+}
+
# It's unfortunate not to be able to use the following tests immediately, but
# they reflect assumptions that need to be updated in light of new qp_fix code.
# Also,, canonicalization may not preserve insignificant whitespace nor the