fn check_entry_size(
safe_name: &str,
content_len: u64,
total_uncompressed: &mut u64,
warnings: &mut WarningSink,
) -> Result<bool, String>Expand description
Single choke point for the per-entry/aggregate size caps, shared by
BOTH intake paths (zip decompression and the raw files RPC list) —
reagent P1 / codex P1, PR #2379 round 5. Two separate gaps motivated
unifying this instead of patching each path independently:
- The raw
filesRPC branch previously ran NO size/count checks at all, even though the spec explicitly treats it as an equally untrusted alternate ingestion path to the zip — a hostile bundle submitted viafilesinstead ofzip_base64bypassed every zip-bomb/DoS defense this module had built for the zip path alone. - Even on the zip path, an entry whose ACTUAL decompressed size exceeds the per-entry cap was decompressed (paying the full MAX_ENTRY_UNCOMPRESSED_BYTES-sized read) and then skipped WITHOUT ever counting that work toward the aggregate budget — so up to MAX_ENTRY_COUNT such entries could force on the order of MAX_ENTRY_COUNT * MAX_ENTRY_UNCOMPRESSED_BYTES of real decompression work while the aggregate cap never tripped.
This function accounts content_len toward the aggregate budget
UNCONDITIONALLY, before deciding whether the entry itself is kept —
closing the second gap structurally (every byte actually processed
counts, whether or not the entry is ultimately retained) — and both
intake paths call it, closing the first gap by construction (there is
no path left that skips this check).
Returns Ok(true) to keep the entry, Ok(false) to skip it (a
warning has already been pushed), or Err to reject the whole import
(aggregate cap exceeded).