cloudwego / cloudwego/sonic-rs

get_many: debug_assert!(strbuf.is_empty()) fires after a sibling key with a simple escape

Open
#241 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
920
Forks
68
Avg merge
2h 5m
Merged PRs (30d)
1

Description

`parse_str` clears `strbuf` lazily (only right before it copies an escaped string into it). A key containing a simple escape (`\f`, `\n`, `\\`) leaves the unescaped bytes in `strbuf`; the next key without escapes is returned borrowed and never touches the buffer; when that key matches a PointerTree node with children, `get_many_keys` is entered recursively with a non-empty `strbuf` and the `debug_assert!` fires. `\u` escapes do not trigger it (a different copy path).

```
use sonic_rs::{get_many, pointer, PointerTree};
fn main() {
let mut tree = PointerTree::new();
tree.add_path(&pointer!["c", "d"]);
let json: &[u8] = br#"{"\f":9,"c":{"d":1}}"#;
println!("{:?}", get_many(json, &tree));
}
```

thread 'main' panicked at .../sonic-rs-0.5.8/src/parser.rs:1714:9:
assertion failed: strbuf.is_empty()

none for release users (results are correct), but every consumer that runs tests with debug assertions crashes on such inputs.

Contributor guide

Open the contributing guide

Research direction

Start at src/parser.rs:1714 and trace get_many_keys together with parse_str, using the reproducer in the issue to follow strbuf after a simple escape and the next sibling key. Add a regression test covering the shown JSON and PointerTree path, then run the relevant test suite with debug assertions; done means the input no longer panics and existing results remain correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.