From 6efe9d02fbf9f3e20dbeafdce4ace7bff858ac63 Mon Sep 17 00:00:00 2001 From: "evgeniy.chernomortsev" Date: Tue, 9 Dec 2025 15:01:59 +0400 Subject: [PATCH] fix: harden hex string parsing (#646) Improve Data(hexString:) to handle edge cases: - Reject odd-length strings (return nil) - Support optional 0x/0X prefix - Trim leading/trailing whitespace - Handle empty strings correctly Add comprehensive unit tests for hex parsing. --- bitchat/Protocols/BinaryEncodingUtils.swift | 34 ++++-- bitchatTests/Utils/HexStringTests.swift | 108 ++++++++++++++++++++ 2 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 bitchatTests/Utils/HexStringTests.swift diff --git a/bitchat/Protocols/BinaryEncodingUtils.swift b/bitchat/Protocols/BinaryEncodingUtils.swift index 10c14c99..1dcfe7c1 100644 --- a/bitchat/Protocols/BinaryEncodingUtils.swift +++ b/bitchat/Protocols/BinaryEncodingUtils.swift @@ -23,20 +23,42 @@ extension Data { return digest.map { String(format: "%02x", $0) }.joined() } + /// Initialize Data from a hex string. + /// - Parameter hexString: A hex string, optionally prefixed with "0x" or "0X". + /// Whitespace is trimmed. Must have even length after prefix removal. + /// - Returns: nil if the string has odd length or contains invalid hex characters. init?(hexString: String) { - let len = hexString.count / 2 + var hex = hexString.trimmingCharacters(in: .whitespaces) + + // Remove optional 0x prefix + if hex.hasPrefix("0x") || hex.hasPrefix("0X") { + hex = String(hex.dropFirst(2)) + } + + // Reject odd-length strings + guard hex.count % 2 == 0 else { + return nil + } + + // Reject empty strings + guard !hex.isEmpty else { + self = Data() + return + } + + let len = hex.count / 2 var data = Data(capacity: len) - var index = hexString.startIndex - + var index = hex.startIndex + for _ in 0..