diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-03-22 05:48:55 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-03-22 05:48:55 +0000 |
commit | 2a6544f906818263e2791bc4cdf4fcbdf7260ab9 (patch) | |
tree | 12cc178506343e5dbbea0285e1dcd0bd0035398c /crates/ra_syntax/fuzz | |
parent | ed823cb38d6c6852b2645f6bcd4c3b699b4b7539 (diff) | |
parent | bf8e7930daa3fb168106534b1cc418f5bc44e8c0 (diff) |
Merge #1013
1013: Fuzz reparsing and fix found bugs r=matklad a=pcpthm
Add fuzz test for reparsing which:
- Checks reparsing doesn't panic and validate result syntax tree.
- Checks that incremental reparsing produces the same syntax tree as full reparse.
- Check for that errors are the same as full reparsing is disabled because errors are less important than syntax tree and produce failures which I couldn't figure out how to fix immediately (FIXME comment).
I guess the current input generation is inefficient but still found several bugs:
- Arithmetic overflow (negative result on an unsigned type). I changed the signature of `SyntaxError::add_offset` to solve this problem.
- When reparsing a leaf, the token of the leaf can be joined to the next characters. Such case was not considered.
- UNDERSCORE token was not produced when text length is exactly 1 (not a reparsing bug).
- When reparsing a block, *inner* curly braces should be balanced. i.e. `{}{}` is invalid.
- Effects of deleting newlines were not considered.
Co-authored-by: pcpthm <[email protected]>
Diffstat (limited to 'crates/ra_syntax/fuzz')
-rw-r--r-- | crates/ra_syntax/fuzz/Cargo.toml | 13 | ||||
-rw-r--r-- | crates/ra_syntax/fuzz/fuzz_targets/parser.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/fuzz/fuzz_targets/reparse.rs | 9 |
3 files changed, 21 insertions, 7 deletions
diff --git a/crates/ra_syntax/fuzz/Cargo.toml b/crates/ra_syntax/fuzz/Cargo.toml index 4a255882e..613ad2857 100644 --- a/crates/ra_syntax/fuzz/Cargo.toml +++ b/crates/ra_syntax/fuzz/Cargo.toml | |||
@@ -4,14 +4,15 @@ name = "ra_syntax-fuzz" | |||
4 | version = "0.0.1" | 4 | version = "0.0.1" |
5 | authors = ["rust-analyzer developers"] | 5 | authors = ["rust-analyzer developers"] |
6 | publish = false | 6 | publish = false |
7 | edition = "2018" | ||
7 | 8 | ||
8 | [package.metadata] | 9 | [package.metadata] |
9 | cargo-fuzz = true | 10 | cargo-fuzz = true |
10 | 11 | ||
11 | [dependencies.ra_syntax] | 12 | [dependencies] |
12 | path = ".." | 13 | ra_syntax = { path = ".." } |
13 | [dependencies.libfuzzer-sys] | 14 | ra_text_edit = { path = "../../ra_text_edit" } |
14 | git = "https://github.com/rust-fuzz/libfuzzer-sys.git" | 15 | libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git" } |
15 | 16 | ||
16 | # Prevent this from interfering with workspaces | 17 | # Prevent this from interfering with workspaces |
17 | [workspace] | 18 | [workspace] |
@@ -20,3 +21,7 @@ members = ["."] | |||
20 | [[bin]] | 21 | [[bin]] |
21 | name = "parser" | 22 | name = "parser" |
22 | path = "fuzz_targets/parser.rs" | 23 | path = "fuzz_targets/parser.rs" |
24 | |||
25 | [[bin]] | ||
26 | name = "reparse" | ||
27 | path = "fuzz_targets/reparse.rs" | ||
diff --git a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs index 4667d5579..76a8b08d0 100644 --- a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs +++ b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | #![no_main] | 1 | #![no_main] |
2 | #[macro_use] extern crate libfuzzer_sys; | 2 | use libfuzzer_sys::fuzz_target; |
3 | extern crate ra_syntax; | 3 | use ra_syntax::fuzz::check_parser; |
4 | 4 | ||
5 | fuzz_target!(|data: &[u8]| { | 5 | fuzz_target!(|data: &[u8]| { |
6 | if let Ok(text) = std::str::from_utf8(data) { | 6 | if let Ok(text) = std::str::from_utf8(data) { |
7 | ra_syntax::check_fuzz_invariants(text) | 7 | check_parser(text) |
8 | } | 8 | } |
9 | }); | 9 | }); |
diff --git a/crates/ra_syntax/fuzz/fuzz_targets/reparse.rs b/crates/ra_syntax/fuzz/fuzz_targets/reparse.rs new file mode 100644 index 000000000..45524d4c1 --- /dev/null +++ b/crates/ra_syntax/fuzz/fuzz_targets/reparse.rs | |||
@@ -0,0 +1,9 @@ | |||
1 | #![no_main] | ||
2 | use libfuzzer_sys::fuzz_target; | ||
3 | use ra_syntax::fuzz::CheckReparse; | ||
4 | |||
5 | fuzz_target!(|data: &[u8]| { | ||
6 | if let Some(check) = CheckReparse::from_data(data) { | ||
7 | check.run(); | ||
8 | } | ||
9 | }); | ||