Give the crate a document level cbor decoder for the spec's MUST-discard rule - #278
Open
thedavidmeister wants to merge 1 commit into
Open
Give the crate a document level cbor decoder for the spec's MUST-discard rule#278thedavidmeister wants to merge 1 commit into
thedavidmeister wants to merge 1 commit into
Conversation
`cbor_decode` treats the rain meta document magic number as an optional prefix, which is the contract the bare item bytes that `hash(false)` identifies a meta by depend on. The metadata-v1 spec's rule that tooling MUST discard data not beginning with that magic number is a document level rule, and the crate had no way to express it: `Store::store_content` re-checked the prefix itself after decoding, because the decoder dropped the one fact it needed. `cbor_decode_document` is that rule, matching solidity `LibMeta.checkMetaUnhashedV1` in the same repo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 58 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 (2)
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 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 #203
The decision the issue asks for
cbor_decodeis an item/sequence level decoder whose document prefix isoptional by design. Three things in the tree say so, none of them accidental:
hash(false)— the metaboard subject for an individual meta — iskeccak256over the bare cbor map, andStore::set_dotrainkeys itscache by exactly those bytes. They carry no prefix and have to decode.
cbor_encode(bare item) andcbor_encode_seq(prefix + items) are bothpublic, and
cbor_decodeis the only decoder: it is the inverse of both.cbor_encodeoutput directly —authoring_meta_roundtrip,dotrain_meta_roundtrip,oa_schema_map_key_roundtrip,no_schema_key_encodes_as_before_roundtrip.So the issue's first branch — make
cbor_decodereject unprefixed input — isnot taken. It would break all three, on a published API, to enforce a rule the
function is not the right place for.
The gap that was real
The spec's MUST ("Tooling that wishes to read meta MUST discard/ignore all
binary data that does not begin with the magic number") is a document level
rule, and the crate gave callers no way to obey it. The solidity half of this
same repo does have it —
LibMeta.isRainMetaV1/checkMetaUnhashedV1— so thetwo halves disagreed about whether unprefixed bytes are meta at all.
Store::store_contentwas the evidence: it calledcbor_decode, thenre-checked
bytes.starts_with(RainMetaDocumentV1)itself before cachinganything, because the decoder had thrown away the one fact it needed.
The fix
RainMetaDocumentV1Item::cbor_decode_document— the document level decoder.Error::NotRainMetaDocumentV1unless the data begins with the document magicnumber, then the existing sequence decode. It is the counterpart of
LibMeta.checkMetaUnhashedV1and the inverse ofcbor_encode_sequnder thatmagic.
store_contentcalls it and drops its hand-rolled prefix re-check: samecondition, one place. No behaviour change there.
cbor_decodeitself is untouched. Its contract is now stated on the functionand pinned by a test, instead of being re-derived by every reader from the
starts_withbranch — which is what the issue asked for on this branch.Relation to the other cbor_decode / KnownMagic work in flight
track,the
error.offset() == lenequality). This diff touches neither the loop northe guard — it adds a function above
cbor_decodeand rewrites the doc line.Only that doc line can conflict textually; semantically independent.
Independent: that is per-item validity, this is the document envelope.
cbor_decode_documentdelegates, so it inherits whatever Items missing mandatory cbor keys 0/1 abort the whole decode; spec says they MUST be treated as unexpected and dropped/ignored #188 decides.(duplicate cbor map keys) are likewise about items once the sequence is
already being decoded. Inherited the same way, no overlap in this diff.
KnownMagicvariant. No interaction.RainMetaDocumentV1should be rejected as an item'sown magic. Adjacent but pointed the other way: this PR enforces that magic
where it is the document envelope and takes no position on the key-1 case.
The two compose if RainMetaDocumentV1 document magic is encodable as an item's own magic, producing representable-but-unusable metas #204 lands strict.
QA
crates/cli/src/meta/mod.rs):test_cbor_decode_document_requires_the_document_prefix,test_cbor_decode_document_rejects_other_magic_prefix,test_cbor_decode_document_rejects_data_shorter_than_the_prefix. Each failson base by construction — base has no such function. The behaviour they pin
is a real distinction, not just a new name: the first asserts both sides,
that
cbor_decodestill accepts the bare map (base behaviour deliberatelykept) and that
cbor_decode_documentrejects the same bytes. The thirdcovers the
< 8bytes case that solidityisRainMetaV1opens with.The pre-existing
test_store_update_with_validation_and_contentalreadypinned both
store_contentbranches (prefixed document caches inner items,bare sequence does not); it stays green untouched, which is the evidence that
the
store_contentrewrite changed nothing.cargo test -p rain-metadata --lib meta::tests::run, then reverted:if !data.starts_with(...)->if false(never reject) -> 4 failed:the three new tests plus
test_store_update_with_validation_and_content.!(reject exactly the documents) -> 5 failed, addingtest_store_update_and_update_check.KnownMagic::RainMetaDocumentV1->KnownMagic::DotrainV1in the check-> 4 failed.
store_content:cbor_decode_document->cbor_decode(restores the basedecode, drops the reinstated guard) -> 1 failed,
test_store_update_with_validation_and_content.src/lib/LibMeta.sol(isRainMetaV1's length guard and magic equality,checkMetaUnhashedV1's revert) — not the behaviour ofcbor_decode, which isthe code under test.
(b) is taken, with the evidence above. The remedy it names for (b) — say that
the prefix is optional — is on
cbor_decode; the spec MUST that branch (b)otherwise leaves unserved is now reachable as
cbor_decode_document.Error::NotRainMetaDocumentV1is a new variant on the publicErrorenum;its
Displaystring is pinned intest_display_fixed_stringsalongside theothers.
Verification
Green locally:
cargo test -p rain-metadata --lib meta::tests::53 passed,cargo test -p rain-metadata --lib error::6 passed,cargo clippy --workspace --all-targetsclean,cargo fmt --check --allclean.The full suite was not run locally (many sibling agents share this machine); CI
runs it.
🤖 Generated with Claude Code