cloudwego / cloudwego/sonic-rs
get_many: debug_assert!(strbuf.is_empty()) fires after a sibling key with a simple escape
- 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
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