From cc516d54037a2f98785dc8cc77d6e6a6201502c3 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Tue, 25 Oct 2022 21:54:11 +0200 Subject: [PATCH] fix: panic when comparing ropes with chunks not aligned at char bounds --- src/slice.rs | 14 ++++--- tests/non_ascii.txt | 77 +++++++++++++++++++++++++++++++++++ tests/non_ascii_comparison.rs | 38 +++++++++++++++++ 3 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 tests/non_ascii.txt create mode 100644 tests/non_ascii_comparison.rs diff --git a/src/slice.rs b/src/slice.rs index bb45c840..c6ce387b 100644 --- a/src/slice.rs +++ b/src/slice.rs @@ -1776,8 +1776,8 @@ impl<'a, 'b> std::cmp::PartialEq> 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() { @@ -1785,18 +1785,18 @@ impl<'a, 'b> std::cmp::PartialEq> for RopeSlice<'a> { 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; } @@ -1804,7 +1804,7 @@ impl<'a, 'b> std::cmp::PartialEq> for RopeSlice<'a> { if chunk2.is_empty() { if let Some(chunk) = chunk_itr_2.next() { - chunk2 = chunk; + chunk2 = chunk.as_bytes(); } else { break; } @@ -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; } diff --git a/tests/non_ascii.txt b/tests/non_ascii.txt new file mode 100644 index 00000000..2059cecb --- /dev/null +++ b/tests/non_ascii.txt @@ -0,0 +1,77 @@ +_____________ + +______________ㅇ_________ㅇㅇㅇ____ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ__________ +________________ +_____________________________________________ +____________________________________________ +_______________ +_____________________________________ +____________________________________________________________________ +______________________ +________________________ +_________________________________________________ +______________________________________________________________ +____________________ +______________________________________________ +_________________ +________________ + +__________________________________________________________ +____________________________________________________ +_______________ + +________________________________________________ +______________________ +________________________ +________________________________________________________________________ +______________________________ +____________________ +__________________________________________ +__________________ +____________________________________________ +________________ + +__________________ +_____________________ +_____________________________________________________ +____________________________________________ +_________________ +___________________________________________ +__________________________________________ +___________________________________________________ +___________________________________________________________________ +_______________________ +_______________ +_____________ + +______________ㅇㅇㅇㅇㅇㅇ____ㅇ_ㅇㅇㅇ____ +______________ㅇㅇㅇㅇ_____________ㅇㅇㅇㅇㅇㅇㅇㅇ____ +____________________________________ +________________________________________________________________________________ +______________________________________ +______________ + +______________ㅇㅇㅇㅇ_______ㅇㅇㅇㅇㅇㅇ_______ㅇㅇ_____________ㅇㅇㅇㅇㅇ____ +________________________________ +__________________________________________________________________ +_________________________ +______________ + +__________________________________________________________________ +_______________________________________________ + +______________________________________ +________________________________________________ + +_______________________________________________ +__________________________________________________________________ +___________ +_________ +_______________________ +________________________________________________ +_______ +______ + +________________________________ +_______________________________________ +______ diff --git a/tests/non_ascii_comparison.rs b/tests/non_ascii_comparison.rs new file mode 100644 index 00000000..1a7cadf4 --- /dev/null +++ b/tests/non_ascii_comparison.rs @@ -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)); + } + } +}