fix: drop unknown-magic items in cbor_decode instead of failing the document - #274
Open
thedavidmeister wants to merge 2 commits into
Open
fix: drop unknown-magic items in cbor_decode instead of failing the document#274thedavidmeister wants to merge 2 commits into
thedavidmeister wants to merge 2 commits into
Conversation
…ocument A cbor-seq mixing a supported meta with one carrying a magic this crate does not know decoded to nothing at all, so the supported item was unreachable. metadata-v1 makes the per-item magic the O(1) signal tooling uses to drop/ignore meta it does not support, and states that others are free to build with their own numbers. An input left with no items after the drop is UnsupportedMeta, not an empty vec: callers index the result. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 17 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
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 |
This was referenced Aug 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #186.
The adjudication
#186 asks, neutrally, whether
cbor_decodeis meant to be strict about unknownmagic numbers or to drop them. This PR takes drop, because the spec text is
one-sided on it:
need or support decoding and parsing for". The per-item magic is named as
exactly the mechanism for that — "a signal of intent for the payload
without needing to first parse ... the entire payload".
interpretations", and the map structure exists "to facilitate future
modifications to the conventions in this document in a way that tooling can
adopt (or not) in a backwards compatible way".
Under the old behaviour neither is achievable: one third-party or newer-spec
item made the whole cbor-seq undecodable, so the supported items alongside it
were unreachable. The spec's magic number table already lists a number this
crate does not carry (Web data v1, the subject of #187), so a document a
conforming encoder can produce today is one this crate cannot read at all.
If a reviewer wants strict instead, then the spec text quoted above needs the
clarifying note #186 mentions, and this PR should be closed rather than
reworked.
What changed
RainMetaDocumentV1Item::cbor_decodepeeks the magic under cbor map key 1 onthe already-parsed
serde_cbor::Valueand skips the item when it is not aKnownMagic, then returns the rest.Deserializevisitor is untouched and still errors on an unknown magic.magicis typedKnownMagic, so a single item with an unknown magic has norepresentation; the drop belongs at the sequence level, which is where the
spec puts it.
or negative key 1, and a sequence member that is not a map at all, still go
through
from_valueand error exactly as before.Error::UnsupportedMeta,not
Ok(vec![]).cbor_decodenever returning an empty vec is load-bearing:AuthoringMetaV2::fetch_for_contractindexes[0]on the result.track.len() != metas.len()(dropping itemsmakes those lengths legitimately differ) and moves
metas.is_empty()out tothe new unsupported check.
track.is_empty()and the end-offset equalitystay, so empty input, a bare document prefix and trailing/truncated bytes are
still
CorruptMeta.Overlap with sibling issues
All five open
cbor_decode/KnownMagicissues were checked; this PR touchesone of them.
track.len() != metas.len()andmetas.is_empty()sub-conditions equivalentmutants. This PR removes the first (dropping items makes it reachable in the
other direction, so it had to go) and repurposes the second as the
unsupported check. The eof
error.offset() == lencondition cbor_decode corrupt-meta guard carries unreachable sub-conditions (eof offset equality, track/metas length) — equivalent-mutant evidence #190 also namesis untouched.
KnownMagic) — no overlap. Adding thatvariant only moves one number from dropped to decoded. The new tests
deliberately use
0xdeadbeefdeadbeef, never a spec-table number, so they donot collide with that fix.
and no behaviour change here: an item with no key 1 still reaches
from_valueand still errors. If Items missing mandatory cbor keys 0/1 abort the whole decode; spec says they MUST be treated as unexpected and dropped/ignored #188 lands, its drop belongs in this sameloop.
serde_cbor::Valuemapfrom_valuealready consumed, so whatever that doeswith duplicates is unchanged.
handling is untouched.
QA
Discriminating tests:
test_cbor_decode_drops_unknown_magic_items,test_cbor_decode_unknown_magic_first_item,test_cbor_decode_all_unknown_magic_is_unsupported,test_cbor_decode_unknown_magic_then_truncated_is_corrupt— each fails onbase, verified by mutating the skip back off (
if true || !is_unknown_magic,which restores the base decode path): all four fail, and the mixed-document
one fails with the issue's own repro,
SerdeCborError(Message("unknown magic number")). The base-behaviour testthey replace,
test_cbor_decode_unknown_magic_errors, is deleted — it pinnedthe behaviour this PR changes.
test_cbor_decode_non_integer_magic_errorsandtest_cbor_decode_non_map_item_errorsdo NOT fail on base (base also errorsthere); they are guard tests bounding the new drop path, mutation-killed
below.
Mutations applied:
if !is_unknown_magic→if true || !is_unknown_magic(never drop) →killed by
test_cbor_decode_drops_unknown_magic_items,test_cbor_decode_unknown_magic_first_item,test_cbor_decode_all_unknown_magic_is_unsupported,test_cbor_decode_unknown_magic_then_truncated_is_corrupt(4 failed).if metas.is_empty() { Err(UnsupportedMeta)? }→if false && ...(no unsupported guard, returns
Ok(vec![])) → killed bytest_cbor_decode_all_unknown_magic_is_unsupported(1 failed).peek_magic's two_ => Nonearms →_ => Some(0)(treat a missing,non-integer or non-map key 1 as an unknown magic and drop it) → killed by
test_cbor_decode_non_integer_magic_errors,test_cbor_decode_non_map_item_errorsand the pre-existingtest_cbor_decode_missing_magic_errors(3 failed).Each mutant was reverted and the suite re-run green after measuring.
Oracle: the metadata-v1 spec
(https://github.com/rainlanguage/specs/blob/main/metadata-v1.md), quoted
above, for the drop/ignore behaviour; the cbor spec for the expected bytes.
Every fixture is handwritten byte by byte (
handwritten_map_foremitsa2 00 41 <payload> 01 1b <magic big-endian>from the cbor major types, notfrom
cbor_encode), and the expected decoded values are built withplain_item, so no assertion is computed by the code under test.Category check: the issue asks one question — strict vs drop — and reports one
behaviour (a document mixing supported and unknown-magic items decodes to
nothing). Covered: the mixed document now decodes to its supported items in
order (unknown in the middle, and unknown first), and the all-unknown boundary
the question implies is settled explicitly as
UnsupportedMeta. The issue'sfallback ask — "if the strict behaviour is intended, the spec text may deserve
a clarifying note" — is not taken, because this PR adjudicates the other way;
the spec repo is not this repo and no spec change is made here.
Verification:
cargo test -p rain-metadata --lib meta::— 237 passed, 0 failed.cargo clippy --all-targets -- -D warningsandcargo fmt --checkclean. Thefull suite was not run locally by request; CI covers it.
🤖 Generated with Claude Code