Validate nested iref reference sizes - #219
Conversation
bradh
left a comment
There was a problem hiding this comment.
LGTM. A test for correct decoding would be a useful follow-up.
Walkthrough
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@CodeRabbit review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/meta/iref.rs`:
- Around line 33-34: In the nested-reference parsing loop around u32::decode in
src/meta/iref.rs, check buf.remaining() < 4 before decoding the length and
return Error::InvalidSize for incomplete length fragments. Add regression
coverage for a single trailing byte and preserve normal decoding when at least
four bytes remain.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 142871e2-dd1a-4881-9303-075f30a5fbe2
📒 Files selected for processing (1)
src/meta/iref.rs
| while buf.has_remaining() { | ||
| let box_len = u32::decode(buf)? as usize; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the changed decoder before inspecting the primitive Decode implementation.
ast-grep outline src/meta/iref.rs --items all
# Verify the error path used by primitive u32 decoding and locate related tests.
rg -n -C 4 'impl\s+Decode\s+for\s+u32|u32::decode|OutOfBounds|InvalidSize' src
rg -n -C 4 'oversized_nested_reference|nested_reference_smaller_than_header' src/meta/iref.rsRepository: kixelated/mp4-atom
Length of output: 50375
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the relevant iref decoder and tests.
sed -n '1,190p' src/meta/iref.rs
# Read the exact primitive decoding implementations.
sed -n '1,125p' src/coding.rs
# Read Error enum.
sed -n '1,60p' src/error.rs
# Check current test coverage for small trailing bytes.
rg -n -C 3 '1|2|3|trailing|smaller_than_header|nested' src/meta/iref.rs
# Standalone parser for the exact inputs in the loop.
python3 - <<'PY'
from struct import unpack
inputs = {
"1 byte trailing": b"\x00",
"2 byte trailing": b"\x00\x00",
"3 byte trailing": b"\x00\x00\x00",
}
expected = "Out of bounds"
for name, payload in inputs.items():
error = None
if len(payload) < 4:
error = "Out of bounds"
print(name, "→", error if error else "valid")
print("u32 primitive requires 4 bytes, so 1-, 2-, 3-byte remainders cannot be decoded before size check.")
PYRepository: kixelated/mp4-atom
Length of output: 14487
Return Error::InvalidSize for one-byte nested length fragments.
u32::decode(buf) returns Error::OutOfBounds when the buffer has fewer than four bytes, so one remaining byte now leaves the malformed nested reference length error-handling contract inconsistent. Add a guard for buf.remaining() < 4 before decoding box_len and add regression tests for a single trailing byte.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/meta/iref.rs` around lines 33 - 34, In the nested-reference parsing loop
around u32::decode in src/meta/iref.rs, check buf.remaining() < 4 before
decoding the length and return Error::InvalidSize for incomplete length
fragments. Add regression coverage for a single trailing byte and preserve
normal decoding when at least four bytes remain.
Split from #199. Refs #179.
What changed
irefbox size before slicing its body.Error::InvalidSize.Why
Nested box lengths are attacker-controlled. The previous decoder subtracted and sliced them without bounds checks, which could underflow, panic, or decode across box boundaries.
Impact
Malformed
irefdata now returns a normal parse error while valid references continue to decode unchanged.Validation
cargo fmt --all -- --checkcargo test --all-features(252 unit tests and 3 doctests passed)cargo clippy --all-targets --all-features -- -D warningsgit diff --check main...HEAD