From 4e80ae6b4307c21164407627c67bc1e7f3d67b05 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Mon, 11 Mar 2024 14:52:56 +0100 Subject: [PATCH] fix(dav): Abort incomplete CalDAV changes sync Signed-off-by: Christoph Wurst --- apps/dav/lib/CalDAV/CalDavBackend.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index e3b8f9ce731..67f01e8092d 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -2376,7 +2376,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription if ($syncToken) { $qb = $this->db->getQueryBuilder(); - $qb->select('uri', 'operation') + $qb->select('uri', 'operation', 'synctoken') ->from('calendarchanges') ->where( $qb->expr()->andX( @@ -2385,7 +2385,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $qb->expr()->eq('calendarid', $qb->createNamedParameter($calendarId)), $qb->expr()->eq('calendartype', $qb->createNamedParameter($calendarType)) ) - )->orderBy('synctoken'); + )->orderBy('synctoken', 'ASC'); if (is_int($limit) && $limit > 0) { $qb->setMaxResults($limit); } @@ -2396,8 +2396,19 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription // This loop ensures that any duplicates are overwritten, only the // last change on a node is relevant. + $rowNr = 0; while ($row = $stmt->fetch()) { + if ($rowNr === 0 && $row['synctoken'] > $syncToken) { + // The oldest change should have a synctoken equal to the + // token sent by the client. Only then we have the full + // history of changes. Else the data cleanup happened too + // fast (or the client was offline for a long time) and + // we would return an incomplete diff. + // Abort to force a clean and full sync. + return null; + } $changes[$row['uri']] = $row['operation']; + $rowNr++; } $stmt->closeCursor();