Skip to content

fix(platform-value): reject lossy CBOR integer conversions#4146

Merged
QuantumExplorer merged 3 commits into
v4.1-devfrom
codex/fix-platform-value-cbor-integers
Jul 21, 2026
Merged

fix(platform-value): reject lossy CBOR integer conversions#4146
QuantumExplorer merged 3 commits into
v4.1-devfrom
codex/fix-platform-value-cbor-integers

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Jul 20, 2026

Copy link
Copy Markdown
Member

What

  • replace unchecked 128-bit CBOR integer narrowing with checked native-range conversion
  • preserve the full native CBOR signed and unsigned integer range
  • reject out-of-range values before nested maps or arrays can emit altered data
  • add boundary, round-trip, collision-prevention, and nested-container regressions

Why

Distinct Platform Value integers could previously serialize to the same CBOR integer, and some native CBOR values could change sign during a decode/re-encode cycle. The conversion now fails closed with the existing IntegerSizeError.

This covers PLATFORM-DS-CAND-366 and PLATFORM-DS-CAND-367.

Checks

  • cargo fmt --all -- --check
  • cargo test -p platform-value --features cbor --lib --tests (1,316 passed)
  • cargo clippy -p platform-value --features cbor --all-targets -- -D warnings

The complete package command also ran all unit and integration tests successfully; its unrelated pre-existing doctest example fails because serde_json is not available to that doctest target.

Summary by CodeRabbit

  • Bug Fixes
    • Improved CBOR conversion for 128-bit signed and unsigned values by using safe integer conversion instead of narrowing.
    • Out-of-range 128-bit values now reliably fail with a dedicated integer size error.
    • Nested composite values containing out-of-range 128-bit integers correctly cause the overall conversion to fail.
  • Tests
    • Expanded test coverage for boundary behavior and verified CBOR serialization/deserialization round-trips for signed 128-bit values within the native range.

@github-actions github-actions Bot added this to the v4.1.0 milestone Jul 20, 2026
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cc24c43e-c865-4a02-8d84-268082f7ed43

📥 Commits

Reviewing files that changed from the base of the PR and between 950c0de and 9ce1e94.

📒 Files selected for processing (1)
  • packages/rs-platform-value/src/converter/ciborium.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/rs-platform-value/src/converter/ciborium.rs

📝 Walkthrough

Walkthrough

Value conversion to CBOR now uses checked native integer conversion and returns IntegerSizeError for overflow. Tests cover valid values, boundaries, nested failures, and I128 buffer round trips.

Changes

CBOR integer validation

Layer / File(s) Summary
Checked CBOR conversion and coverage
packages/rs-platform-value/src/converter/ciborium.rs
U128 and I128 conversions use checked integer conversion and return IntegerSizeError on overflow. Tests cover native boundaries, out-of-range values, nested conversion failures, and I128 buffer round trips.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: preventing lossy CBOR integer conversions in platform-value.
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-platform-value-cbor-integers

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…undaries

Round-trip I128 boundary values through to_cbor_buffer and back to pin
the serialized encoding at the edges of the native CBOR integer range,
and move the u64::MAX accept case into the u128 in-range test so the
reject test only covers rejection.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@QuantumExplorer
QuantumExplorer marked this pull request as ready for review July 20, 2026 13:25
@thepastaclaw

thepastaclaw commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

✅ Final review complete — no blockers (commit 9ce1e94)

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.95918% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 87.44%. Comparing base (fc05d62) to head (9ce1e94).
⚠️ Report is 1 commits behind head on v4.1-dev.

Files with missing lines Patch % Lines
...ckages/rs-platform-value/src/converter/ciborium.rs 97.95% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           v4.1-dev    #4146      +/-   ##
============================================
+ Coverage     87.43%   87.44%   +0.01%     
============================================
  Files          2646     2648       +2     
  Lines        333981   334222     +241     
============================================
+ Hits         292023   292273     +250     
+ Misses        41958    41949       -9     
Components Coverage Δ
dpp 88.44% <ø> (ø)
drive 86.13% <ø> (-0.02%) ⬇️
drive-abci 89.57% <ø> (+0.05%) ⬆️
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.90% <97.95%> (+0.01%) ⬆️
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 49.55% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final validation — Codex + Sonnet

