From ee273ae73c6c08d6b05e30a2315d1c8c4df952fd Mon Sep 17 00:00:00 2001 From: Robert Stepanek Date: Tue, 27 Jun 2023 14:52:47 +0200 Subject: [PATCH] jmap_calendar: return unsupportedFilter for too large SQL queries Signed-off-by: Robert Stepanek --- .../calendarevent_query_unsupported | 39 +++++++++++++++++++ imap/jmap_calendar.c | 13 +++++-- 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 cassandane/tiny-tests/JMAPCalendars/calendarevent_query_unsupported diff --git a/cassandane/tiny-tests/JMAPCalendars/calendarevent_query_unsupported b/cassandane/tiny-tests/JMAPCalendars/calendarevent_query_unsupported new file mode 100644 index 00000000000..71a6a16f6df --- /dev/null +++ b/cassandane/tiny-tests/JMAPCalendars/calendarevent_query_unsupported @@ -0,0 +1,39 @@ +#!perl +use Cassandane::Tiny; +use Data::UUID; + +sub test_calendarevent_query_unsupported + :min_version_3_9 :needs_component_jmap +{ + my ($self) = @_; + + my $jmap = $self->{jmap}; + my $caldav = $self->{caldav}; + my $uuidgen = Data::UUID->new; + + xlog $self, "Run squatter"; + $self->{instance}->run_command({cyrus => 1}, 'squatter'); + + my $filter = { + operator => 'OR', + conditions => [] + }; + + # evoke a sqlite error for too complex expression trees. + # this filter is non- + for (1 .. 1001) { # this is the internal sqlite3 limit + push(@{$filter->{conditions}}, { + uid => $uuidgen->create_str, + after => '2023-03-04T14:00:00', + }); + } + + my $res = $jmap->CallMethods([ + ['CalendarEvent/query', { + filter => $filter + }, 'R1'], + ]); + $self->assert_str_equals("unsupportedFilter", $res->[0][1]{type}); + + $self->{instance}->getsyslog(); # ignore seen.db DBERROR +} diff --git a/imap/jmap_calendar.c b/imap/jmap_calendar.c index 631c738b4d3..25dc9662248 100644 --- a/imap/jmap_calendar.c +++ b/imap/jmap_calendar.c @@ -7119,7 +7119,7 @@ static int eventquery_run(jmap_req_t *req, { time_t before = caldav_eternity; time_t after = caldav_epoch; - int r = HTTP_NOT_IMPLEMENTED; + int r = 0, r_db = 0; enum caldav_sort *sort = NULL; struct buf buf = BUF_INITIALIZER; size_t nsort = 0; @@ -7176,7 +7176,7 @@ static int eventquery_run(jmap_req_t *req, struct eventquery_fastpath_rock rock = { req, query, is_sharee, BUF_INITIALIZER }; - r = caldav_foreach_jscal(db, req->userid, jscal_filter, NULL, + r_db = caldav_foreach_jscal(db, req->userid, jscal_filter, NULL, sort, nsort, eventquery_fastpath_cb, &rock); buf_free(&rock.buf); is_fastpath = 1; @@ -7197,11 +7197,12 @@ static int eventquery_run(jmap_req_t *req, }; enum caldav_sort mboxsort = CAL_SORT_MAILBOX; - r = caldav_foreach_jscal(db, req->userid, jscal_filter, NULL, + r_db = caldav_foreach_jscal(db, req->userid, jscal_filter, NULL, args.expandrecur ? &mboxsort : sort, args.expandrecur ? 1 : nsort, eventquery_cb, &rock); jmap_closembox(req, &rock.mailbox); + if (r_db) goto done; } if (args.expandrecur) { @@ -7311,6 +7312,12 @@ static int eventquery_run(jmap_req_t *req, eventquery_match_free(&match); } } + if (r_db == SQLDB_ERR_LIMIT && !*err) { + *err = json_pack("{s:s}", "type", "unsupportedFilter"); + } + else if (r_db) { + r = HTTP_SERVER_ERROR; + } ptrarray_fini(&matches); caldav_jscal_filter_fini(jscal_filter); free(jscal_filter);