From f85c9e92002527d1c605dfce92ffec3be19575d1 Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Sat, 21 Mar 2026 13:42:29 +0100 Subject: [PATCH] fix(activesync): handle missing synckey in error handler Treat missing synckey as requiring state reset (like initial sync). Asking for state reset may be wasteful but from what I read it's safe to do mostly. In EAS protocol, synckey '0' means initial sync. Missing synckey is fishy. It indicates a protocol error that occurred before synckey was parsed. Trigger synckey reset to establish a new valid state. See also: MS-ASCMD synckey semantics for initial vs subsequent sync --- lib/Horde/ActiveSync/Request/Sync.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Horde/ActiveSync/Request/Sync.php b/lib/Horde/ActiveSync/Request/Sync.php index 79057978..0c90d4f9 100644 --- a/lib/Horde/ActiveSync/Request/Sync.php +++ b/lib/Horde/ActiveSync/Request/Sync.php @@ -1250,14 +1250,15 @@ protected function _handleError(array $collection) $this->_encoder->startTag(Horde_ActiveSync::SYNC_FOLDERS); - // Get new synckey if needed + // Generate new synckey for initial sync, state reset, or when synckey missing/invalid if ($this->_statusCode == self::STATUS_KEYMISM || !empty($collection['importedchanges']) || !empty($collection['getchanges']) || + empty($collection['synckey']) || $collection['synckey'] == '0') { - $collection['newsynckey'] = Horde_ActiveSync_State_Base::getNewSyncKey(($this->_statusCode == self::STATUS_KEYMISM) ? 0 : $collection['synckey']); - if ($collection['synckey'] != '0') { + $collection['newsynckey'] = Horde_ActiveSync_State_Base::getNewSyncKey(($this->_statusCode == self::STATUS_KEYMISM) ? 0 : ($collection['synckey'] ?? 0)); + if (!empty($collection['synckey']) && $collection['synckey'] != '0') { $this->_state->removeState(array('synckey' => $collection['synckey'])); } }