Skip to content

fix(lazyvalue): OwnedLazyValue::as_array/as_object on an unparsed value - #254

Merged
liuq19 merged 1 commit into
cloudwego:mainfrom
yuxi-liu-wired:pr/owned-lazy-as-array
Oct 11, 2026
Merged

liuq19 merged 1 commit into
cloudwego:mainfrom
yuxi-liu-wired:pr/owned-lazy-as-array

Conversation

@yuxi-liu-wired

Copy link
Copy Markdown
Contributor

fix: as_array/as_object on an unparsed OwnedLazyValue panicked on use

OwnedLazyValue::as_array and as_object (the &self versions from
JsonContainerTrait) return a LazyArray / LazyObject view of a
value that is still LazyPacked::Raw; the parse is cached in
LazyRaw::parsed. Their Deref impls only handled Parsed, so the
first use of the view panicked:

let lv: OwnedLazyValue = sonic_rs::from_str("[1,2]")?;
lv.as_array().unwrap().len()
    panicked: internal error: entered unreachable code:
              must be a lazy array

(The _mut versions replace Raw with Parsed first, so they work,
which is the path the existing tests use.) Deref now also takes the
Raw case and returns the cached parse from LazyRaw::load.

Test: test_owned_as_array_as_object_on_raw (fails before this
change); cargo miri test --all-features --lib lazyvalue::owned is
clean.

Testing

Each commit adds a regression test that fails before the change. The full test suite passes and
cargo fmt --check is clean on the changed files.

Found with a differential fuzzer comparing serde_json, simd-json, sonic-rs and jiter.

@CLAassistant

CLAassistant commented Oct 1, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@yuxi-liu-wired
yuxi-liu-wired force-pushed the pr/owned-lazy-as-array branch from 77e6b69 to 2dd94f1 Compare October 1, 2026 20:24
@codecov

codecov Bot commented Oct 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.47059% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.88%. Comparing base (cd1e5ab) to head (b46a8e0).

Files with missing lines Patch % Lines
src/lazyvalue/owned.rs 76.47% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #254      +/-   ##
==========================================
+ Coverage   72.62%   72.88%   +0.25%     
==========================================
  Files          42       42              
  Lines        9934     9962      +28     
==========================================
+ Hits         7215     7261      +46     
+ Misses       2719     2701      -18     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

`OwnedLazyValue::as_array` and `as_object` (the `&self` versions from
`JsonContainerTrait`) return a `LazyArray` / `LazyObject` view of a
value that is still `LazyPacked::Raw`; the parse is cached in
`LazyRaw::parsed`. Their `Deref` impls only handled `Parsed`, so the
first use of the view panicked:

    let lv: OwnedLazyValue = sonic_rs::from_str("[1,2]")?;
    lv.as_array().unwrap().len()
        panicked: internal error: entered unreachable code:
                  must be a lazy array

(The `_mut` versions replace `Raw` with `Parsed` first, so they work,
which is the path the existing tests use.) `Deref` now also takes the
`Raw` case and returns the cached parse from `LazyRaw::load`.

Test: `test_owned_as_array_as_object_on_raw` (fails before this
change); `cargo miri test --all-features --lib lazyvalue::owned` is
clean.

Found by a differential fuzzer (serde_json, simd-json, sonic-rs, jiter).
@liuq19
liuq19 force-pushed the pr/owned-lazy-as-array branch from b46a8e0 to f8080fe Compare October 11, 2026 06:02
@liuq19
liuq19 merged commit 444063c into cloudwego:main Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants