Skip to content

Commit

Permalink
B4 fix: fixing by adding max index computation in bitfield validation (
Browse files Browse the repository at this point in the history
  • Loading branch information
laudiacay authored Jan 18, 2022
1 parent 250e27a commit 6a8b2de
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 6 deletions.
9 changes: 9 additions & 0 deletions utils/bitfield/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ impl BitField {
.find(|i| !self.unset.contains(i))
}

/// Returns the index of the highest bit present in the bit field.
/// Errors if no bits are set. Merges set/unset into ranges, so be cautious with use if set is pretty populated
pub fn last(&self) -> Result<usize> {
self.ranges()
.last()
.map(|r| r.end - 1)
.ok_or("no last bit set")
}

/// Returns an iterator over the indices of the bit field's set bits.
pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
// this code results in the same values as `self.ranges().flatten()`, but there's
Expand Down
38 changes: 38 additions & 0 deletions utils/bitfield/src/rleplus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,4 +382,42 @@ mod tests {
assert_eq!(bf.ranges().collect::<Vec<_>>(), ranges);
}
}

// auditor says this:
// I used the ntest package to add a 60 sec timeout
// to the test, as it would otherwise not complete.
// may consider doing this eventually
//#[timeout(60000)]
#[test]
fn iter_last() {
// Create RLE with 2**64-2 set bits- tests timeout on the `let max` line with last
let rle: Vec<u8> = vec![
0xE4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
];
let max = BitField::from_bytes(&rle).unwrap().last().unwrap();
assert_eq!(max, 18446744073709551614);
}

#[test]
fn test_unset_last() {
// Create a bitfield first 3 set bits
let ranges: Vec<usize> = vec![0, 1, 2, 3];
let iter = ranges_from_bits(ranges.clone());
let mut bf = BitField::from_ranges(iter);
// Unset bit at pos 3
bf.unset(3);

let last = bf.last().unwrap();
assert_eq!(2, last);
}

#[test]
fn test_zero_last() {
let mut bf = BitField::new();
bf.set(0);

let last = bf.last().unwrap();
assert_eq!(0, last);
}
}
14 changes: 8 additions & 6 deletions vm/actor/src/builtin/miner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2508,14 +2508,16 @@ impl Actor {
.validate()
.map_err(|e| actor_error!(ErrIllegalArgument, "invalid mask bitfield: {}", e))?;

let last_sector_number = mask_sector_numbers
.iter()
.last()
.ok_or_else(|| actor_error!(ErrIllegalArgument, "invalid mask bitfield"))?
as SectorNumber;
let last_sector_number = mask_sector_numbers.last().map_err(|e| {
actor_error!(
ErrIllegalArgument,
"invalid mask bitfield, no sectors set: {}",
e
)
})?;

#[allow(clippy::absurd_extreme_comparisons)]
if last_sector_number > MAX_SECTOR_NUMBER {
if (last_sector_number as u64) > MAX_SECTOR_NUMBER {
return Err(actor_error!(
ErrIllegalArgument,
"masked sector number {} exceeded max sector number",
Expand Down

0 comments on commit 6a8b2de

Please sign in to comment.