Skip to content

Commit

Permalink
fix(cli): Don't panic when finding column
Browse files Browse the repository at this point in the history
When rendering typos, we look up what visual column the typoe starts on
but I mixed a raw byte offset with the offset into a lossy string.  This
caused panics when dealing with non-ascii content.

Fixes #258
  • Loading branch information
Ed Page committed May 28, 2021
1 parent b4e198a commit 9859e60
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
<!-- next-header -->
## [Unreleased] - ReleaseDate

#### Bug Fixes

- Don't panic when rendering typos on lines with non-ASCII character

## [1.0.1] - 2021-05-27

#### Bug Fixes
Expand Down
7 changes: 2 additions & 5 deletions src/bin/typos-cli/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,8 @@ fn print_long_correction(msg: &Typo, palette: Palette) -> Result<(), std::io::Er

let line = String::from_utf8_lossy(msg.buffer.as_ref());
let line = line.replace("\t", " ");
let column = unicode_segmentation::UnicodeSegmentation::graphemes(
line.get(0..msg.byte_offset).unwrap(),
true,
)
.count();
let start = String::from_utf8_lossy(&msg.buffer[0..msg.byte_offset]);
let column = unicode_segmentation::UnicodeSegmentation::graphemes(start.as_ref(), true).count();
match &msg.corrections {
typos::Status::Valid => {}
typos::Status::Invalid => {
Expand Down
62 changes: 52 additions & 10 deletions src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,36 +702,78 @@ mod test {

#[test]
fn test_extract_line_single_line() {
let (line, offset) = extract_line(b"hello world", 6);
assert_eq!(line, b"hello world");
let buffer = b"hello world";
let buffer_offset = 6;
let expected_line = b"hello world";
let (line, offset) = extract_line(buffer, buffer_offset);
assert_eq!(line, expected_line);
assert_eq!(offset, 6);
assert_eq!(line[offset], buffer[buffer_offset]);
}

#[test]
fn test_extract_line_first() {
let (line, offset) = extract_line(b"1\n2\n3", 0);
assert_eq!(line, b"1");
let buffer = b"1\n2\n3";
let buffer_offset = 0;
let expected_line = b"1";
let (line, offset) = extract_line(buffer, buffer_offset);
assert_eq!(line, expected_line);
assert_eq!(offset, 0);
assert_eq!(line[offset], buffer[buffer_offset]);
}

#[test]
fn test_extract_line_middle() {
let (line, offset) = extract_line(b"1\n2\n3", 2);
assert_eq!(line, b"2");
let buffer = b"1\n2\n3";
let buffer_offset = 2;
let expected_line = b"2";
let (line, offset) = extract_line(buffer, buffer_offset);
assert_eq!(line, expected_line);
assert_eq!(offset, 0);
assert_eq!(line[offset], buffer[buffer_offset]);
}

#[test]
fn test_extract_line_end() {
let (line, offset) = extract_line(b"1\n2\n3", 4);
assert_eq!(line, b"3");
let buffer = b"1\n2\n3";
let buffer_offset = 4;
let expected_line = b"3";
let (line, offset) = extract_line(buffer, buffer_offset);
assert_eq!(line, expected_line);
assert_eq!(offset, 0);
assert_eq!(line[offset], buffer[buffer_offset]);
}

#[test]
fn test_extract_line_offset_change() {
let (line, offset) = extract_line(b"1\nhello world\n2", 8);
assert_eq!(line, b"hello world");
let buffer = b"1\nhello world\n2";
let buffer_offset = 8;
let expected_line = b"hello world";
let (line, offset) = extract_line(buffer, buffer_offset);
assert_eq!(line, expected_line);
assert_eq!(offset, 6);
assert_eq!(line[offset], buffer[buffer_offset]);
}

#[test]
fn test_extract_line_windows() {
let buffer = b"1\r\nhello world\r\n2";
let buffer_offset = 9;
let expected_line = b"hello world";
let (line, offset) = extract_line(buffer, buffer_offset);
assert_eq!(line, expected_line);
assert_eq!(offset, 6);
assert_eq!(line[offset], buffer[buffer_offset]);
}

#[test]
fn test_extract_line_slovak() {
let buffer = b"LastErrorMessage=%1.%n%nChyba %2: %3\r\nSetupFileMissing=In\x9Atala\xE8n\xFD adres\xE1r neobsahuje s\xFAbor %1. Opravte, pros\xEDm, t\xFAto chybu alebo si zaobstarajte nov\xFA k\xF3piu tohto produktu.\r\nSetupFileCorrupt=S\xFAbory sprievodcu in\x9Atal\xE1ciou s\xFA po\x9Akoden\xE9. Zaobstarajte si, pros\xEDm, nov\xFA k\xF3piu tohto produktu.";
let buffer_offset = 66;
let expected_line = b"SetupFileMissing=In\x9Atala\xE8n\xFD adres\xE1r neobsahuje s\xFAbor %1. Opravte, pros\xEDm, t\xFAto chybu alebo si zaobstarajte nov\xFA k\xF3piu tohto produktu.";
let (line, offset) = extract_line(buffer, buffer_offset);
assert_eq!(line, expected_line);
assert_eq!(offset, 28);
assert_eq!(line[offset], buffer[buffer_offset]);
}
}

0 comments on commit 9859e60

Please sign in to comment.