This commit is contained in:
CC
2026-06-10 14:14:28 +02:00
parent 2bd2751a6a
commit fc38a8c6b6
57 changed files with 1157 additions and 621 deletions
@@ -0,0 +1,110 @@
package com.bitchat.android.model
import com.bitchat.android.protocol.TlvLengthSize
import com.bitchat.android.protocol.TlvWriter
import com.bitchat.android.services.meshgraph.GossipTLV
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Test
class TlvPacketRegressionTest {
@Test
fun `identity announcement skips unknown tlv fields`() {
val noiseKey = ByteArray(32) { 0x11 }
val signingKey = ByteArray(32) { 0x22 }
val encoded = TlvWriter()
.put(0x7f, byteArrayOf(0x55), TlvLengthSize.ONE_BYTE)
.put(0x01, "alice".toByteArray(), TlvLengthSize.ONE_BYTE)
.put(0x02, noiseKey, TlvLengthSize.ONE_BYTE)
.put(0x03, signingKey, TlvLengthSize.ONE_BYTE)
.toByteArray()
val decoded = IdentityAnnouncement.decode(encoded)
assertNotNull(decoded)
assertEquals("alice", decoded!!.nickname)
assertArrayEquals(noiseKey, decoded.noisePublicKey)
assertArrayEquals(signingKey, decoded.signingPublicKey)
}
@Test
fun `private message rejects unknown tlv fields`() {
val encoded = TlvWriter()
.put(0x00, "msg-1".toByteArray(), TlvLengthSize.ONE_BYTE)
.put(0x7f, byteArrayOf(0x55), TlvLengthSize.ONE_BYTE)
.put(0x01, "hello".toByteArray(), TlvLengthSize.ONE_BYTE)
.toByteArray()
assertNull(PrivateMessagePacket.decode(encoded))
}
@Test
fun `request sync skips unknown tlv fields and enforces payload cap`() {
val encoded = TlvWriter()
.put(0x7f, byteArrayOf(0x55), TlvLengthSize.TWO_BYTES)
.put(0x01, byteArrayOf(4), TlvLengthSize.TWO_BYTES)
.put(0x02, byteArrayOf(0, 0, 0, 16), TlvLengthSize.TWO_BYTES)
.put(0x03, byteArrayOf(1, 2, 3), TlvLengthSize.TWO_BYTES)
.toByteArray()
val tooLarge = TlvWriter()
.put(0x01, byteArrayOf(4), TlvLengthSize.TWO_BYTES)
.put(0x02, byteArrayOf(0, 0, 0, 16), TlvLengthSize.TWO_BYTES)
.put(0x03, ByteArray(RequestSyncPacket.MAX_ACCEPT_FILTER_BYTES + 1), TlvLengthSize.TWO_BYTES)
.toByteArray()
val decoded = RequestSyncPacket.decode(encoded)
assertNotNull(decoded)
assertEquals(4, decoded!!.p)
assertEquals(16L, decoded.m)
assertArrayEquals(byteArrayOf(1, 2, 3), decoded.data)
assertNull(RequestSyncPacket.decode(tooLarge))
}
@Test
fun `file packet uses four byte content length for large payloads`() {
val content = ByteArray(70_000) { (it % 251).toByte() }
val packet = BitchatFilePacket(
fileName = "large.bin",
fileSize = content.size.toLong(),
mimeType = "application/octet-stream",
content = content
)
val encoded = packet.encode()
val decoded = BitchatFilePacket.decode(encoded!!)
val contentTypeOffset = encoded.indexOf(0x04.toByte())
val contentLength =
((encoded[contentTypeOffset + 1].toInt() and 0xFF) shl 24) or
((encoded[contentTypeOffset + 2].toInt() and 0xFF) shl 16) or
((encoded[contentTypeOffset + 3].toInt() and 0xFF) shl 8) or
(encoded[contentTypeOffset + 4].toInt() and 0xFF)
assertEquals(content.size, contentLength)
assertNotNull(decoded)
assertArrayEquals(content, decoded!!.content)
}
@Test
fun `file packet rejects unknown tlv fields`() {
val encoded = TlvWriter()
.put(0x7f, byteArrayOf(0x55), TlvLengthSize.TWO_BYTES)
.put(0x01, "x.bin".toByteArray(), TlvLengthSize.TWO_BYTES)
.put(0x02, byteArrayOf(0, 0, 0, 1), TlvLengthSize.TWO_BYTES)
.put(0x03, "application/octet-stream".toByteArray(), TlvLengthSize.TWO_BYTES)
.put(0x04, byteArrayOf(1), TlvLengthSize.FOUR_BYTES)
.toByteArray()
assertNull(BitchatFilePacket.decode(encoded))
}
@Test
fun `gossip tlv uses shared peer id and tlv helpers`() {
val encoded = GossipTLV.encodeNeighbors(listOf("0102030405060708", "aabbcc"))
assertEquals(listOf("0102030405060708", "aabbcc0000000000"), GossipTLV.decodeNeighborsFromAnnouncementPayload(encoded))
}
}