From f93263fe9dc9412c456a2c4a3f2377636bd8d067 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 29 Sep 2021 21:50:30 +0100 Subject: [PATCH 1/3] MXSpaceService: Fix a crash due to recursion depth limit --- MatrixSDK/Space/MXSpaceService.swift | 156 +++++++++++++-------------- changelog.d/4919.bugfix | 1 + 2 files changed, 79 insertions(+), 78 deletions(-) create mode 100644 changelog.d/4919.bugfix diff --git a/MatrixSDK/Space/MXSpaceService.swift b/MatrixSDK/Space/MXSpaceService.swift index 77df37de27..c78e184da0 100644 --- a/MatrixSDK/Space/MXSpaceService.swift +++ b/MatrixSDK/Space/MXSpaceService.swift @@ -132,59 +132,57 @@ public class MXSpaceService: NSObject { self.isGraphBuilding = true self.needsUpdate = false - self.processingQueue.async { - let startDate = Date() - MXLog.debug("[Spaces] buildGraph started") - - let output = PrepareDataResult() - MXLog.debug("[Spaces] preparing data for \(rooms.count) rooms") - self.prepareData(with: rooms, index: 0, output: output) { result in - MXLog.debug("[Spaces] data prepared") - var parentIdsPerRoomId: [String : Set] = [:] - output.spaces.forEach { space in - space.updateChildSpaces(with: output.spacesPerId) - space.updateChildDirectRooms(with: output.directRooms) - space.childRoomIds.forEach { roomId in - var parentIds = parentIdsPerRoomId[roomId] ?? Set() - parentIds.insert(space.spaceId) - parentIdsPerRoomId[roomId] = parentIds - } - space.childSpaces.forEach { childSpace in - var parentIds = parentIdsPerRoomId[childSpace.spaceId] ?? Set() - parentIds.insert(space.spaceId) - parentIdsPerRoomId[childSpace.spaceId] = parentIds - } - } - - self.spaces = output.spaces - self.spacesPerId = output.spacesPerId - self.parentIdsPerRoomId = parentIdsPerRoomId - self.rootSpaces = output.spaces.filter { space in - return parentIdsPerRoomId[space.spaceId] == nil - } - self.orphanedRooms = self.session.rooms.filter { room in - return !room.isDirect && parentIdsPerRoomId[room.roomId] == nil + let startDate = Date() + MXLog.debug("[Spaces] buildGraph started") + + let output = PrepareDataResult() + MXLog.debug("[Spaces] preparing data for \(rooms.count) rooms") + self.prepareData(with: rooms, index: 0, output: output) { result in + MXLog.debug("[Spaces] data prepared") + var parentIdsPerRoomId: [String : Set] = [:] + output.spaces.forEach { space in + space.updateChildSpaces(with: output.spacesPerId) + space.updateChildDirectRooms(with: output.directRooms) + space.childRoomIds.forEach { roomId in + var parentIds = parentIdsPerRoomId[roomId] ?? Set() + parentIds.insert(space.spaceId) + parentIdsPerRoomId[roomId] = parentIds } - self.orphanedDirectRooms = self.session.rooms.filter { room in - return room.isDirect && parentIdsPerRoomId[room.roomId] == nil - } - - var flattenedParentIds: [String: Set] = [:] - self.rootSpaces.forEach { space in - self.buildFlattenedParentIdList(with: space, visitedSpaceIds: [], flattenedParentIds: &flattenedParentIds) - } - self.flattenedParentIds = flattenedParentIds - - // TODO improve updateNotificationsCount and call the method to all spaces once subspaces will be supported - self.notificationCounter.computeNotificationCount(for: self.rootSpaces, with: rooms, flattenedParentIds: flattenedParentIds) - - MXLog.debug("[Spaces] buildGraph ended after \(Date().timeIntervalSince(startDate))s") - - self.completionQueue.async { - self.isGraphBuilding = false - NotificationCenter.default.post(name: MXSpaceService.didBuildSpaceGraph, object: self) + space.childSpaces.forEach { childSpace in + var parentIds = parentIdsPerRoomId[childSpace.spaceId] ?? Set() + parentIds.insert(space.spaceId) + parentIdsPerRoomId[childSpace.spaceId] = parentIds } } + + self.spaces = output.spaces + self.spacesPerId = output.spacesPerId + self.parentIdsPerRoomId = parentIdsPerRoomId + self.rootSpaces = output.spaces.filter { space in + return parentIdsPerRoomId[space.spaceId] == nil + } + self.orphanedRooms = self.session.rooms.filter { room in + return !room.isDirect && parentIdsPerRoomId[room.roomId] == nil + } + self.orphanedDirectRooms = self.session.rooms.filter { room in + return room.isDirect && parentIdsPerRoomId[room.roomId] == nil + } + + var flattenedParentIds: [String: Set] = [:] + self.rootSpaces.forEach { space in + self.buildFlattenedParentIdList(with: space, visitedSpaceIds: [], flattenedParentIds: &flattenedParentIds) + } + self.flattenedParentIds = flattenedParentIds + + // TODO improve updateNotificationsCount and call the method to all spaces once subspaces will be supported + self.notificationCounter.computeNotificationCount(for: self.rootSpaces, with: rooms, flattenedParentIds: flattenedParentIds) + + MXLog.debug("[Spaces] buildGraph ended after \(Date().timeIntervalSince(startDate))s") + + self.completionQueue.async { + self.isGraphBuilding = false + NotificationCenter.default.post(name: MXSpaceService.didBuildSpaceGraph, object: self) + } } } @@ -418,40 +416,42 @@ public class MXSpaceService: NSObject { } private func prepareData(with rooms:[MXRoom], index: Int, output: PrepareDataResult, completion: @escaping (_ result: PrepareDataResult) -> Void) { - guard index < rooms.count else { - completion(output) - return - } - - let room = rooms[index] - if let space = room.toSpace() { - space.readChildRoomsAndMembers { - output.spaces.append(space) - output.spacesPerId[space.spaceId] = space - - self.prepareData(with: rooms, index: index+1, output: output, completion: completion) + self.processingQueue.async { + guard index < rooms.count else { + completion(output) + return } - } else if room.isDirect { - room.members { response in - guard let members = response.value as? MXRoomMembers else { + + let room = rooms[index] + if let space = room.toSpace() { + space.readChildRoomsAndMembers { + output.spaces.append(space) + output.spacesPerId[space.spaceId] = space + self.prepareData(with: rooms, index: index+1, output: output, completion: completion) - return } - - let membersId = members.members?.compactMap({ roomMember in - return roomMember.userId != self.session.myUserId ? roomMember.userId : nil - }) ?? [] - - membersId.forEach { memberId in - var rooms = output.directRooms[memberId] ?? [] - rooms.append(room) - output.directRooms[memberId] = rooms + } else if room.isDirect { + room.members { response in + guard let members = response.value as? MXRoomMembers else { + self.prepareData(with: rooms, index: index+1, output: output, completion: completion) + return + } + + let membersId = members.members?.compactMap({ roomMember in + return roomMember.userId != self.session.myUserId ? roomMember.userId : nil + }) ?? [] + + membersId.forEach { memberId in + var rooms = output.directRooms[memberId] ?? [] + rooms.append(room) + output.directRooms[memberId] = rooms + } + self.prepareData(with: rooms, index: index+1, output: output, completion: completion) } + } else { + output.roomsPerId[room.roomId] = room self.prepareData(with: rooms, index: index+1, output: output, completion: completion) } - } else { - output.roomsPerId[room.roomId] = room - self.prepareData(with: rooms, index: index+1, output: output, completion: completion) } } } diff --git a/changelog.d/4919.bugfix b/changelog.d/4919.bugfix new file mode 100644 index 0000000000..5cea7d0da6 --- /dev/null +++ b/changelog.d/4919.bugfix @@ -0,0 +1 @@ +MXSpaceService: Fix a crash due to recursion depth limit \ No newline at end of file From ae5b099e281014535711ff6c466810e866584ed5 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 30 Sep 2021 22:16:43 +0100 Subject: [PATCH 2/3] version++ --- CHANGES.md | 7 +++++++ MatrixSDK.podspec | 2 +- MatrixSDK/MatrixSDKVersion.m | 2 +- changelog.d/4919.bugfix | 1 - 4 files changed, 9 insertions(+), 3 deletions(-) delete mode 100644 changelog.d/4919.bugfix diff --git a/CHANGES.md b/CHANGES.md index ff8bd98885..4da4a90e9b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +## Changes in 0.20.4 (2021-09-30) + +🐛 Bugfixes + +- MXSpaceService: Fix a crash due to recursion depth limit ([#4919](https://github.com/vector-im/element-ios/issues/4919)) + + ## Changes in 0.20.3 (2021-09-28) 🙌 Improvements diff --git a/MatrixSDK.podspec b/MatrixSDK.podspec index 1b82994775..33c2883f2f 100644 --- a/MatrixSDK.podspec +++ b/MatrixSDK.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "MatrixSDK" - s.version = "0.20.3" + s.version = "0.20.4" s.summary = "The iOS SDK to build apps compatible with Matrix (https://www.matrix.org)" s.description = <<-DESC diff --git a/MatrixSDK/MatrixSDKVersion.m b/MatrixSDK/MatrixSDKVersion.m index ff5c59dc2e..7ec41c2ead 100644 --- a/MatrixSDK/MatrixSDKVersion.m +++ b/MatrixSDK/MatrixSDKVersion.m @@ -16,4 +16,4 @@ #import -NSString *const MatrixSDKVersion = @"0.20.3"; +NSString *const MatrixSDKVersion = @"0.20.4"; diff --git a/changelog.d/4919.bugfix b/changelog.d/4919.bugfix deleted file mode 100644 index 5cea7d0da6..0000000000 --- a/changelog.d/4919.bugfix +++ /dev/null @@ -1 +0,0 @@ -MXSpaceService: Fix a crash due to recursion depth limit \ No newline at end of file From a22270b834085ac94d47427aa0a04641f4295e08 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 30 Sep 2021 22:39:20 +0100 Subject: [PATCH 3/3] finish version++