Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix panic when comparing ropes with chunks that do not align at char bounds #65

Merged
merged 1 commit into from
Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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));
}
}
}