Skip to content

Commit c86994c

Browse files
authored
fix: rsonpath-syntax error messages blowing up on long inputs (#842)
* fix: rsonpath-syntax error messages blowing up on long inputs Previously, when displaying a ParseError every underlying SyntaxError would be printed with the full query input as context. If the density of errors in the input was high this would effectively cause a quadratic blowup during printing. It's probably unlikely inputs like this would be given by a user, but they do happen during fuzzing (when we're throwing long strings of essentially random characters at the parser) and could potentially be used as a DoS attack vector (intentionally supplying nonsensical large queries and forcing error messages to be sent back). Any SyntaxError contains the actual error span (which gets underlined in the output message) and the rest of the input is displayed as context. We will call the part before the error the *pre-context*, the part after the *post-context*, and the error part the *underline*. We alleviate the quadratic blowup in two ways. First, in multiline input we now only display the lines that contain the underline. Second, if the first (or last) line of the error is excessively long and would print a very large pre-context (or post-context), we truncate the context by force to keep the total line length under a reasonable limit (`error::display::MAX_ERROR_LINE_WIDTH`). Crucially, the SyntaxErrors never overlap, i.e. the underline parts are always disjoint. The fixes therefore guarantee that we will output at most the entire input, plus some constant overhead per error (limited by `MAX_ERROR_LINE_WIDTH`). The logic to accomplish this is non-trivial, so now we have quite a bit of code dedicated to this rather exotic edge-case. Nonetheless, it ultimately makes the error reporting much more robust. Additionally fixed an invalid error message given when a side of a comparison operator was a non-singular query. This is part of the investigation into fuzzing failures tracked at #749.
1 parent 2f28704 commit c86994c

14 files changed

+2782
-848
lines changed

crates/rsonpath-syntax/examples/cli.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
1+
use std::io::Read;
12
use std::process::ExitCode;
23

34
fn main() -> ExitCode {
45
let args: Vec<_> = std::env::args().collect();
56

6-
if args.len() != 2 {
7-
eprintln!("provide exactly one argument, the query string");
7+
if args.len() != 1 {
8+
eprintln!("no arguments are expected");
89
return ExitCode::FAILURE;
910
}
1011

11-
let input: &str = &args[1];
12+
let input = {
13+
let mut buf = String::new();
14+
if let Err(err) = std::io::stdin().read_to_string(&mut buf) {
15+
eprintln!("error reading stdin: {err}");
16+
return ExitCode::FAILURE;
17+
}
18+
buf
19+
};
1220

13-
let res = rsonpath_syntax::parse(input);
21+
let res = rsonpath_syntax::parse(&input);
1422

1523
match res {
1624
Ok(x) => println!("OK: {x:?}\nDISPLAY:{x}\nINPUT: {input}"),

0 commit comments

Comments
 (0)