Tolerate trailing box padding after child boxes - #173
Conversation
WalkthroughAdded 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/moov/trak/mdia/minf/stbl/stsd/h264/avc1.rs (1)
107-147: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover both sides of the eight-byte boundary.
This test only exercises a four-byte remainder. Add cases for 1 and 7 bytes, plus an 8-byte remainder that remains on the existing rejection path, to verify the helper’s exact
< 8contract.🤖 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/moov/trak/mdia/minf/stbl/stsd/h264/avc1.rs` around lines 107 - 147, The test test_avc1_trailing_padding only validates a 4-byte remainder; extend it to cover 1-byte and 7-byte trailing padding cases, confirming both decode successfully and produce the original Avc1 value. Also add an 8-byte remainder case that continues to reject decoding, preserving the helper’s exact less-than-8-byte contract and existing rejection behavior.
🤖 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/moov/udta/mod.rs`:
- Line 224: Run cargo fmt to format the Rust test code around the buf slice
assignment, then verify cargo fmt -- --check passes without changes.
- Around line 40-45: In the child parsing loop around the size check, replace
the truncated-child break path with an immediate decoding error when size
exceeds buf.remaining(). Ensure the already-consumed header and leftover bytes
are not passed to skip_trailing_padding, while preserving normal parsing for
children whose declared body fits.
---
Nitpick comments:
In `@src/moov/trak/mdia/minf/stbl/stsd/h264/avc1.rs`:
- Around line 107-147: The test test_avc1_trailing_padding only validates a
4-byte remainder; extend it to cover 1-byte and 7-byte trailing padding cases,
confirming both decode successfully and produce the original Avc1 value. Also
add an 8-byte remainder case that continues to reject decoding, preserving the
helper’s exact less-than-8-byte contract and existing rejection behavior.
🪄 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
Run ID: e60959ab-d3f0-4be3-ba3f-9117d0dff04b
📒 Files selected for processing (17)
src/buf.rssrc/moov/trak/mdia/minf/stbl/stsd/ac3.rssrc/moov/trak/mdia/minf/stbl/stsd/amr/samr.rssrc/moov/trak/mdia/minf/stbl/stsd/av01.rssrc/moov/trak/mdia/minf/stbl/stsd/eac3.rssrc/moov/trak/mdia/minf/stbl/stsd/flac.rssrc/moov/trak/mdia/minf/stbl/stsd/h264/avc1.rssrc/moov/trak/mdia/minf/stbl/stsd/hevc/hev1.rssrc/moov/trak/mdia/minf/stbl/stsd/hevc/hvc1.rssrc/moov/trak/mdia/minf/stbl/stsd/mp4a/mod.rssrc/moov/trak/mdia/minf/stbl/stsd/opus.rssrc/moov/trak/mdia/minf/stbl/stsd/tx3g.rssrc/moov/trak/mdia/minf/stbl/stsd/uncv.rssrc/moov/trak/mdia/minf/stbl/stsd/vp9/vp08.rssrc/moov/trak/mdia/minf/stbl/stsd/vp9/vp09.rssrc/moov/trak/mdia/minf/stbl/stsd/wvtt.rssrc/moov/udta/mod.rs
| let mut buf = ENCODED_UDTA_WITH_CPRT.to_vec(); | ||
| buf.extend_from_slice(&[0, 0, 0, 0]); | ||
| let size = (buf.len() as u32).to_be_bytes(); | ||
| buf[0..4].copy_from_slice(&size); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Run cargo fmt before merging.
The build check reports a rustfmt diff in this test hunk. As per coding guidelines, Rust files must pass cargo fmt -- --check.
🧰 Tools
🪛 GitHub Check: build
[warning] 224-224:
Diff in /home/runner/work/mp4-atom/mp4-atom/src/moov/udta/mod.rs
🤖 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/moov/udta/mod.rs` at line 224, Run cargo fmt to format the Rust test code
around the buf slice assignment, then verify cargo fmt -- --check passes without
changes.
Sources: Coding guidelines, Linters/SAST tools
0fe5fd1 to
540aa7f
Compare
bradh
left a comment
There was a problem hiding this comment.
#112 was an earlier attempt at the same problem, so skip_trailing_padding may be needed in other places.
Can you fix the format problem.
I'd also prefer not to have the "before the fix" type noise added by the AI. That doesn't make sense in the code. If you want to have it, just put it in the PR text or a comment.
| /// other demuxers. A remainder of 8 or more bytes is left untouched so genuine | ||
| /// trailing corruption is still reported. | ||
| pub(crate) fn skip_trailing_padding<B: Buf>(buf: &mut B) { | ||
| if buf.remaining() < 8 { |
There was a problem hiding this comment.
Could this be
| if buf.remaining() < 8 { | |
| if buf.remaining() > 0 && buf.remaining() < 8 { |
to save the common case of buf.advance(0) ?
| Kind::KIND => kind = Some(Kind::decode_atom(&header, buf)?), | ||
| Meta::KIND => meta = Some(Meta::decode_atom(&header, buf)?), | ||
| Rtng::KIND => rtng = Some(Rtng::decode_atom(&header, buf)?), | ||
| // `free`/`skip` are padding boxes — drop them silently, as the |
There was a problem hiding this comment.
This kind of AI noise is better removed.
| } | ||
| } | ||
| // QuickTime appends a 4-byte zero terminator after `udta`'s children | ||
| // (e.g. after an `apmd` box), just as it does inside sample entries. |
There was a problem hiding this comment.
What is apmd and why does that matter here?
| // terminator) after a sample entry's child boxes. Before the fix the | ||
| // strict remaining-bytes check rejected the whole entry with | ||
| // `UnderDecode(avc1)`; now the sub-header remainder is skipped as padding. |
There was a problem hiding this comment.
| // terminator) after a sample entry's child boxes. Before the fix the | |
| // strict remaining-bytes check rejected the whole entry with | |
| // `UnderDecode(avc1)`; now the sub-header remainder is skipped as padding. | |
| // terminator) after a sample entry's child boxes. |
|
Also, its easier to review one fix at a time - this has two. |
QuickTime muxers append a few bytes of padding — commonly a 4-byte zero terminator — after the child boxes of a container atom or sample entry (e.g. `avc1 → avcC + colr + 00000000`). The remainder is shorter than an 8-byte box header, so it cannot be a box; ffmpeg, GPAC and others skip it. The strict remaining-bytes check otherwise fails the whole `moov` with `UnderDecode`. `skip_trailing_padding` drains a sub-header (`< 8` byte) remainder — 8+ zero bytes already decode as a null-fourcc box, so only a 1–7 byte remainder is affected — and is now called after the child-box loop everywhere one occurs: the `nested!` container macro (moov, trak, mdia, minf, stbl, dinf, edts, mvex, moof, traf, iprp, udta), the hand-written `meta` and `mfra` containers, and every sample entry. A remainder of 8+ bytes is left untouched so genuine trailing corruption is still reported.
540aa7f to
6d3fa1a
Compare
|
Split as requested — this PR is now just the trailing-padding fix; the Addressed the rest:
Rebased onto current |
QuickTime muxers append a few bytes of padding — commonly a 4-byte zero terminator — after the child boxes of a container atom or sample entry (e.g.
avc1 → avcC + colr + 00000000). The remainder is shorter than an 8-byte box header, so it can't be a box; ffmpeg, GPAC and others skip it. The strict remaining-bytes check otherwise fails the wholemoovwithUnderDecode.A
skip_trailing_paddinghelper drains a sub-header (< 8byte) remainder — 8+ zero bytes already decode as a null-fourcc box, so only a 1–7 byte remainder is affected — and is applied after the child-box loop everywhere one occurs (per the note about #112): thenested!container macro (moov/trak/mdia/minf/stbl/dinf/edts/mvex/moof/traf/iprp/udta), the hand-writtenmetaandmfracontainers, and every sample entry. A remainder of 8+ bytes is left untouched so genuine trailing corruption is still reported.Tests cover the sample-entry boundary (1/4/7 tolerated, 8 rejected) and the container paths (
edtsvia the macro,metahand-written).Split from the original two-in-one PR — the
udtanamespace dispatch is now #222. Rebased ontomain.