Skip to content

Commit b8810ee

Browse files
authoredOct 28, 2022
fix(graphical): Fix panic with zero-width span at end of line (#204)
This was introduced in 196c09c, and is a simple off-by-one error.
1 parent 622e09d commit b8810ee

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed
 

‎src/handlers/graphical.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ impl GraphicalReportHandler {
618618

619619
/// Returns the visual column position of a byte offset on a specific line.
620620
fn visual_offset(&self, line: &Line, offset: usize) -> usize {
621-
let line_range = line.offset..(line.offset + line.length);
621+
let line_range = line.offset..=(line.offset + line.length);
622622
assert!(line_range.contains(&offset));
623623

624624
let text = &line.text[..offset - line.offset];
@@ -657,9 +657,9 @@ impl GraphicalReportHandler {
657657
.iter()
658658
.map(|hl| {
659659
let byte_start = hl.offset();
660-
let byte_end = hl.offset() + hl.len().max(1);
660+
let byte_end = hl.offset() + hl.len();
661661
let start = self.visual_offset(line, byte_start).max(highest);
662-
let end = self.visual_offset(line, byte_end);
662+
let end = self.visual_offset(line, byte_end).max(start + 1);
663663

664664
let vbar_offset = (start + end) / 2;
665665
let num_left = vbar_offset - start;

‎tests/graphical.rs

+68
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,38 @@ fn empty_source() -> Result<(), MietteError> {
6767
Ok(())
6868
}
6969

70+
#[test]
71+
fn single_line_highlight_span_full_line() {
72+
#[derive(Error, Debug, Diagnostic)]
73+
#[error("oops!")]
74+
#[diagnostic(severity(Error))]
75+
struct MyBad {
76+
#[source_code]
77+
src: NamedSource,
78+
#[label("This bit here")]
79+
bad_bit: SourceSpan,
80+
}
81+
let err = MyBad {
82+
src: NamedSource::new("issue", "source\ntext"),
83+
bad_bit: (7, 4).into(),
84+
};
85+
let out = fmt_report(err.into());
86+
println!("Error: {}", out);
87+
88+
let expected = r#"
89+
× oops!
90+
╭─[issue:1:1]
91+
1 │ source
92+
2 │ text
93+
· ──┬─
94+
· ╰── This bit here
95+
╰────
96+
"#
97+
.to_string();
98+
99+
assert_eq!(expected, out);
100+
}
101+
70102
#[test]
71103
fn single_line_with_wide_char() -> Result<(), MietteError> {
72104
#[derive(Debug, Diagnostic, Error)]
@@ -290,6 +322,42 @@ fn single_line_highlight_offset_zero() -> Result<(), MietteError> {
290322
Ok(())
291323
}
292324

325+
#[test]
326+
fn single_line_higlight_offset_end_of_line() -> Result<(), MietteError> {
327+
#[derive(Debug, Diagnostic, Error)]
328+
#[error("oops!")]
329+
#[diagnostic(code(oops::my::bad), help("try doing it better next time?"))]
330+
struct MyBad {
331+
#[source_code]
332+
src: NamedSource,
333+
#[label("this bit here")]
334+
highlight: SourceSpan,
335+
}
336+
337+
let src = "source\n text\n here".to_string();
338+
let err = MyBad {
339+
src: NamedSource::new("bad_file.rs", src),
340+
highlight: (6, 0).into(),
341+
};
342+
let out = fmt_report(err.into());
343+
println!("Error: {}", out);
344+
let expected = r#"oops::my::bad
345+
346+
× oops!
347+
╭─[bad_file.rs:1:1]
348+
1 │ source
349+
· ▲
350+
· ╰── this bit here
351+
2 │ text
352+
╰────
353+
help: try doing it better next time?
354+
"#
355+
.trim_start()
356+
.to_string();
357+
assert_eq!(expected, out);
358+
Ok(())
359+
}
360+
293361
#[test]
294362
fn single_line_highlight_with_empty_span() -> Result<(), MietteError> {
295363
#[derive(Debug, Diagnostic, Error)]

0 commit comments

Comments
 (0)
Please sign in to comment.