mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
uniq: Fix skip fields
Current implementation of the skip fields logic does not handle multibyte code points correctly. It assumes each code point (`char`) is one byte. If the skipped part of the input line has any multibyte code points then this can cause fields not being skipped correctly (field start index is calculated to be before it actually starts).
This commit is contained in:
+11
-14
@@ -79,22 +79,19 @@ impl Uniq {
|
||||
|
||||
fn skip_fields<'a>(&self, line: &'a str) -> &'a str {
|
||||
if let Some(skip_fields) = self.skip_fields {
|
||||
if line.split_whitespace().count() > skip_fields {
|
||||
let mut field = 0;
|
||||
let mut i = 0;
|
||||
while field < skip_fields && i < line.len() {
|
||||
while i < line.len() && line.chars().nth(i).unwrap().is_whitespace() {
|
||||
i += 1;
|
||||
}
|
||||
while i < line.len() && !line.chars().nth(i).unwrap().is_whitespace() {
|
||||
i += 1;
|
||||
}
|
||||
field += 1;
|
||||
let mut i = 0;
|
||||
let mut char_indices = line.char_indices();
|
||||
for _ in 0..skip_fields {
|
||||
if char_indices.find(|(_, c)| !c.is_whitespace()) == None {
|
||||
return "";
|
||||
}
|
||||
match char_indices.find(|(_, c)| c.is_whitespace()) {
|
||||
None => return "",
|
||||
|
||||
Some((next_field_i, _)) => i = next_field_i,
|
||||
}
|
||||
&line[i..]
|
||||
} else {
|
||||
""
|
||||
}
|
||||
&line[i..]
|
||||
} else {
|
||||
line
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
aaa aa a
|
||||
aaa ⟪⟫ a
|
||||
aa a
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
aaa aa a
|
||||
aaa ⟪⟫ a
|
||||
ZZZ aa a
|
||||
ZZZ aa a
|
||||
ZZZ bb a
|
||||
|
||||
Reference in New Issue
Block a user