From b31a63ce37397f985287f8d33d9c12fc051b2e94 Mon Sep 17 00:00:00 2001 From: jack <212554440+jackjackbits@users.noreply.github.com> Date: Sun, 5 Jul 2026 14:09:13 +0200 Subject: [PATCH] Burn down SwiftLint advisory violations from 109 to 4 (#1362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mechanical style fixes across the enabled rule set, mostly via swiftlint --fix (trailing_comma, comma, colon, trailing_newline, comment_spacing, unused_closure_parameter, unneeded_break_in_switch, opening_brace) plus hand fixes: - non_optional_string_data_conversion (45): .data(using: .utf8)! and ?? Data() fallbacks replaced with the non-optional Data(_.utf8), including two production sites (NIP-44 HKDF info constant and the announce canonicalization context/nickname bytes — byte-identical output, only the impossible-nil handling is gone). - switch_case_alignment: LocationChannel had a misindented closing brace; also repaired an --fix artifact in BLEService's .none case. - redundant_string_enum_value: TrustLevel raw values equal to the case names (encoded form unchanged). - unused_optional_binding: let _ = binds replaced with != nil / is Bool. - static_over_final_class: PreviewView.layerClass. - Resolved the BinaryProtocolTests TODO by documenting that 8-byte recipient ID truncation is the fixed wire-field size, not a bug. The 4 remaining violations are all todo markers for a shared test-helpers module (tracked in #1088) and one Reuse note. Co-authored-by: jack Co-authored-by: Claude Fable 5 --- Package.swift | 4 +- bitchat/BitchatApp.swift | 2 +- bitchat/Identity/IdentityModels.swift | 8 +-- bitchat/Nostr/NostrProtocol.swift | 2 +- bitchat/Nostr/XChaCha20Poly1305Compat.swift | 1 - bitchat/Protocols/LocationChannel.swift | 2 +- bitchat/Services/BLE/BLEService.swift | 7 +-- bitchat/Services/MessageRouter.swift | 2 +- bitchat/Services/NoiseEncryptionService.swift | 4 +- bitchat/Services/NostrTransport.swift | 2 +- bitchat/Services/NotificationService.swift | 2 +- bitchat/Utils/PeerDisplayNameResolver.swift | 1 - bitchat/ViewModels/ChatNostrCoordinator.swift | 4 +- bitchat/Views/MessageListView.swift | 4 +- bitchat/Views/VerificationViews.swift | 2 +- .../ShareViewController.swift | 2 +- .../ChatComposerCoordinatorContextTests.swift | 4 +- ...ChatLifecycleCoordinatorContextTests.swift | 8 +-- .../ChatPeerListCoordinatorContextTests.swift | 6 +- ...eConversationCoordinatorContextTests.swift | 2 +- ...ransportEventCoordinatorContextTests.swift | 4 +- .../Integration/IntegrationTests.swift | 6 +- .../Integration/TestNetworkHelper.swift | 1 - bitchatTests/MimeTypeTests.swift | 12 ++-- bitchatTests/Noise/NoiseCoverageTests.swift | 2 +- bitchatTests/Noise/NoiseProtocolTests.swift | 55 +++++++++---------- .../PerformanceBaselineTests.swift | 4 +- bitchatTests/TestUtilities/TestHelpers.swift | 4 +- .../XChaCha20Poly1305CompatTests.swift | 24 ++++---- localPackages/Arti/Package.swift | 14 ++--- localPackages/BitFoundation/Package.swift | 2 +- .../BinaryProtocolTests.swift | 9 +-- .../BitFoundationTests/TestHelpers.swift | 4 +- 33 files changed, 103 insertions(+), 107 deletions(-) diff --git a/Package.swift b/Package.swift index 3f6e6b8f..7d447630 100644 --- a/Package.swift +++ b/Package.swift @@ -13,9 +13,9 @@ let package = Package( .executable( name: "bitchat", targets: ["bitchat"] - ), + ) ], - dependencies:[ + dependencies: [ .package(path: "localPackages/Arti"), .package(path: "localPackages/BitFoundation"), .package(path: "localPackages/BitLogger"), diff --git a/bitchat/BitchatApp.swift b/bitchat/BitchatApp.swift index 4f2e4199..e606506f 100644 --- a/bitchat/BitchatApp.swift +++ b/bitchat/BitchatApp.swift @@ -71,7 +71,7 @@ struct BitchatApp: App { final class AppDelegate: NSObject, UIApplicationDelegate { weak var runtime: AppRuntime? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { true } diff --git a/bitchat/Identity/IdentityModels.swift b/bitchat/Identity/IdentityModels.swift index 29f036c6..ad83962f 100644 --- a/bitchat/Identity/IdentityModels.swift +++ b/bitchat/Identity/IdentityModels.swift @@ -127,10 +127,10 @@ struct SocialIdentity: Codable { } enum TrustLevel: String, Codable { - case unknown = "unknown" - case casual = "casual" - case trusted = "trusted" - case verified = "verified" + case unknown + case casual + case trusted + case verified } // MARK: - Identity Cache diff --git a/bitchat/Nostr/NostrProtocol.swift b/bitchat/Nostr/NostrProtocol.swift index f68caa8d..d59a5200 100644 --- a/bitchat/Nostr/NostrProtocol.swift +++ b/bitchat/Nostr/NostrProtocol.swift @@ -648,7 +648,7 @@ private extension NostrProtocol { let derivedKey = HKDF.deriveKey( inputKeyMaterial: SymmetricKey(data: sharedSecretData), salt: Data(), - info: "nip44-v2".data(using: .utf8)!, + info: Data("nip44-v2".utf8), outputByteCount: 32 ) return derivedKey.withUnsafeBytes { Data($0) } diff --git a/bitchat/Nostr/XChaCha20Poly1305Compat.swift b/bitchat/Nostr/XChaCha20Poly1305Compat.swift index 13794508..006cf899 100644 --- a/bitchat/Nostr/XChaCha20Poly1305Compat.swift +++ b/bitchat/Nostr/XChaCha20Poly1305Compat.swift @@ -132,4 +132,3 @@ private extension Data { replaceSubrange(offset..<(offset+4), with: bytes) } } - diff --git a/bitchat/Protocols/LocationChannel.swift b/bitchat/Protocols/LocationChannel.swift index b7c0d5b6..cbe1c55f 100644 --- a/bitchat/Protocols/LocationChannel.swift +++ b/bitchat/Protocols/LocationChannel.swift @@ -18,7 +18,7 @@ enum GeohashChannelLevel: CaseIterable, Codable, Equatable { case .city: return 5 case .province: return 4 case .region: return 2 - } + } } var displayName: String { diff --git a/bitchat/Services/BLE/BLEService.swift b/bitchat/Services/BLE/BLEService.swift index 2ee9cd13..a0f77ded 100644 --- a/bitchat/Services/BLE/BLEService.swift +++ b/bitchat/Services/BLE/BLEService.swift @@ -1305,7 +1305,7 @@ extension BLEService: GossipSyncManager.Delegate { extension BLEService: CBCentralManagerDelegate { #if os(iOS) - func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) { + func centralManager(_ central: CBCentralManager, willRestoreState dict: [String: Any]) { let restoredPeripherals = (dict[CBCentralManagerRestoredStatePeripheralsKey] as? [CBPeripheral]) ?? [] let restoredServices = (dict[CBCentralManagerRestoredStateScanServicesKey] as? [CBUUID]) ?? [] let restoredOptions = (dict[CBCentralManagerRestoredStateScanOptionsKey] as? [String: Any]) ?? [:] @@ -1987,7 +1987,7 @@ extension BLEService: CBPeripheralManagerDelegate { } #if os(iOS) - func peripheralManager(_ peripheral: CBPeripheralManager, willRestoreState dict: [String : Any]) { + func peripheralManager(_ peripheral: CBPeripheralManager, willRestoreState dict: [String: Any]) { let restoredServices = (dict[CBPeripheralManagerRestoredStateServicesKey] as? [CBMutableService]) ?? [] let restoredAdvertisement = (dict[CBPeripheralManagerRestoredStateAdvertisementDataKey] as? [String: Any]) ?? [:] @@ -2956,10 +2956,9 @@ extension BLEService { case .leave: handleLeave(packet, from: senderID) - + case .none: SecureLogger.warning("⚠️ Unknown message type: \(packet.type)", category: .session) - break } if forwardAlongRouteIfNeeded(packet) { diff --git a/bitchat/Services/MessageRouter.swift b/bitchat/Services/MessageRouter.swift index af0b3291..ace112bc 100644 --- a/bitchat/Services/MessageRouter.swift +++ b/bitchat/Services/MessageRouter.swift @@ -51,7 +51,7 @@ final class MessageRouter { } // Handle key updates if let newKey = note.userInfo?["peerPublicKey"] as? Data, - let _ = note.userInfo?["isKeyUpdate"] as? Bool { + note.userInfo?["isKeyUpdate"] is Bool { let peerID = PeerID(publicKey: newKey) Task { @MainActor in self.flushOutbox(for: peerID) diff --git a/bitchat/Services/NoiseEncryptionService.swift b/bitchat/Services/NoiseEncryptionService.swift index 70e43c0d..a19e3da2 100644 --- a/bitchat/Services/NoiseEncryptionService.swift +++ b/bitchat/Services/NoiseEncryptionService.swift @@ -428,7 +428,7 @@ final class NoiseEncryptionService { private func canonicalAnnounceBytes(peerID: Data, noiseKey: Data, ed25519Key: Data, nickname: String, timestampMs: UInt64) -> Data { var out = Data() // context - let context = "bitchat-announce-v1".data(using: .utf8) ?? Data() + let context = Data("bitchat-announce-v1".utf8) out.append(UInt8(min(context.count, 255))) out.append(context.prefix(255)) // peerID (expect 8 bytes; pad/truncate to 8 for canonicalization) @@ -444,7 +444,7 @@ final class NoiseEncryptionService { out.append(ed32) if ed32.count < 32 { out.append(Data(repeating: 0, count: 32 - ed32.count)) } // nickname length + bytes - let nickData = nickname.data(using: .utf8) ?? Data() + let nickData = Data(nickname.utf8) out.append(UInt8(min(nickData.count, 255))) out.append(nickData.prefix(255)) // timestamp diff --git a/bitchat/Services/NostrTransport.swift b/bitchat/Services/NostrTransport.swift index 380593fb..35c96547 100644 --- a/bitchat/Services/NostrTransport.swift +++ b/bitchat/Services/NostrTransport.swift @@ -137,7 +137,7 @@ final class NostrTransport: Transport, @unchecked Sendable { } func peerNickname(peerID: PeerID) -> String? { nil } - func getPeerNicknames() -> [PeerID : String] { [:] } + func getPeerNicknames() -> [PeerID: String] { [:] } func getFingerprint(for peerID: PeerID) -> String? { nil } func getNoiseSessionState(for peerID: PeerID) -> LazyHandshakeState { .none } diff --git a/bitchat/Services/NotificationService.swift b/bitchat/Services/NotificationService.swift index d51efa86..091f4289 100644 --- a/bitchat/Services/NotificationService.swift +++ b/bitchat/Services/NotificationService.swift @@ -111,7 +111,7 @@ final class NotificationService { func requestAuthorization() { guard !isRunningTests else { return } - authorizer.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in + authorizer.requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in if granted { // Permission granted } else { diff --git a/bitchat/Utils/PeerDisplayNameResolver.swift b/bitchat/Utils/PeerDisplayNameResolver.swift index 77a89ec5..a92953d3 100644 --- a/bitchat/Utils/PeerDisplayNameResolver.swift +++ b/bitchat/Utils/PeerDisplayNameResolver.swift @@ -27,4 +27,3 @@ struct PeerDisplayNameResolver { return result } } - diff --git a/bitchat/ViewModels/ChatNostrCoordinator.swift b/bitchat/ViewModels/ChatNostrCoordinator.swift index 0b52baa6..37ac4a50 100644 --- a/bitchat/ViewModels/ChatNostrCoordinator.swift +++ b/bitchat/ViewModels/ChatNostrCoordinator.swift @@ -71,7 +71,7 @@ final class ChatNostrCoordinator { key: Data? ) { guard let context else { return } - if let _ = key { + if key != nil { if let identity = context.currentNostrIdentity() { context.sendGeohashDeliveryAck(for: message.id, toRecipientHex: senderPubkey, from: identity) } @@ -84,7 +84,7 @@ final class ChatNostrCoordinator { } if !wasReadBefore && context.selectedPrivateChatPeer == message.senderPeerID { - if let _ = key { + if key != nil { if let identity = context.currentNostrIdentity() { context.sendGeohashReadReceipt(message.id, toRecipientHex: senderPubkey, from: identity) } diff --git a/bitchat/Views/MessageListView.swift b/bitchat/Views/MessageListView.swift index c8837983..da7fa116 100644 --- a/bitchat/Views/MessageListView.swift +++ b/bitchat/Views/MessageListView.swift @@ -426,6 +426,6 @@ private extension ChannelID { } } -//#Preview { +// #Preview { // MessageListView() -//} +// } diff --git a/bitchat/Views/VerificationViews.swift b/bitchat/Views/VerificationViews.swift index 78e0ff93..61697ad6 100644 --- a/bitchat/Views/VerificationViews.swift +++ b/bitchat/Views/VerificationViews.swift @@ -265,7 +265,7 @@ struct CameraScannerView: UIViewRepresentable { } final class PreviewView: UIView { - override class var layerClass: AnyClass { AVCaptureVideoPreviewLayer.self } + override static var layerClass: AnyClass { AVCaptureVideoPreviewLayer.self } var videoPreviewLayer: AVCaptureVideoPreviewLayer { layer as! AVCaptureVideoPreviewLayer } override init(frame: CGRect) { super.init(frame: frame) diff --git a/bitchatShareExtension/ShareViewController.swift b/bitchatShareExtension/ShareViewController.swift index a777720a..bd83b678 100644 --- a/bitchatShareExtension/ShareViewController.swift +++ b/bitchatShareExtension/ShareViewController.swift @@ -84,7 +84,7 @@ final class ShareViewController: UIViewController { self.loadFirstPlainText(from: providers) { text in if let t = text, !t.isEmpty { // Treat as URL if parseable http(s), else plain text - if let u = URL(string: t), ["http","https"].contains(u.scheme?.lowercased() ?? "") { + if let u = URL(string: t), ["http", "https"].contains(u.scheme?.lowercased() ?? "") { self.saveAndFinish(url: u, title: item.attributedTitle?.string) } else { self.saveAndFinish(text: t) diff --git a/bitchatTests/ChatComposerCoordinatorContextTests.swift b/bitchatTests/ChatComposerCoordinatorContextTests.swift index 49891a1e..24624897 100644 --- a/bitchatTests/ChatComposerCoordinatorContextTests.swift +++ b/bitchatTests/ChatComposerCoordinatorContextTests.swift @@ -82,7 +82,7 @@ struct ChatComposerCoordinatorContextTests { context.meshNicknamesByPeerID = [ PeerID(str: "1111111111111111"): "alice", PeerID(str: "2222222222222222"): "bob", - PeerID(str: "3333333333333333"): "me", + PeerID(str: "3333333333333333"): "me" ] // Matching query: suggestions and range are published, index resets. @@ -113,7 +113,7 @@ struct ChatComposerCoordinatorContextTests { "aaaabbbbccccdddd": "carol", // Own token (nickname#last-4-of-pubkey) must be removed; the dummy // identity's public key hex ends in "2222". - "ffffeeeeddddcccc2222": "me", + "ffffeeeeddddcccc2222": "me" ] coordinator.updateAutocomplete(for: "@ca", cursorPosition: 3) diff --git a/bitchatTests/ChatLifecycleCoordinatorContextTests.swift b/bitchatTests/ChatLifecycleCoordinatorContextTests.swift index be13d01e..88596f16 100644 --- a/bitchatTests/ChatLifecycleCoordinatorContextTests.swift +++ b/bitchatTests/ChatLifecycleCoordinatorContextTests.swift @@ -214,10 +214,10 @@ struct ChatLifecycleCoordinatorContextTests { // Same message under both keys: the read copy must win over sent. context.privateChats[peerID] = [ makePrivateMessage(id: "m1", timestamp: t1, deliveryStatus: .sent), - makePrivateMessage(id: "m2", timestamp: t2), + makePrivateMessage(id: "m2", timestamp: t2) ] context.privateChats[stablePeerID] = [ - makePrivateMessage(id: "m1", timestamp: t1, deliveryStatus: .read(by: "alice", at: t2)), + makePrivateMessage(id: "m1", timestamp: t1, deliveryStatus: .read(by: "alice", at: t2)) ] let merged = coordinator.getPrivateChatMessages(for: peerID) @@ -245,7 +245,7 @@ struct ChatLifecycleCoordinatorContextTests { makePrivateMessage(id: "m1", senderPeerID: convKey), makePrivateMessage(id: "already-acked", senderPeerID: convKey), makePrivateMessage(id: "relay", senderPeerID: convKey, isRelay: true), - makePrivateMessage(id: "mine", sender: "me", senderPeerID: context.myPeerID), + makePrivateMessage(id: "mine", sender: "me", senderPeerID: context.myPeerID) ] coordinator.markPrivateMessagesAsRead(from: convKey) @@ -339,7 +339,7 @@ struct ChatLifecycleCoordinatorContextTests { ) context.privateChats[peerID] = [ makePrivateMessage(id: "in-1", senderPeerID: peerID), - makePrivateMessage(id: "in-relay", senderPeerID: peerID, isRelay: true), + makePrivateMessage(id: "in-relay", senderPeerID: peerID, isRelay: true) ] coordinator.markPrivateMessagesAsRead(from: peerID) diff --git a/bitchatTests/ChatPeerListCoordinatorContextTests.swift b/bitchatTests/ChatPeerListCoordinatorContextTests.swift index 62d1c538..e9c7549c 100644 --- a/bitchatTests/ChatPeerListCoordinatorContextTests.swift +++ b/bitchatTests/ChatPeerListCoordinatorContextTests.swift @@ -154,18 +154,18 @@ struct ChatPeerListCoordinatorContextTests { peerID: currentPeer, noisePublicKey: Data(repeating: 0x01, count: 32), nickname: "alice" - ), + ) ] context.unreadPrivateMessages = [ currentPeer, staleShortPeer, geoDMWithMessages, geoDMWithoutMessages, - noiseKeyWithMessages, + noiseKeyWithMessages ] context.privateChats = [ geoDMWithMessages: [makeMessage(id: "geo-1")], - noiseKeyWithMessages: [makeMessage(id: "noise-1")], + noiseKeyWithMessages: [makeMessage(id: "noise-1")] ] coordinator.didUpdatePeerList([currentPeer]) diff --git a/bitchatTests/ChatPrivateConversationCoordinatorContextTests.swift b/bitchatTests/ChatPrivateConversationCoordinatorContextTests.swift index 2a19afe9..60f913fa 100644 --- a/bitchatTests/ChatPrivateConversationCoordinatorContextTests.swift +++ b/bitchatTests/ChatPrivateConversationCoordinatorContextTests.swift @@ -352,7 +352,7 @@ struct ChatPrivateConversationCoordinatorContextTests { context.displayNamesByPubkey[senderPubkey] = "alice#1234" context.privateChats[convKey] = [ makeIncomingMessage(id: "mine-1", sender: "me"), - makeIncomingMessage(id: "mine-2", sender: "me"), + makeIncomingMessage(id: "mine-2", sender: "me") ] coordinator.handleDelivered( diff --git a/bitchatTests/ChatTransportEventCoordinatorContextTests.swift b/bitchatTests/ChatTransportEventCoordinatorContextTests.swift index d7e6c863..8ffd2933 100644 --- a/bitchatTests/ChatTransportEventCoordinatorContextTests.swift +++ b/bitchatTests/ChatTransportEventCoordinatorContextTests.swift @@ -259,7 +259,7 @@ struct ChatTransportEventCoordinatorContextTests { context.privateChats[peerID] = [ makeMessage(id: "theirs-1", isPrivate: true, senderPeerID: peerID), makeMessage(id: "mine-1", sender: "me", isPrivate: true, senderPeerID: context.myPeerID), - makeMessage(id: "theirs-2", isPrivate: true, senderPeerID: peerID), + makeMessage(id: "theirs-2", isPrivate: true, senderPeerID: peerID) ] coordinator.didDisconnectFromPeer(peerID) await drainMainActorTasks() @@ -282,7 +282,7 @@ struct ChatTransportEventCoordinatorContextTests { context.unreadPrivateMessages = [peerID] context.privateChats[peerID] = [ makeMessage(id: "m1", isPrivate: true, senderPeerID: peerID), - makeMessage(id: "mine", sender: "me", isPrivate: true, senderPeerID: context.myPeerID), + makeMessage(id: "mine", sender: "me", isPrivate: true, senderPeerID: context.myPeerID) ] coordinator.didDisconnectFromPeer(peerID) diff --git a/bitchatTests/Integration/IntegrationTests.swift b/bitchatTests/Integration/IntegrationTests.swift index 52b4d2de..11ba1602 100644 --- a/bitchatTests/Integration/IntegrationTests.swift +++ b/bitchatTests/Integration/IntegrationTests.swift @@ -174,7 +174,7 @@ struct IntegrationTests { } // Encrypted path: use NoiseSessionManager explicitly - let plaintext = "Encrypted message".data(using: .utf8)! + let plaintext = Data("Encrypted message".utf8) let ciphertext = try helper.noiseManagers["Alice"]!.encrypt(plaintext, for: helper.nodes["Bob"]!.peerID) helper.nodes["Bob"]!.packetDeliveryHandler = { packet in @@ -206,7 +206,7 @@ struct IntegrationTests { try await confirmation("Messages delivered despite churn", expectedCount: totalMessages) { completion in // David tracks received messages - helper.nodes["David"]!.messageDeliveryHandler = { message in + helper.nodes["David"]!.messageDeliveryHandler = { _ in completion() } @@ -288,7 +288,7 @@ struct IntegrationTests { } do { - let plaintext = "After restart success".data(using: .utf8)! + let plaintext = Data("After restart success".utf8) let ciphertext = try helper.noiseManagers["Bob"]!.encrypt(plaintext, for: helper.nodes["Alice"]!.peerID) let packet = TestHelpers.createTestPacket(type: MessageType.noiseEncrypted.rawValue, payload: ciphertext) helper.nodes["Alice"]!.packetDeliveryHandler = { pkt in diff --git a/bitchatTests/Integration/TestNetworkHelper.swift b/bitchatTests/Integration/TestNetworkHelper.swift index 277e1f52..d7b7b7ef 100644 --- a/bitchatTests/Integration/TestNetworkHelper.swift +++ b/bitchatTests/Integration/TestNetworkHelper.swift @@ -121,4 +121,3 @@ final class TestNetworkHelper { _ = try manager2.handleIncomingHandshake(from: peer1ID, message: msg3) } } - diff --git a/bitchatTests/MimeTypeTests.swift b/bitchatTests/MimeTypeTests.swift index a6b20b10..b30436f3 100644 --- a/bitchatTests/MimeTypeTests.swift +++ b/bitchatTests/MimeTypeTests.swift @@ -52,19 +52,19 @@ struct MimeTypeTests { @Test(arguments: [ // === Image types === (MimeType.jpeg, [0xFF, 0xD8, 0xFF]), - (MimeType.png, [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]), - (MimeType.gif, [0x47, 0x49, 0x46, 0x38, 0x39, 0x61]), // "GIF89a" + (MimeType.png, [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]), + (MimeType.gif, [0x47, 0x49, 0x46, 0x38, 0x39, 0x61]), // "GIF89a" (MimeType.webp, [0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50]), // "RIFF....WEBP" // === Audio types === - (MimeType.mp3, [0x49, 0x44, 0x33]), // "ID3" - (MimeType.wav, [0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, + (MimeType.mp3, [0x49, 0x44, 0x33]), // "ID3" + (MimeType.wav, [0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45]), // "RIFF....WAVE" - (MimeType.ogg, [0x4F, 0x67, 0x67, 0x53]), // "OggS" + (MimeType.ogg, [0x4F, 0x67, 0x67, 0x53]), // "OggS" // === Application types === - (MimeType.pdf, [0x25, 0x50, 0x44, 0x46]) // "%PDF" + (MimeType.pdf, [0x25, 0x50, 0x44, 0x46]) // "%PDF" ]) func validSignatures(mime: MimeType, bytes: [UInt8]) throws { let data = Data(bytes) diff --git a/bitchatTests/Noise/NoiseCoverageTests.swift b/bitchatTests/Noise/NoiseCoverageTests.swift index 5a178f73..ab3b8641 100644 --- a/bitchatTests/Noise/NoiseCoverageTests.swift +++ b/bitchatTests/Noise/NoiseCoverageTests.swift @@ -172,7 +172,7 @@ struct NoiseCoverageTests { Data(), Data(repeating: 0x00, count: 32), Data([0x01] + Array(repeating: 0x00, count: 31)), - Data(repeating: 0xFF, count: 32), + Data(repeating: 0xFF, count: 32) ] for invalidKey in invalidKeys { diff --git a/bitchatTests/Noise/NoiseProtocolTests.swift b/bitchatTests/Noise/NoiseProtocolTests.swift index 9c5f2dc1..5d1a3129 100644 --- a/bitchatTests/Noise/NoiseProtocolTests.swift +++ b/bitchatTests/Noise/NoiseProtocolTests.swift @@ -151,7 +151,7 @@ struct NoiseProtocolTests { @Test func basicEncryptionDecryption() throws { try performHandshake(initiator: aliceSession, responder: bobSession) - let plaintext = "Hello, Bob!".data(using: .utf8)! + let plaintext = Data("Hello, Bob!".utf8) // Alice encrypts let ciphertext = try aliceSession.encrypt(plaintext) @@ -167,13 +167,13 @@ struct NoiseProtocolTests { try performHandshake(initiator: aliceSession, responder: bobSession) // Alice -> Bob - let aliceMessage = "Hello from Alice".data(using: .utf8)! + let aliceMessage = Data("Hello from Alice".utf8) let aliceCiphertext = try aliceSession.encrypt(aliceMessage) let bobReceived = try bobSession.decrypt(aliceCiphertext) #expect(bobReceived == aliceMessage) // Bob -> Alice - let bobMessage = "Hello from Bob".data(using: .utf8)! + let bobMessage = Data("Hello from Bob".utf8) let bobCiphertext = try bobSession.encrypt(bobMessage) let aliceReceived = try aliceSession.decrypt(bobCiphertext) #expect(aliceReceived == bobMessage) @@ -193,7 +193,7 @@ struct NoiseProtocolTests { } @Test func encryptionBeforeHandshake() { - let plaintext = "test".data(using: .utf8)! + let plaintext = Data("test".utf8) #expect(throws: NoiseSessionError.notEstablished) { try aliceSession.encrypt(plaintext) @@ -270,7 +270,7 @@ struct NoiseProtocolTests { try establishManagerSessions(aliceManager: aliceManager, bobManager: bobManager) // Encrypt with manager - let plaintext = "Test message".data(using: .utf8)! + let plaintext = Data("Test message".utf8) let ciphertext = try aliceManager.encrypt(plaintext, for: alicePeerID) // Decrypt with manager @@ -283,7 +283,7 @@ struct NoiseProtocolTests { @Test func tamperedCiphertextDetection() throws { try performHandshake(initiator: aliceSession, responder: bobSession) - let plaintext = "Secret message".data(using: .utf8)! + let plaintext = Data("Secret message".utf8) var ciphertext = try aliceSession.encrypt(plaintext) // Tamper with ciphertext @@ -304,7 +304,7 @@ struct NoiseProtocolTests { @Test func replayPrevention() throws { try performHandshake(initiator: aliceSession, responder: bobSession) - let plaintext = "Test message".data(using: .utf8)! + let plaintext = Data("Test message".utf8) let ciphertext = try aliceSession.encrypt(plaintext) // First decryption should succeed @@ -337,7 +337,7 @@ struct NoiseProtocolTests { try performHandshake(initiator: aliceSession2, responder: bobSession2) // Encrypt with session 1 - let plaintext = "Secret".data(using: .utf8)! + let plaintext = Data("Secret".utf8) let ciphertext1 = try aliceSession1.encrypt(plaintext) // Should not be able to decrypt with session 2 @@ -366,10 +366,10 @@ struct NoiseProtocolTests { try establishManagerSessions(aliceManager: aliceManager, bobManager: bobManager) // Exchange some messages to establish nonce state - let message1 = try aliceManager.encrypt("Hello".data(using: .utf8)!, for: alicePeerID) + let message1 = try aliceManager.encrypt(Data("Hello".utf8), for: alicePeerID) _ = try bobManager.decrypt(message1, from: bobPeerID) - let message2 = try bobManager.encrypt("World".data(using: .utf8)!, for: bobPeerID) + let message2 = try bobManager.encrypt(Data("World".utf8), for: bobPeerID) _ = try aliceManager.decrypt(message2, from: alicePeerID) // Simulate Bob restart by creating new manager with same key @@ -391,7 +391,7 @@ struct NoiseProtocolTests { _ = try aliceManager.handleIncomingHandshake(from: alicePeerID, message: newHandshake3!) // Should be able to exchange messages with new sessions - let testMessage = "After restart".data(using: .utf8)! + let testMessage = Data("After restart".utf8) let encrypted = try bobManagerRestarted.encrypt(testMessage, for: bobPeerID) let decrypted = try aliceManager.decrypt(encrypted, from: alicePeerID) #expect(decrypted == testMessage) @@ -409,17 +409,17 @@ struct NoiseProtocolTests { // Exchange messages to advance nonces for i in 0..<5 { - let msg = try aliceSession.encrypt("Message \(i)".data(using: .utf8)!) + let msg = try aliceSession.encrypt(Data("Message \(i)".utf8)) _ = try bobSession.decrypt(msg) } // Simulate desynchronization by encrypting but not decrypting for i in 0..<3 { - _ = try aliceSession.encrypt("Lost message \(i)".data(using: .utf8)!) + _ = try aliceSession.encrypt(Data("Lost message \(i)".utf8)) } // With per-packet nonce carried, decryption should not throw here - let desyncMessage = try aliceSession.encrypt("This now succeeds".data(using: .utf8)!) + let desyncMessage = try aliceSession.encrypt(Data("This now succeeds".utf8)) #expect(throws: Never.self) { try bobSession.decrypt(desyncMessage) } @@ -434,12 +434,11 @@ struct NoiseProtocolTests { let messageCount = 100 - try await confirmation("All messages encrypted and decrypted", expectedCount: messageCount) - { completion in + try await confirmation("All messages encrypted and decrypted", expectedCount: messageCount) { completion in var encryptedMessages: [Int: Data] = [:] // Encrypt messages sequentially to avoid nonce races in manager for i in 0.. 0) // Test encryption from Alice to Bob - let plaintext1 = "Hello from Alice after secureClear!".data(using: .utf8)! + let plaintext1 = Data("Hello from Alice after secureClear!".utf8) let ciphertext1 = try alice.encrypt(plaintext1) let decrypted1 = try bob.decrypt(ciphertext1) #expect(decrypted1 == plaintext1) // Test encryption from Bob to Alice - let plaintext2 = "Hello from Bob after secureClear!".data(using: .utf8)! + let plaintext2 = Data("Hello from Bob after secureClear!".utf8) let ciphertext2 = try bob.encrypt(plaintext2) let decrypted2 = try alice.decrypt(ciphertext2) #expect(decrypted2 == plaintext2) // Test multiple messages to verify cipher state is correct for i in 1...10 { - let msg = "Message \(i) from Alice".data(using: .utf8)! + let msg = Data("Message \(i) from Alice".utf8) let cipher = try alice.encrypt(msg) let dec = try bob.decrypt(cipher) #expect(dec == msg) diff --git a/bitchatTests/Performance/PerformanceBaselineTests.swift b/bitchatTests/Performance/PerformanceBaselineTests.swift index 57714e45..39ed95bf 100644 --- a/bitchatTests/Performance/PerformanceBaselineTests.swift +++ b/bitchatTests/Performance/PerformanceBaselineTests.swift @@ -301,7 +301,7 @@ final class PerformanceBaselineTests: XCTestCase { ("@carol#a1b2 did you see this? https://example.com/threads/42", ["carol"]), ("checking in from the harbor #bitchat #mesh", nil), ("@bob#0042 ping me when you get this", ["bob#0042"]), - ("long form update with a link https://news.example.org/articles/2026/06/mesh-networks and a tag #geohash", nil), + ("long form update with a link https://news.example.org/articles/2026/06/mesh-networks and a tag #geohash", nil) ] let batches: [[BitchatMessage]] = (0.. BitchatPacket { return BitchatPacket( type: type, - senderID: senderID.id.data(using: .utf8)!, + senderID: Data(senderID.id.utf8), recipientID: recipientID?.id.data(using: .utf8), timestamp: UInt64(Date().timeIntervalSince1970 * 1000), payload: payload, diff --git a/bitchatTests/XChaCha20Poly1305CompatTests.swift b/bitchatTests/XChaCha20Poly1305CompatTests.swift index 9b607a9b..a90e1de0 100644 --- a/bitchatTests/XChaCha20Poly1305CompatTests.swift +++ b/bitchatTests/XChaCha20Poly1305CompatTests.swift @@ -13,7 +13,7 @@ import struct Foundation.Data struct XChaCha20Poly1305CompatTests { @Test func sealAndOpenRoundtrip() throws { - let plaintext = "Hello, XChaCha20-Poly1305!".data(using: .utf8)! + let plaintext = Data("Hello, XChaCha20-Poly1305!".utf8) let key = Data(repeating: 0x42, count: 32) let nonce = Data(repeating: 0x24, count: 24) @@ -29,10 +29,10 @@ struct XChaCha20Poly1305CompatTests { } @Test func sealAndOpenWithAAD() throws { - let plaintext = "Secret message".data(using: .utf8)! + let plaintext = Data("Secret message".utf8) let key = Data(repeating: 0xAB, count: 32) let nonce = Data(repeating: 0xCD, count: 24) - let aad = "additional authenticated data".data(using: .utf8)! + let aad = Data("additional authenticated data".utf8) let sealed = try XChaCha20Poly1305Compat.seal(plaintext: plaintext, key: key, nonce24: nonce, aad: aad) let decrypted = try XChaCha20Poly1305Compat.open( @@ -47,7 +47,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func sealProducesDifferentCiphertextWithDifferentNonces() throws { - let plaintext = "Same plaintext".data(using: .utf8)! + let plaintext = Data("Same plaintext".utf8) let key = Data(repeating: 0x42, count: 32) let nonce1 = Data(repeating: 0x01, count: 24) let nonce2 = Data(repeating: 0x02, count: 24) @@ -59,7 +59,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func sealThrowsOnShortKey() { - let plaintext = "Test".data(using: .utf8)! + let plaintext = Data("Test".utf8) let shortKey = Data(repeating: 0x42, count: 16) let nonce = Data(repeating: 0x24, count: 24) @@ -73,7 +73,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func sealThrowsOnLongKey() { - let plaintext = "Test".data(using: .utf8)! + let plaintext = Data("Test".utf8) let longKey = Data(repeating: 0x42, count: 64) let nonce = Data(repeating: 0x24, count: 24) @@ -87,7 +87,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func sealThrowsOnEmptyKey() { - let plaintext = "Test".data(using: .utf8)! + let plaintext = Data("Test".utf8) let emptyKey = Data() let nonce = Data(repeating: 0x24, count: 24) @@ -116,7 +116,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func sealThrowsOnShortNonce() { - let plaintext = "Test".data(using: .utf8)! + let plaintext = Data("Test".utf8) let key = Data(repeating: 0x42, count: 32) let shortNonce = Data(repeating: 0x24, count: 12) @@ -130,7 +130,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func sealThrowsOnLongNonce() { - let plaintext = "Test".data(using: .utf8)! + let plaintext = Data("Test".utf8) let key = Data(repeating: 0x42, count: 32) let longNonce = Data(repeating: 0x24, count: 32) @@ -144,7 +144,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func sealThrowsOnEmptyNonce() { - let plaintext = "Test".data(using: .utf8)! + let plaintext = Data("Test".utf8) let key = Data(repeating: 0x42, count: 32) let emptyNonce = Data() @@ -173,7 +173,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func openFailsWithWrongKey() throws { - let plaintext = "Secret".data(using: .utf8)! + let plaintext = Data("Secret".utf8) let correctKey = Data(repeating: 0x42, count: 32) let wrongKey = Data(repeating: 0x43, count: 32) let nonce = Data(repeating: 0x24, count: 24) @@ -195,7 +195,7 @@ struct XChaCha20Poly1305CompatTests { } @Test func openFailsWithTamperedCiphertext() throws { - let plaintext = "Secret".data(using: .utf8)! + let plaintext = Data("Secret".utf8) let key = Data(repeating: 0x42, count: 32) let nonce = Data(repeating: 0x24, count: 24) diff --git a/localPackages/Arti/Package.swift b/localPackages/Arti/Package.swift index 1fe587da..c0e0ff5f 100644 --- a/localPackages/Arti/Package.swift +++ b/localPackages/Arti/Package.swift @@ -5,16 +5,16 @@ let package = Package( name: "Tor", // Keep name "Tor" for drop-in compatibility platforms: [ .iOS(.v16), - .macOS(.v13), + .macOS(.v13) ], products: [ .library( name: "Tor", targets: ["Tor"] - ), + ) ], dependencies: [ - .package(path: "../BitLogger"), + .package(path: "../BitLogger") ], targets: [ // Main Swift target @@ -22,19 +22,19 @@ let package = Package( name: "Tor", dependencies: [ "arti", - .product(name: "BitLogger", package: "BitLogger"), + .product(name: "BitLogger", package: "BitLogger") ], path: "Sources", exclude: ["C"], sources: [ "TorManager.swift", "TorURLSession.swift", - "TorNotifications.swift", + "TorNotifications.swift" ], linkerSettings: [ .linkedLibrary("resolv"), .linkedLibrary("z"), - .linkedLibrary("sqlite3"), + .linkedLibrary("sqlite3") ] ), // Binary framework containing the Rust static library. @@ -42,6 +42,6 @@ let package = Package( .binaryTarget( name: "arti", path: "Frameworks/arti.xcframework" - ), + ) ] ) diff --git a/localPackages/BitFoundation/Package.swift b/localPackages/BitFoundation/Package.swift index a1de1be1..fbcf8e4e 100644 --- a/localPackages/BitFoundation/Package.swift +++ b/localPackages/BitFoundation/Package.swift @@ -21,7 +21,7 @@ let package = Package( .target( name: "BitFoundation", dependencies: [ - .product(name: "BitLogger", package: "BitLogger"), + .product(name: "BitLogger", package: "BitLogger") ], path: "Sources" ), diff --git a/localPackages/BitFoundation/Tests/BitFoundationTests/BinaryProtocolTests.swift b/localPackages/BitFoundation/Tests/BitFoundationTests/BinaryProtocolTests.swift index 4016080f..ddf7c8fc 100644 --- a/localPackages/BitFoundation/Tests/BitFoundationTests/BinaryProtocolTests.swift +++ b/localPackages/BitFoundation/Tests/BitFoundationTests/BinaryProtocolTests.swift @@ -46,7 +46,8 @@ struct BinaryProtocolTests { // Verify recipient #expect(decodedPacket.recipientID != nil) let decodedRecipientID = decodedPacket.recipientID?.trimmingNullBytes() - // TODO: Check if this is intended that the decoding only gets the first 8 + // Recipient IDs are a fixed 8-byte wire field: encode pads or truncates + // to BinaryProtocol.recipientIDSize, so only the first 8 bytes survive. #expect(String(data: decodedRecipientID!, encoding: .utf8) == "abcdef01") } @@ -294,7 +295,7 @@ struct BinaryProtocolTests { @Test("Create a large, compressible payload above current threshold (2048B)") func payloadCompression() throws { let repeatedString = String(repeating: "This is a test message. ", count: 200) - let largePayload = repeatedString.data(using: .utf8)! + let largePayload = Data(repeatedString.utf8) let packet = TestHelpers.createTestPacket(payload: largePayload) @@ -314,7 +315,7 @@ struct BinaryProtocolTests { @Test("Small payloads should not be compressed") func smallPayloadNoCompression() throws { - let smallPayload = "Hi".data(using: .utf8)! + let smallPayload = Data("Hi".utf8) let packet = TestHelpers.createTestPacket(payload: smallPayload) let encodedData = try #require(BinaryProtocol.encode(packet), "Failed to encode small packet") let decodedPacket = try #require(BinaryProtocol.decode(encodedData), "Failed to decode small packet") @@ -362,7 +363,7 @@ struct BinaryProtocolTests { var encodedSizes = Set() for payload in payloads { - let packet = TestHelpers.createTestPacket(payload: payload.data(using: .utf8)!) + let packet = TestHelpers.createTestPacket(payload: Data(payload.utf8)) let encodedData = try #require(BinaryProtocol.encode(packet), "Failed to encode packet") // Verify padding creates standard block sizes up to configured limit (no 4096 bucket currently) diff --git a/localPackages/BitFoundation/Tests/BitFoundationTests/TestHelpers.swift b/localPackages/BitFoundation/Tests/BitFoundationTests/TestHelpers.swift index 5c8ca7c0..d2405b10 100644 --- a/localPackages/BitFoundation/Tests/BitFoundationTests/TestHelpers.swift +++ b/localPackages/BitFoundation/Tests/BitFoundationTests/TestHelpers.swift @@ -54,13 +54,13 @@ final class TestHelpers { type: UInt8 = 0x01, senderID: PeerID = PeerID(str: UUID().uuidString), recipientID: PeerID? = nil, - payload: Data = "test payload".data(using: .utf8)!, + payload: Data = Data("test payload".utf8), signature: Data? = nil, ttl: UInt8 = 3 ) -> BitchatPacket { return BitchatPacket( type: type, - senderID: senderID.id.data(using: .utf8)!, + senderID: Data(senderID.id.utf8), recipientID: recipientID?.id.data(using: .utf8), timestamp: UInt64(Date().timeIntervalSince1970 * 1000), payload: payload,