mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Content scanner also checks for thumbnails (#5911)
* scan also thumbnails for medias * pr suggestion
This commit is contained in:
@@ -26,6 +26,10 @@ nonisolated struct ContentScannerProxy: ContentScannerProxyProtocol {
|
||||
do {
|
||||
let response = try await contentScanner.scan(client: client, mediaSource: mediaSource.underlyingSource)
|
||||
return .success(response.clean)
|
||||
} catch ClientError.ContentScanner(.mcsMimeTypeForbidden, _), ClientError.ContentScanner(.mcsMediaNotClean, _) {
|
||||
// The server flagged the media as unsafe (dangerous content or a forbidden mime type),
|
||||
// which we treat as an unsafe verdict rather than a scan failure.
|
||||
return .success(false)
|
||||
} catch {
|
||||
MXLog.error("Failed scanning media content: \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
|
||||
@@ -25,3 +25,47 @@ nonisolated protocol ContentScannerServiceProtocol: Sendable {
|
||||
@discardableResult
|
||||
func loadScanResultFromSource(_ source: MediaSourceProxy) async -> Result<Bool, ContentScannerServiceError>
|
||||
}
|
||||
|
||||
nonisolated extension ContentScannerServiceProtocol {
|
||||
/// The combined cached verdict for several sources (e.g. a media source and its thumbnail, both
|
||||
/// downloaded through the scanner): `false` if any is unsafe, `true` if all are safe, or `nil`
|
||||
/// when any of them hasn't been scanned yet.
|
||||
func scanResultFromSources(_ sources: [MediaSourceProxy]) -> Bool? {
|
||||
let results = sources.map { scanResultFromSource($0) }
|
||||
if results.contains(false) {
|
||||
return false
|
||||
}
|
||||
if results.contains(where: { $0 == nil }) {
|
||||
return nil
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/// Scans several sources concurrently, resolving as soon as one comes back non-safe (unsafe or
|
||||
/// failed) since a single failure is enough to flag the media - the remaining scans are then
|
||||
/// ignored. Resolves as safe only when every source is safe.
|
||||
@discardableResult
|
||||
func loadScanResultFromSources(_ sources: [MediaSourceProxy]) async -> Result<Bool, ContentScannerServiceError> {
|
||||
await withTaskGroup(of: Result<Bool, ContentScannerServiceError>.self) { group in
|
||||
for source in sources {
|
||||
group.addTask { await loadScanResultFromSource(source) }
|
||||
}
|
||||
|
||||
for await result in group where !result.isSafe {
|
||||
group.cancelAll()
|
||||
return result
|
||||
}
|
||||
|
||||
return .success(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private nonisolated extension Result where Success == Bool {
|
||||
var isSafe: Bool {
|
||||
if case .success(true) = self {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user