[BUG] Out of bounds index diffing Go code
ekilmer opened this issue · comments
Eric Kilmer commented
Describe the bug
I get an out of bounds index error when diffing Go code:
thread 'main' panicked at 'byte index 6 is out of bounds of ` do()`', src/formatting.rs:403:43
To Reproduce
Have a file a.go
:
package main
import "fmt"
func main() {
b := "string"
fmt.Println(b)
c := "hi"
fmt.Println(c)
}
Have a file b.go
:
package main
import "fmt"
func main() {
do()
}
func do() {
b := "string"
fmt.Println(b)
c := "hi"
fmt.Println(c)
}
Run the following to see the error:
$ env RUST_BACKTRACE=1 cargo run --package diffsitter --bin diffsitter a.go b.go
Compiling diffsitter v0.7.1 (/Users/ekilmer/src/diffsitter)
Finished dev [unoptimized + debuginfo] target(s) in 1.44s
Running `target/debug/diffsitter a.go b.go`
thread 'main' panicked at 'byte index 6 is out of bounds of ` do()`', src/formatting.rs:403:43
stack backtrace:
0: rust_begin_unwind
at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/std/src/panicking.rs:575:5
1: core::panicking::panic_fmt
at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/panicking.rs:65:14
2: core::str::slice_error_fail_rt
3: core::str::slice_error_fail
at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/str/mod.rs:86:9
4: core::str::traits::<impl core::slice::index::SliceIndex<str> for core::ops::range::Range<usize>>::index
at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/str/traits.rs:218:21
5: core::str::traits::<impl core::ops::index::Index<I> for str>::index
at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/str/traits.rs:65:9
6: diffsitter::formatting::DiffWriter::print_line
at ./src/formatting.rs:403:43
7: diffsitter::formatting::DiffWriter::print_hunk
at ./src/formatting.rs:354:13
8: diffsitter::formatting::DiffWriter::print
at ./src/formatting.rs:227:21
9: diffsitter::run_diff
at ./src/main.rs:182:5
10: diffsitter::main
at ./src/main.rs:275:13
11: core::ops::function::FnOnce::call_once
at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/ops/function.rs:251:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
a.go -> b.go
============
5 - 8:
------
+ do()
Expected behavior
I expect no error and a diff.
Log output/screenshots
See above
Platform:
OS: macOS 13.0
Rust: rustc 1.66.0-nightly (0da281b60 2022-10-27)
Additional context
I was able to debug and make a patch that allows the tool to finish without crashing. I'm not very familiar with Rust or this project, so this patch could probably use some improvement.
Patch:
diff --git a/src/formatting.rs b/src/formatting.rs
index 00d822b..f5077cf 100644
--- a/src/formatting.rs
+++ b/src/formatting.rs
@@ -388,6 +388,9 @@ fn print_line(
// We keep printing ranges until we've covered the entire line
for entry in &line.entries {
+ if entry.text.eq_ignore_ascii_case("\n") || entry.text.eq_ignore_ascii_case("\r") {
+ continue;
+ }
// The range of text to emphasize
// TODO(afnan) deal with ranges spanning multiple rows
let emphasis_range = entry.start_position().column..entry.end_position().column;
Output with patch:
$ cargo run --package diffsitter --bin diffsitter a.go b.go
Finished dev [unoptimized + debuginfo] target(s) in 0.17s
Running `target/debug/diffsitter a.go b.go`
a.go -> b.go
============
5 - 8:
------
+ do()
+ }
+
+ func do() {
Afnan Enayet commented
Interesting, it seems like the tree-sitter parser for go counts each newline as a node