Skip to content

Commit 6bd8b39

Browse files
authored
Merge pull request #1374 from epage/invalid
fix(cli): Don't panic with invalid utf-8
2 parents b6297a6 + f5e19d3 commit 6bd8b39

File tree

5 files changed

+52
-19
lines changed

5 files changed

+52
-19
lines changed

crates/typos-cli/src/bin/typos-cli/report.rs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use std::borrow::Cow;
44
use std::io::Write as _;
5+
use std::ops::Range;
56
use std::sync::{atomic, Mutex};
67

78
use annotate_snippets::Annotation;
@@ -162,41 +163,64 @@ fn typo_to_group<'t>(msg: &'t Typo<'t>) -> Group<'t> {
162163
let group = match &msg.context {
163164
Some(Context::File(context)) => {
164165
let path = context.path.as_os_str().to_string_lossy();
165-
let line = String::from_utf8_lossy(msg.buffer.as_ref());
166+
let (line, span) = to_string(&msg.buffer, msg.byte_offset, msg.typo.len());
166167
let snippet = Snippet::source(line)
167168
.path(path)
168169
.line_start(context.line_num);
169-
append_corrections(msg, 0, snippet, group)
170+
append_corrections(span, snippet, group)
170171
}
171172
Some(Context::Path(context)) => {
172-
let path = context
173-
.path
174-
.parent()
175-
.unwrap_or(std::path::Path::new("."))
176-
.join("");
177-
let path = path.as_os_str().to_string_lossy();
178-
let line = context.path.as_os_str().to_string_lossy();
173+
let parent = context.path.parent().unwrap_or(std::path::Path::new("."));
174+
let parent = parent.as_os_str().to_string_lossy();
175+
let mut line = parent.into_owned();
176+
line.push(std::path::MAIN_SEPARATOR);
177+
let parent_len = line.len();
178+
let mut line = line.into_bytes();
179+
line.extend(msg.buffer.iter());
180+
let (line, span) = to_string(&line, parent_len + msg.byte_offset, msg.typo.len());
181+
let line = line.into_owned();
179182
let snippet = Snippet::source(line);
180-
append_corrections(msg, path.len(), snippet, group)
183+
append_corrections(span, snippet, group)
181184
}
182185
Some(_) | None => group,
183186
};
184187
group
185188
}
186189

187190
fn append_corrections<'t>(
188-
msg: &'t Typo<'t>,
189-
offset: usize,
191+
span: Range<usize>,
190192
snippet: Snippet<'t, Annotation<'t>>,
191193
group: Group<'t>,
192194
) -> Group<'t> {
193-
let span_start = msg.byte_offset + offset;
194-
let span_end = span_start + msg.typo.len();
195-
let span = span_start..span_end;
196195
let snippet = snippet.annotation(AnnotationKind::Primary.span(span));
197196
group.element(snippet)
198197
}
199198

199+
fn to_string(line: &[u8], start: usize, len: usize) -> (Cow<'_, str>, Range<usize>) {
200+
let end = start + len;
201+
202+
if let Ok(line) = std::str::from_utf8(line) {
203+
return (Cow::Borrowed(line), start..end);
204+
}
205+
206+
let prefix = &line[0..start];
207+
let prefix = String::from_utf8_lossy(prefix);
208+
209+
let middle = &line[start..end];
210+
let middle = String::from_utf8_lossy(middle);
211+
212+
let suffix = &line[end..];
213+
let suffix = String::from_utf8_lossy(suffix);
214+
215+
let span_start = prefix.len();
216+
let span_end = span_start + middle.len();
217+
218+
(
219+
Cow::Owned(format!("{prefix}{middle}{suffix}")),
220+
span_start..span_end,
221+
)
222+
}
223+
200224
fn error_to_group<'e>(error: &'e Error<'e>) -> Group<'e> {
201225
let group = Group::with_title(Level::ERROR.primary_title(&error.msg));
202226
match &error.context {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Not valid UTF-8
2+
3+
vouloir lire la nouvelle page man mais ce qui suit vous aidera assur�ment :
File renamed without changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
bin.name = "typos"
2+
status.code = 2
3+
stdout = """
4+
error: `ment` should be `meant`
5+
╭▸ ./invalid_utf8.txt:3:70
6+
7+
3 │ vouloir lire la nouvelle page man mais ce qui suit vous aidera assur�ment :
8+
╰╴ ━━━━
9+
"""
10+
stderr = ""

crates/typos-cli/tests/cmd/utf16.toml

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)