This PR fixes a real correctness bug where U128/I128 platform values outside ciborium's native CBOR integer range were silently truncated via as u64/as i64 casts, causing distinct values to collide or flip sign on decode. The fix replaces these with checked Integer::try_from conversions that I verified against ciborium 0.2.2's actual TryFrom/TryFrom source match the native range exactly, failing closed with the crate's existing Error::IntegerSizeError pattern. All 38 relevant tests pass, clippy is clean with warnings denied, and the new boundary/rejection/nested-container/round-trip tests correctly exercise the fix. Only a minor test-code duplication nitpick was found; no blocking issues.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed), gpt-5.6-sol — security-auditor (completed), gpt-5.6-sol — rust-quality (completed)
  • Verifier: claude-sonnet-5 — final-verifier
  • Sonnet reviewers: claude-sonnet-5 — general (completed), claude-sonnet-5 — security-auditor (completed), claude-sonnet-5 — rust-quality (completed)

💬 1 nitpick(s)

Comment on lines +400 to +598
@@ -535,6 +593,23 @@ mod tests {
assert!(!buf.is_empty());
}

#[test]
fn to_cbor_buffer_roundtrips_native_cbor_integer_boundaries() {
const MIN_NATIVE_CBOR_INTEGER: i128 = -(u64::MAX as i128) - 1;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Nitpick: MIN_NATIVE_CBOR_INTEGER boundary constant duplicated across three test functions

const MIN_NATIVE_CBOR_INTEGER: i128 = -(u64::MAX as i128) - 1; is independently redefined inside i128_preserves_the_full_native_cbor_integer_range (line 400), i128_rejects_values_outside_the_native_cbor_integer_range (line 418), and to_cbor_buffer_roundtrips_native_cbor_integer_boundaries (line 598). This is the exact boundary value the whole PR is about, so keeping it in three places means a future edit could update it in one test but not the others, silently weakening coverage of the edge case this PR was written to protect.

Suggested change
// at module scope, e.g. just inside `mod tests {`
const MIN_NATIVE_CBOR_INTEGER: i128 = -(u64::MAX as i128) - 1;

source: ['claude']

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in 9ce1e94MIN_NATIVE_CBOR_INTEGER boundary constant duplicated across three test functions no longer present.

Auto-resolved by the review system based on the latest commit diff. If you believe this was closed in error, reopen the thread.

…e scope

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final validation — Codex + Sonnet

This delta is a pure test-only cleanup: it hoists the previously triplicated MIN_NATIVE_CBOR_INTEGER constant to module scope in packages/rs-platform-value/src/converter/ciborium.rs and updates the three boundary/rejection/round-trip tests to reference it. No production code, validation logic, or consensus-relevant behavior changed. Both Codex and Claude reviewer lanes independently confirm the prior duplication finding is fixed and report no new defects.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (failed), gpt-5.6-sol — rust-quality (failed), gpt-5.6-sol — general (failed), gpt-5.6-sol — rust-quality (failed), gpt-5.6-sol — general (failed), gpt-5.6-sol — rust-quality (failed), gpt-5.6-sol — general (failed), gpt-5.6-sol — rust-quality (failed), gpt-5.6-sol — general (failed), gpt-5.6-sol — rust-quality (failed), gpt-5.6-sol — general (failed), gpt-5.6-sol — general (completed), gpt-5.6-sol — rust-quality (completed)
  • Verifier: claude-sonnet-5 — final-verifier
  • Sonnet reviewers: claude-sonnet-5 — general (failed), claude-sonnet-5 — rust-quality (failed), claude-sonnet-5 — general (failed), claude-sonnet-5 — rust-quality (failed), claude-sonnet-5 — general (failed), claude-sonnet-5 — rust-quality (failed), claude-sonnet-5 — general (failed), claude-sonnet-5 — rust-quality (failed), claude-sonnet-5 — general (completed), claude-sonnet-5 — rust-quality (completed)

@QuantumExplorer
QuantumExplorer merged commit 7f4aaa2 into v4.1-dev Jul 21, 2026
32 of 35 checks passed
@QuantumExplorer
QuantumExplorer deleted the codex/fix-platform-value-cbor-integers branch July 21, 2026 05:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants