From 11cd5527edf5c79d9c2543776d27408ee3e8e8d6 Mon Sep 17 00:00:00 2001 From: jack Date: Thu, 28 Aug 2025 09:18:11 +0100 Subject: [PATCH] Fix crash in formatMessageAsText: use NSString length for NSRanges and guard slicing before matches to avoid invalid ranges with multi-byte content --- bitchat/ViewModels/ChatViewModel.swift | 34 +++++++++++++++----------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index f074ab64..03b18761 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -3161,9 +3161,12 @@ class ChatViewModel: ObservableObject, BitchatDelegate { // For extremely long content, render as plain text to avoid heavy regex/layout work, // unless the content includes Cashu tokens we want to chip-render below + // Compute NSString-backed length for regex/nsrange correctness with multi-byte characters + let nsContent = content as NSString + let nsLen = nsContent.length let containsCashuEarly: Bool = { let rx = Regexes.quickCashuPresence - return rx.numberOfMatches(in: content, options: [], range: NSRange(location: 0, length: content.count)) > 0 + return rx.numberOfMatches(in: content, options: [], range: NSRange(location: 0, length: nsLen)) > 0 }() if (content.count > 4000 || content.hasVeryLongToken(threshold: 1024)) && !containsCashuEarly { var plainStyle = AttributeContainer() @@ -3181,8 +3184,6 @@ class ChatViewModel: ObservableObject, BitchatDelegate { let lnurlRegex = Regexes.lnurl let lightningSchemeRegex = Regexes.lightningScheme let detector = Regexes.linkDetector - - let nsLen = content.count let hasMentionsHint = content.contains("@") let hasHashtagsHint = content.contains("#") let hasURLHint = content.contains("://") || content.contains("www.") || content.contains("http") @@ -3262,17 +3263,19 @@ class ChatViewModel: ObservableObject, BitchatDelegate { for (range, type) in allMatches { // Add text before match if let nsRange = Range(range, in: content) { - let beforeText = String(content[lastEnd..