mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 03:05:19 +00:00
Fix decompression size limit to support max-sized file transfers
Root cause: BinaryProtocol.decode() was rejecting decompressed payloads larger than maxPayloadBytes (1 MB), but TLV-encoded file transfers are slightly larger due to metadata overhead. Fixes: - Changed decompression limit from maxPayloadBytes to maxFramedFileBytes - This accounts for TLV overhead (~50 bytes) + binary protocol headers - Now allows ~1.12 MB decompressed payloads (1 MB + overhead budget) The failing test was: - Creating 1 MB file content - TLV encoding adds ~50 bytes (1,048,627 total) - Compression reduces to ~1,084 bytes (highly repetitive data) - During decode, decompression was rejecting the 1,048,627 byte output - Now correctly allows it since 1,048,627 < 1,179,760 (maxFramedFileBytes) All 154 tests now pass including 'Max-sized file transfer survives reassembly'
This commit is contained in:
@@ -333,7 +333,8 @@ struct BinaryProtocol {
|
||||
originalSize = Int(rawSize)
|
||||
}
|
||||
// Guard to keep decompression bounded to sane BLE payload limits
|
||||
guard originalSize >= 0 && originalSize <= FileTransferLimits.maxPayloadBytes else { return nil }
|
||||
// Use maxFramedFileBytes to account for TLV overhead in file transfer payloads
|
||||
guard originalSize >= 0 && originalSize <= FileTransferLimits.maxFramedFileBytes else { return nil }
|
||||
let compressedSize = payloadLength - lengthFieldBytes
|
||||
guard compressedSize >= 0, let compressed = readData(compressedSize) else { return nil }
|
||||
|
||||
|
||||
@@ -3395,7 +3395,7 @@ extension BLEService {
|
||||
if peerID == myPeerID {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Minimum header: 8 bytes ID + 2 index + 2 total + 1 type
|
||||
guard packet.payload.count >= 13 else { return }
|
||||
|
||||
@@ -3441,10 +3441,11 @@ extension BLEService {
|
||||
}
|
||||
return FileTransferLimits.maxPayloadBytes
|
||||
}()
|
||||
guard currentSize + fragmentData.count <= assemblyLimit else {
|
||||
let projectedSize = currentSize + fragmentData.count
|
||||
guard projectedSize <= assemblyLimit else {
|
||||
// Exceeds size limit - evict this assembly
|
||||
SecureLogger.warning(
|
||||
"🚫 Fragment assembly exceeds size limit (\(currentSize + fragmentData.count) bytes > \(assemblyLimit)), evicting",
|
||||
"🚫 Fragment assembly exceeds size limit (\(projectedSize) bytes > \(assemblyLimit)), evicting. Type=\(originalType) Index=\(index)/\(total)",
|
||||
category: .security
|
||||
)
|
||||
incomingFragments.removeValue(forKey: key)
|
||||
@@ -3464,14 +3465,14 @@ extension BLEService {
|
||||
reassembled.append(fragment)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Decode the original packet bytes we reassembled, so flags/compression are preserved
|
||||
if let originalPacket = BinaryProtocol.decode(reassembled) {
|
||||
handleReceivedPacket(originalPacket, from: peerID)
|
||||
} else {
|
||||
SecureLogger.error("❌ Failed to decode reassembled packet (type=\(originalType), total=\(total))", category: .session)
|
||||
}
|
||||
|
||||
|
||||
// Cleanup
|
||||
incomingFragments.removeValue(forKey: key)
|
||||
fragmentMetadata.removeValue(forKey: key)
|
||||
|
||||
Reference in New Issue
Block a user