Fix: time-range filter on VTODO with DTSTART/DUE and CREATED/COMPLETED

visit_time_ranges() reuses a single "original_duration" variable for two
unrelated purposes: the DTSTART->DUE span and the CREATED->COMPLETED span.
When a VTODO carries all four properties (a completed task, which most
clients write with CREATED and COMPLETED), the second assignment clobbers
the first, and the DTSTART/DUE branch of the rfc4791-9.9 table then
reconstructs DUE as DTSTART + (COMPLETED - CREATED).

The elif chain already implements the RFC table correctly (DTSTART/DUE
take precedence over CREATED/COMPLETED), so the CREATED/COMPLETED value
is never wanted there. Keep it in its own variable.

Effect: such a VTODO is filtered against a bogus interval, both in
calendar-query REPORT and in item.find_time_range() (the enclosing range
cached for the storage prefilter), so completed tasks go missing from -
or wrongly appear in - client results.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
TowyTowy
2026-08-04 20:05:04 +02:00
parent 3ad8ae1d39
commit 0e15021c11
4 changed files with 40 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
# Changelog
## 3.7.8.dev
* Fix: time-range filter on a VTODO having DTSTART/DUE and also CREATED/COMPLETED used the CREATED->COMPLETED duration instead of the DTSTART->DUE one, so completed tasks were missing from (or wrongly returned by) calendar-query REPORT results
* Fix: sharing/proppatch: reject in case of write-access but 'p' is in permissions
* Fix: sharing/by-map: catch collection path without trailing / (supporting "pimsync")
* Add: [report] max_expand_occurrence option to separate from max_freebusy_occurrence