diff --git a/app/src/main/java/com/bitchat/android/util/BinaryEncodingUtils.kt b/app/src/main/java/com/bitchat/android/util/BinaryEncodingUtils.kt index d2637403..06615332 100644 --- a/app/src/main/java/com/bitchat/android/util/BinaryEncodingUtils.kt +++ b/app/src/main/java/com/bitchat/android/util/BinaryEncodingUtils.kt @@ -27,7 +27,8 @@ fun String.dataFromHexString(): ByteArray? { if (hex.isEmpty()) { return ByteArray(0) } - if (hex.length % 2 != 0) { + // Radix parsing accepts signs and Unicode digits; encoded bytes require ASCII hex. + if (hex.length % 2 != 0 || hex.any { it !in '0'..'9' && it !in 'a'..'f' && it !in 'A'..'F' }) { return null } diff --git a/app/src/test/java/com/bitchat/android/util/HexStringTest.kt b/app/src/test/java/com/bitchat/android/util/HexStringTest.kt index b5b449bc..6472ede8 100644 --- a/app/src/test/java/com/bitchat/android/util/HexStringTest.kt +++ b/app/src/test/java/com/bitchat/android/util/HexStringTest.kt @@ -48,6 +48,13 @@ class HexStringTest { assertNull("0xgg".dataFromHexString()) } + @Test + fun `rejects signed byte chunks and non-ascii digits`() { + for (invalid in listOf("0x-1", "0x+1", "-1", "+1", "00-1", "0X+100", "01")) { + assertNull(invalid.dataFromHexString()) + } + } + @Test fun `round-trips with hexEncodedString`() { val original = byteArrayOf(0x00, 0x7f, 0xff.toByte())