From f9d7fd355c6354e81abaea1f8ca4f7f336997c53 Mon Sep 17 00:00:00 2001 From: Felix Schwarz Date: Wed, 28 Jul 2021 11:42:05 +0200 Subject: [PATCH] Add safeguards against mutation of OCCore._queries during enumeration. --- .../OCCore+ConnectionStatus.m | 8 +++++++- ownCloudSDK/Core/ItemList/OCCore+ItemList.m | 9 ++++++++- ownCloudSDK/Core/OCCore+ItemUpdates.m | 8 +++++++- ownCloudSDK/Core/OCCore.m | 19 ++++++++++++++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/ownCloudSDK/Core/Connection Status/OCCore+ConnectionStatus.m b/ownCloudSDK/Core/Connection Status/OCCore+ConnectionStatus.m index 92c1856c..0781105c 100644 --- a/ownCloudSDK/Core/Connection Status/OCCore+ConnectionStatus.m +++ b/ownCloudSDK/Core/Connection Status/OCCore+ConnectionStatus.m @@ -328,7 +328,13 @@ - (void)updateConnectionStatus:(OCCoreConnectionStatus)newStatus withSignal:(OCC [self queueBlock:^{ // See if we can proceed if (self->_state == OCCoreStateRunning) { - for (OCQuery *query in self->_queries) + NSArray *queries; + @synchronized(self->_queries) + { + queries = [self->_queries copy]; + } + + for (OCQuery *query in queries) { if (query.state == OCQueryStateContentsFromCache) { diff --git a/ownCloudSDK/Core/ItemList/OCCore+ItemList.m b/ownCloudSDK/Core/ItemList/OCCore+ItemList.m index a13d2b70..6cd8ad4e 100644 --- a/ownCloudSDK/Core/ItemList/OCCore+ItemList.m +++ b/ownCloudSDK/Core/ItemList/OCCore+ItemList.m @@ -1025,7 +1025,14 @@ - (void)_finalizeQueryUpdatesWithQueryResults:(NSMutableArray *)queryR } // Update queries - for (OCQuery *query in self->_queries) + NSArray *queries; + + @synchronized(self->_queries) + { + queries = [self->_queries copy]; + } + + for (OCQuery *query in queries) { NSMutableArray *useQueryResults = nil; OCItem *queryRootItem = nil; diff --git a/ownCloudSDK/Core/OCCore+ItemUpdates.m b/ownCloudSDK/Core/OCCore+ItemUpdates.m index 26d645e0..86785767 100644 --- a/ownCloudSDK/Core/OCCore+ItemUpdates.m +++ b/ownCloudSDK/Core/OCCore+ItemUpdates.m @@ -223,7 +223,13 @@ - (void)performUpdatesForAddedItems:(nullable NSArray *)addedItems } }; - for (OCQuery *query in self->_queries) + NSArray *queries; + @synchronized(self->_queries) + { + queries = [self->_queries copy]; + } + + for (OCQuery *query in queries) { // Protect full query results against modification (-setFullQueryResults: is protected using @synchronized(query), too) @synchronized(query) diff --git a/ownCloudSDK/Core/OCCore.m b/ownCloudSDK/Core/OCCore.m index 994fe856..dfcce5de 100644 --- a/ownCloudSDK/Core/OCCore.m +++ b/ownCloudSDK/Core/OCCore.m @@ -820,7 +820,10 @@ - (void)startQuery:(OCCoreQuery *)coreQuery { // Add query to list of queries [self queueBlock:^{ - [self->_queries addObject:query]; + @synchronized(self->_queries) + { + [self->_queries addObject:query]; + } }]; if (!query.isCustom) @@ -889,7 +892,10 @@ - (void)stopQuery:(OCCoreQuery *)coreQuery [query.stopAction cancel]; query.state = OCQueryStateStopped; - [self->_queries removeObject:query]; + @synchronized(self->_queries) + { + [self->_queries removeObject:query]; + } }]; } @@ -1101,7 +1107,14 @@ - (void)_replayChangesSinceSyncAnchor:(OCSyncAnchor)fromSyncAnchor newSyncAnchor:syncAnchor beforeQueryUpdates:^(dispatch_block_t _Nonnull completionHandler) { // Find items that moved to a different path - for (OCQuery *query in self->_queries) + NSArray *queries; + + @synchronized(self->_queries) + { + queries = [self->_queries copy]; + } + + for (OCQuery *query in queries) { OCCoreItemList *queryItemList;