Skip to content

Commit

Permalink
fix: panic when comparing ropes with chunks not aligned at char bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalkuthe committed Oct 27, 2022
1 parent 594adfa commit cc516d5
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1776,35 +1776,35 @@ impl<'a, 'b> std::cmp::PartialEq<RopeSlice<'b>> for RopeSlice<'a> {

let mut chunk_itr_1 = self.chunks();
let mut chunk_itr_2 = other.chunks();
let mut chunk1 = chunk_itr_1.next().unwrap_or("");
let mut chunk2 = chunk_itr_2.next().unwrap_or("");
let mut chunk1 = chunk_itr_1.next().unwrap_or("").as_bytes();
let mut chunk2 = chunk_itr_2.next().unwrap_or("").as_bytes();

loop {
if chunk1.len() > chunk2.len() {
if &chunk1[..chunk2.len()] != chunk2 {
return false;
} else {
chunk1 = &chunk1[chunk2.len()..];
chunk2 = "";
chunk2 = &[];
}
} else if &chunk2[..chunk1.len()] != chunk1 {
return false;
} else {
chunk2 = &chunk2[chunk1.len()..];
chunk1 = "";
chunk1 = &[];
}

if chunk1.is_empty() {
if let Some(chunk) = chunk_itr_1.next() {
chunk1 = chunk;
chunk1 = chunk.as_bytes();
} else {
break;
}
}

if chunk2.is_empty() {
if let Some(chunk) = chunk_itr_2.next() {
chunk2 = chunk;
chunk2 = chunk.as_bytes();
} else {
break;
}
Expand All @@ -1823,9 +1823,11 @@ impl<'a, 'b> std::cmp::PartialEq<&'b str> for RopeSlice<'a> {
if self.len_bytes() != other.len() {
return false;
}
let other = other.as_bytes();

let mut idx = 0;
for chunk in self.chunks() {
let chunk = chunk.as_bytes();
if chunk != &other[idx..(idx + chunk.len())] {
return false;
}
Expand Down
77 changes: 77 additions & 0 deletions tests/non_ascii.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
_____________

______________ㅇ_________ㅇㅇㅇ____ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ__________
________________
_____________________________________________
____________________________________________
_______________
_____________________________________
____________________________________________________________________
______________________
________________________
_________________________________________________
______________________________________________________________
____________________
______________________________________________
_________________
________________

__________________________________________________________
____________________________________________________
_______________

________________________________________________
______________________
________________________
________________________________________________________________________
______________________________
____________________
__________________________________________
__________________
____________________________________________
________________

__________________
_____________________
_____________________________________________________
____________________________________________
_________________
___________________________________________
__________________________________________
___________________________________________________
___________________________________________________________________
_______________________
_______________
_____________

______________ㅇㅇㅇㅇㅇㅇ____ㅇ_ㅇㅇㅇ____
______________ㅇㅇㅇㅇ_____________ㅇㅇㅇㅇㅇㅇㅇㅇ____
____________________________________
________________________________________________________________________________
______________________________________
______________

______________ㅇㅇㅇㅇ_______ㅇㅇㅇㅇㅇㅇ_______ㅇㅇ_____________ㅇㅇㅇㅇㅇ____
________________________________
__________________________________________________________________
_________________________
______________

__________________________________________________________________
_______________________________________________

______________________________________
________________________________________________

_______________________________________________
__________________________________________________________________
___________
_________
_______________________
________________________________________________
_______
______

________________________________
_______________________________________
______
38 changes: 38 additions & 0 deletions tests/non_ascii_comparison.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
extern crate ropey;

use ropey::Rope;

const TEXT1: &str = include_str!("non_ascii.txt");

#[test]
#[allow(clippy::cmp_owned)]
#[cfg_attr(miri, ignore)]
fn non_ascii_eq() {
// Build rope from file contents
let rope1 = Rope::from_str(TEXT1);

let mut rope2 = Rope::from_str(TEXT1);
rope2.remove(1467..1827);
for line1 in rope1.lines() {
for line2 in rope2.lines() {
println!("lines1: {line1} line2: {line2}");
println!("{}", line1.to_string() == line2);
println!("{}", line1 == line2);
}
}
}

#[test]
fn non_ascii_ord() {
// Build rope from file contents
let rope1 = Rope::from_str(TEXT1);

let mut rope2 = Rope::from_str(TEXT1);
rope2.remove(1467..1827);
for line1 in rope1.lines() {
for line2 in rope2.lines() {
println!("lines1: {line1} line2: {line2}");
println!("{:?}", line2.partial_cmp(&line1));
}
}
}

0 comments on commit cc516d5

Please sign in to comment.