From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id DBE8A1F5AF for ; Sun, 21 Jun 2020 19:23:25 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 1/2] imap: *SEARCH: return no results for out-of-range queries Date: Sun, 21 Jun 2020 19:23:24 +0000 Message-Id: <20200621192325.18165-2-e@yhbt.net> In-Reply-To: <20200621192325.18165-1-e@yhbt.net> References: <20200621192325.18165-1-e@yhbt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Unlike FETCH and "UID FETCH" where out-of-range queries can will return the highest UID, SEARCH and "UID SEARCH" handle ranges as-is for filtering. --- lib/PublicInbox/IMAP.pm | 8 ++++---- lib/PublicInbox/IMAPsearchqp.pm | 4 ++-- t/imapd.t | 11 +++++++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/PublicInbox/IMAP.pm b/lib/PublicInbox/IMAP.pm index d8b1fce109e..0508ae381dd 100644 --- a/lib/PublicInbox/IMAP.pm +++ b/lib/PublicInbox/IMAP.pm @@ -689,8 +689,8 @@ sub uid_clamp ($$$) { $$end = $uid_end if $$end > $uid_end; } -sub range_step ($$) { - my ($self, $range_csv) = @_; +sub range_step ($$;$) { + my ($self, $range_csv, $is_search) = @_; my ($beg, $end, $range); if ($$range_csv =~ s/\A([^,]+),//) { $range = $1; @@ -707,7 +707,7 @@ sub range_step ($$) { $beg = $1 + 0; $end = $self->{ibx}->over->max; $end = $uid_end if $end > $uid_end; - $beg = $end if $beg > $end; + $beg = $end if !$is_search && $beg > $end; uid_clamp($self, \$beg, \$end); } elsif ($range =~ /\A[0-9]+\z/) { $beg = $end = $range + 0; @@ -772,7 +772,7 @@ sub refill_uids ($$$;$) { } elsif (!$range_csv) { return 0; } else { - my $next_range = range_step($self, \$range_csv); + my $next_range = range_step($self, \$range_csv, !!$sql); return $next_range if !ref($next_range); # error ($beg, $end, $range_csv) = @$range_info = @$next_range; # continue looping diff --git a/lib/PublicInbox/IMAPsearchqp.pm b/lib/PublicInbox/IMAPsearchqp.pm index 4ea99ea500b..6d7ce32a84a 100644 --- a/lib/PublicInbox/IMAPsearchqp.pm +++ b/lib/PublicInbox/IMAPsearchqp.pm @@ -35,7 +35,7 @@ sub uid_set_xap ($$) { my ($self, $seq_set) = @_; my @u; do { - my $u = $self->{imap}->range_step(\$seq_set); + my $u = $self->{imap}->range_step(\$seq_set, 1); die $u unless ref($u); # break out of the parser on error push @u, "uid:$u->[0]..$u->[1]"; } while ($seq_set); @@ -265,7 +265,7 @@ sub parse { if (my $uid = delete $q->{uid}) { my @u; for my $uid_set (@$uid) { - my $u = $q->{imap}->range_step(\$uid_set); + my $u = $q->{imap}->range_step(\$uid_set, 1); return $u if !ref($u); push @u, "num >= $u->[0] AND num <= $u->[1]"; } diff --git a/t/imapd.t b/t/imapd.t index ffa195d57ac..c17f59b5d8b 100644 --- a/t/imapd.t +++ b/t/imapd.t @@ -118,16 +118,23 @@ $ret = $mic->search('uid 1') or BAIL_OUT "SEARCH FAIL $@"; is_deeply($ret, [ 1 ], 'search UID 1 works'); $ret = $mic->search('uid 1:1') or BAIL_OUT "SEARCH FAIL $@"; is_deeply($ret, [ 1 ], 'search UID 1:1 works'); -$ret = $mic->search('uid 1:*') or BAIL_OUT "SEARCH FAIL $@"; +$ret = $mic->search(\'uid 1:*') or BAIL_OUT "SEARCH FAIL $@"; is_deeply($ret, [ 1 ], 'search UID 1:* works'); +$ret = $mic->search(\'uid 9:*') or BAIL_OUT "SEARCH FAIL $@"; +is_deeply($ret, [], 'search UID 9:* is empty'); SKIP: { - skip 'Xapian missing', 7 if $level eq 'basic'; + skip 'Xapian missing', 9 if $level eq 'basic'; my $x = $mic->search(qw(smaller 99999)); is_deeply($x, [1], 'SMALLER works with Xapian (hit)'); $x = $mic->search(qw(smaller 9)); is_deeply($x, [], 'SMALLER works with Xapian (miss)'); + $x = $mic->search(\'smaller 9 UID 9:*'); + is_deeply($x, [], 'SMALLER + UID works with Xapian (miss)'); + $x = $mic->search(\'larger 9 UID 9:*'); + is_deeply($x, [], 'LARGER + UID works with Xapian (miss)'); + $x = $mic->search(qw(larger 99999)); is_deeply($x, [], 'LARGER works with Xapian (miss)'); $x = $mic->search(qw(larger 9));