From 5318c1b84c5f1fc20f31f97714925ca330bd4064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 20 Apr 2026 05:45:36 +0800 Subject: [PATCH] Fix thread-safety crash in ProfileUpdateTask Snapshot @Published properties before async suspension points to prevent SIGBUS from corrupted pointers due to concurrent access. --- ApplicationLibrary/Service/ProfileUpdateTask.swift | 5 +++-- Library/Database/Profile+Update.swift | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ApplicationLibrary/Service/ProfileUpdateTask.swift b/ApplicationLibrary/Service/ProfileUpdateTask.swift index 1b649b1..7bd47fb 100644 --- a/ApplicationLibrary/Service/ProfileUpdateTask.swift +++ b/ApplicationLibrary/Service/ProfileUpdateTask.swift @@ -52,14 +52,15 @@ public enum ProfileUpdateTask { static func updateProfiles(_ profiles: [Profile]) async -> Bool { var success = true for profile in profiles { + let profileName = profile.name if profile.lastUpdated! > Date(timeIntervalSinceNow: -profile.autoUpdateIntervalOrDefault) { continue } do { try await profile.updateRemoteProfile() - NSLog("Updated profile \(profile.name)") + NSLog("Updated profile %@", profileName) } catch { - NSLog("Update profile \(profile.name) failed: \(error.localizedDescription)") + NSLog("Update profile %@ failed: %@", profileName, error.localizedDescription) success = false } } diff --git a/Library/Database/Profile+Update.swift b/Library/Database/Profile+Update.swift index b2b91f3..f130666 100644 --- a/Library/Database/Profile+Update.swift +++ b/Library/Database/Profile+Update.swift @@ -7,7 +7,8 @@ public extension Profile { if type != .remote { return } - let remoteContent = try await HTTPClient.getStringAsync(remoteURL) + let url = remoteURL + let remoteContent = try await HTTPClient.getStringAsync(url) try await BlockingIO.run { var error: NSError? LibboxCheckConfig(remoteContent, &error) @@ -15,7 +16,9 @@ public extension Profile { throw error } } - lastUpdated = Date() + await MainActor.run { + lastUpdated = Date() + } try await ProfileManager.update(self) do { let oldContent = try await readAsync()