Skip to content

Commit

Permalink
Backport ferrilab#114 to 0.20.3
Browse files Browse the repository at this point in the history
  • Loading branch information
myrrlyn committed Apr 23, 2021
1 parent 249c8b5 commit f6f5d65
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 8 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All notable changes will be documented in this file.

This document is written according to the [Keep a Changelog][kac] style.

1. [0.20.3](#0203)
1. [0.20.2](#0202)
1. [0.20.1](#0201)
1. [0.20.0](#0200)
Expand Down Expand Up @@ -59,6 +60,10 @@ This document is written according to the [Keep a Changelog][kac] style.
1. [0.2.0](#020)
1. [0.1.0](#010)

## 0.20.3

Backports [#114].

## 0.20.2

Fixed overly vague `funty` dependency, as the `1.2` release moved `BITS` from
Expand Down Expand Up @@ -1129,6 +1134,7 @@ Initial implementation and release.
[@Fotosmile]: https://github.com/Fotosmile
[@GeorgeGkas]: https://github.com/GeorgeGkas
[@ImmemorConsultrixContrarie]: https://github.com/ImmemorConsultrixContrarie
[@VilleHallivuori]: https://github.com/VilleHallivuori
[@arucil]: https://github.com/arucil
[@caelunshun]: https://github.com/caelunshun
[@geq1t]: https://github.com/geq1t
Expand Down Expand Up @@ -1163,6 +1169,7 @@ Initial implementation and release.
[Issue #69]: https://github.com/myrrlyn/bitvec/issues/69
[Issue #75]: https://github.com/myrrlyn/bitvec/issues/75
[Issue #83]: https://github.com/myrrlyn/bitvec/issues/83
[Issue #114]: https://github.com/myrrlyn/bitvec/issues/114
[Pull Request #34]: https://github.com/myrrlyn/bitvec/pull/34
[Pull Request #41]: https://github.com/myrrlyn/bitvec/pull/41
[Pull Request #68]: https://github.com/myrrlyn/bitvec/pull/68
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

[package]
name = "bitvec"
version = "0.20.2"
version = "0.20.3"
authors = [
"myrrlyn <self@myrrlyn.dev>",
]
Expand Down
14 changes: 8 additions & 6 deletions src/slice/specialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ where T: BitStore
pub(crate) fn sp_iter_ones_last(&self) -> Option<usize> {
let mut out = match self.len() {
0 => return None,
n => n - 1,
n => n,
};
match self.domain() {
(|| match self.domain() {
Domain::Enclave { head, elem, tail } => {
let val = (Lsb0::mask(head, tail) & elem.load_value()).value();
let dead_bits = T::Mem::BITS - tail.value();
Expand Down Expand Up @@ -213,7 +213,8 @@ where T: BitStore

None
},
}
})()
.map(|idx| idx - 1)
}

/// Seeks the index of the first `0` bit in the bit-slice.
Expand Down Expand Up @@ -267,9 +268,9 @@ where T: BitStore
pub(crate) fn sp_iter_zeros_last(&self) -> Option<usize> {
let mut out = match self.len() {
0 => return None,
n => n - 1,
n => n,
};
match self.domain() {
(|| match self.domain() {
Domain::Enclave { head, elem, tail } => {
let val = (Lsb0::mask(head, tail) & !elem.load_value()).value();
let dead_bits = T::Mem::BITS - tail.value();
Expand Down Expand Up @@ -310,7 +311,8 @@ where T: BitStore

None
},
}
})()
.map(|idx| idx - 1)
}
}

Expand Down
48 changes: 47 additions & 1 deletion tests/issues.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Test cases for defect reports.
#[cfg(feature = "alloc")]
#![allow(clippy::unusual_byte_groupings)]

use bitvec::prelude::*;

/** Test case for [Issue #10], opened by [@overminder].
Expand Down Expand Up @@ -271,3 +272,48 @@ fn issue_77() {
// are all `false`!!!
assert_eq!(&[&true; N], last_few.as_slice());
}

/** Test case for [Issue #114], opened by [@VilleHallivuori].
This report describes an overflowing-subtraction error encountered when
attempting to find the last index of an un/set bit in a bit-slice that does not
have any.
This is not a surprising crash: the reverse gallop by indices through a slice is
a cumbersome operation that is fraught with potential for failure, thanks to the
half-open nature of indices within a length.
The fix turned out to be incredibly simple: defer the derement operation (to go
from len to last valid index) from the *start* of the search to the *end*.
I am not confident in the categorical correctness of this solution, but it fixes
the provided test cases and does not break the existing tests.
I will need to devise test cases that thoroughly check all possible branches of
the galloping searches, but for now, this is an improvement over the existing
behavior, so I am going to call it sufficient for the bug as reported, publish
patches, and await further reports.
[Issue #114]: https://github.com/bitvecto-rs/bitvec/issues/114
[@VilleHallivuori]: https://github.com/VilleHallivuori
**/
#[test]
fn issue_114() {
let one_zero = bits![0];
let one_one = bits![1];

assert_eq!(one_zero.count_zeros(), 1);
assert_eq!(one_zero.count_ones(), 0);
assert_eq!(one_one.count_zeros(), 0);
assert_eq!(one_one.count_ones(), 1);

assert!(one_zero.first_one().is_none());
assert!(one_zero.last_one().is_none());
assert!(one_one.first_zero().is_none());
assert!(one_one.last_zero().is_none());

assert_eq!(one_zero.first_zero(), Some(0));
assert_eq!(one_zero.last_zero(), Some(0));
assert_eq!(one_one.first_one(), Some(0));
assert_eq!(one_one.last_one(), Some(0));
}

0 comments on commit f6f5d65

Please sign in to comment.