Log the oversized-payload rejection instead of dropping in silence

`decodeCore` rejects a compressed packet whose declared expanded size
exceeds `maxFramedFileBytes` by returning nil with no trace. The suspicious-
ratio rejection immediately below it drops the packet just as completely but
logs a warning, so of the two ways a compressed payload can be refused, one
is diagnosable and one is invisible.

That asymmetry has a cost now that #1618 reports Android permitting a 10 MiB
expanded payload against this ~1.13 MiB ceiling: every such message dies here
with nothing on either side to say why, which is why it took a code read
rather than a log to find.

Behavior is unchanged — the packet is still refused, and the existing
"Reject payloads larger than the framed file cap" test still covers it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ecgang 2026-08-02 10:24:23 -07:00
parent 1f59e814f9
commit f61dcf37a8

View File

@ -366,7 +366,19 @@ public struct BinaryProtocol {
guard let rawSize = read16() else { return nil }
originalSize = Int(rawSize)
}
guard originalSize >= 0 && originalSize <= FileTransferLimits.maxFramedFileBytes else { return nil }
// Logged, not silent: this is the sibling of the ratio
// rejection below and drops the packet just as completely, but
// returning `nil` bare left no trace anywhere. A peer whose
// ceiling is higher than ours (issue #1618: Android permits a
// 10 MiB expanded payload against our ~1.13 MiB) then looks to
// both sides like a message that simply never arrived.
guard originalSize >= 0 && originalSize <= FileTransferLimits.maxFramedFileBytes else {
SecureLogger.warning(
"🚫 Declared expanded payload \(originalSize) B exceeds the \(FileTransferLimits.maxFramedFileBytes) B ceiling",
category: .security
)
return nil
}
let compressedSize = payloadLength - lengthFieldBytes
guard compressedSize > 0, let compressed = readData(compressedSize) else { return nil }