Skip to content

Commit

Permalink
Fixed overflow bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Veedrac committed Dec 1, 2020
1 parent b4452f1 commit 491d8db
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/simd/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ pub fn chunk_count(haystack: &[u8], needle: u8) -> usize {
for i in 0..(haystack.len() - offset) / 32 {
counts -= u8x32::from_cast(u8x32_from_offset(haystack, offset + i * 32).eq(needles_x32));
}
count += sum_x32(&counts);

// Straggler; need to reset counts because prior loop can run 255 times
counts = u8x32::splat(0);
if haystack.len() % 32 != 0 {
counts -= u8x32::from_cast(u8x32_from_offset(haystack, haystack.len() - 32).eq(needles_x32)) &
u8x32_from_offset(&MASK, haystack.len() % 32);
Expand Down Expand Up @@ -118,6 +122,10 @@ pub fn chunk_num_chars(utf8_chars: &[u8]) -> usize {
for i in 0..(utf8_chars.len() - offset) / 32 {
counts -= is_leading_utf8_byte_x32(u8x32_from_offset(utf8_chars, offset + i * 32));
}
count += sum_x32(&counts);

// Straggler; need to reset counts because prior loop can run 255 times
counts = u8x32::splat(0);
if utf8_chars.len() % 32 != 0 {
counts -= is_leading_utf8_byte_x32(u8x32_from_offset(utf8_chars, utf8_chars.len() - 32)) &
u8x32_from_offset(&MASK, utf8_chars.len() % 32);
Expand Down
18 changes: 18 additions & 0 deletions tests/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ fn check_count_overflow() {
assert_eq!(count(&haystack, needle), naive_count(&haystack, needle));
}

#[test]
fn check_count_overflow_many() {
let string = [b'x'; 20000];
for i in 0..20000 {
assert_eq!(count(&string[..i], b'x'), i);
}
}



quickcheck! {
fn check_num_chars_correct(haystack: Vec<u8>) -> bool {
num_chars(&haystack) == naive_num_chars(&haystack)
Expand All @@ -75,3 +85,11 @@ fn check_num_chars_overflow() {
let haystack = vec![0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
assert_eq!(num_chars(&haystack), naive_num_chars(&haystack));
}

#[test]
fn check_num_chars_overflow_many() {
let string = [b'x'; 20000];
for i in 0..20000 {
assert_eq!(num_chars(&string[..i]), i);
}
}

0 comments on commit 491d8db

Please sign in to comment.