From 6480023c96577d56f0b416a6bc8b4ca2b8173d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=E2=80=99Aquino?= Date: Mon, 5 Aug 2024 12:48:18 -0700 Subject: [PATCH] Fix crash with blurhashes with reported dimension of 0x0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes a consistent crash noticed when visiting a particular profile. The crash was occuring when trying to display the blurhash of a specific Event, where the metadata claimed the image dimensions were 0px x 0px. The null dimensions caused a division by zero to occur when scaling the image down, yielding a NaN (Not a Number) size value, which crashed the app when trying to cast that CGFloat value down to an integer. The crash was fixed by modifying the down-scaling computations to check for invalid dimensions, and return nil. The callers were then updated to fallback to a default display dimension. Issue repro ------- Device: iPhone 15 simulator iOS: 17.5 Damus: dba1799df097014298c52aa16238b4f33ec09ed2 Steps: 1. Visit the profile npub1gujeqakgt7fyp6zjggxhyy7ft623qtcaay5lkc8n8gkry4cvnrzqd3f67z 2. Check accessing the profile does not crash Damus. 3. Visit the event that had invalid 0x0 dimensions on the metadata (note1qmqdualjezamcjun23l4d9xw7529m7fee6hklgtnhack2fwznxysuzuuyz) 4. Check that Damus does not crash. Results: Steps 2 and 4 crash 100% of the time (3/3) Testing -------- PASS Device: iPhone 15 simulator iOS: 17.5 Damus: This commit Steps: Same as repro Results: 1. Crash no longer occurs 2. Blurhash looks ok Closes: https://github.com/damus-io/damus/issues/2341 Changelog-Fixed: Fix crash when viewing notes with invalid image dimension metadata Signed-off-by: Daniel D’Aquino --- damus/Util/Images/ImageMetadata.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/damus/Util/Images/ImageMetadata.swift b/damus/Util/Images/ImageMetadata.swift index cf02294e7..a3cce5ddc 100644 --- a/damus/Util/Images/ImageMetadata.swift +++ b/damus/Util/Images/ImageMetadata.swift @@ -60,7 +60,8 @@ struct ImageMetadata: Equatable { func process_blurhash(blurhash: String, size: CGSize?) async -> UIImage? { let res = Task.detached(priority: .low) { - let size = get_blurhash_size(img_size: size ?? CGSize(width: 100.0, height: 100.0)) + let default_size = CGSize(width: 100.0, height: 100.0) + let size = get_blurhash_size(img_size: size ?? default_size) ?? default_size guard let img = UIImage.init(blurHash: blurhash, size: size) else { let noimg: UIImage? = nil return noimg @@ -135,7 +136,8 @@ extension UIImage { } } -func get_blurhash_size(img_size: CGSize) -> CGSize { +func get_blurhash_size(img_size: CGSize) -> CGSize? { + guard img_size.width > 0 && img_size.height > 0 else { return nil } return CGSize(width: 100.0, height: (100.0/img_size.width) * img_size.height) } @@ -145,7 +147,7 @@ func calculate_blurhash(img: UIImage) async -> String? { } let res = Task.detached(priority: .low) { - let bhs = get_blurhash_size(img_size: img.size) + let bhs = get_blurhash_size(img_size: img.size) ?? CGSize(width: 100.0, height: 100.0) let smaller = img.resized(to: bhs) guard let blurhash = smaller.blurHash(numberOfComponents: (5,5)) else {