Fix compressed BLE file transfers

This commit is contained in:
jack
2025-10-15 00:37:40 +01:00
committed by islam
parent a244c4084f
commit 8389961269
4 changed files with 128 additions and 4 deletions
+2 -2
View File
@@ -320,8 +320,8 @@ struct BinaryProtocol {
guard let rawSize = read16() else { return nil }
originalSize = Int(rawSize)
}
// Guard to keep decompression bounded (1 MiB ceiling aligns with previous behaviour)
guard originalSize >= 0 && originalSize <= 1_048_576 else { return nil }
// Guard to keep decompression bounded to sane BLE payload limits
guard originalSize >= 0 && originalSize <= FileTransferLimits.maxPayloadBytes else { return nil }
let compressedSize = payloadLength - lengthFieldBytes
guard compressedSize >= 0, let compressed = readData(compressedSize) else { return nil }
guard let decompressed = CompressionUtil.decompress(compressed, originalSize: originalSize),
+16 -2
View File
@@ -26,7 +26,9 @@ struct NotificationStreamAssembler {
var reset = false
let maxFrameLength = TransportConfig.bleNotificationAssemblerHardCapBytes
while buffer.count >= BinaryProtocol.v1HeaderSize + BinaryProtocol.senderIDSize {
let minimumFramePrefix = BinaryProtocol.v1HeaderSize + BinaryProtocol.senderIDSize
while buffer.count >= minimumFramePrefix {
guard let version = buffer.first else { break }
guard version == 1 || version == 2 else {
dropped.append(buffer.removeFirst())
@@ -41,10 +43,13 @@ struct NotificationStreamAssembler {
}
guard buffer.count >= framePrefix else { break }
let flagsIndex = buffer.startIndex + 11
let flagsOffset = 1 + 1 + 1 + 8 // version + type + ttl + timestamp
let flagsIndex = buffer.startIndex + flagsOffset
guard flagsIndex < buffer.endIndex else { break }
let flags = buffer[flagsIndex]
let hasRecipient = (flags & BinaryProtocol.Flags.hasRecipient) != 0
let hasSignature = (flags & BinaryProtocol.Flags.hasSignature) != 0
let isCompressed = (flags & BinaryProtocol.Flags.isCompressed) != 0
let lengthOffset = 12
let payloadLength: Int
@@ -63,6 +68,15 @@ struct NotificationStreamAssembler {
var frameLength = framePrefix + payloadLength
if hasRecipient { frameLength += BinaryProtocol.recipientIDSize }
if hasSignature { frameLength += BinaryProtocol.signatureSize }
if isCompressed {
let rawLengthFieldBytes = (version == 2) ? 4 : 2
if payloadLength < rawLengthFieldBytes {
SecureLogger.error("❌ Invalid compressed payload length (\(payloadLength))", category: .session)
buffer.removeAll()
reset = true
break
}
}
guard frameLength > 0, frameLength <= maxFrameLength else {
SecureLogger.error("❌ Notification frame length \(frameLength) invalid (cap=\(maxFrameLength)); resetting stream", category: .session)