Skip to content

Commit a8ea273

Browse files
Merge pull request #61 from triblespace/codex/add-kani-harness-for-bytes-verification
Add Kani harness for Bytes owner downcast
2 parents 61ce64e + ba2afee commit a8ea273

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
## Unreleased
4+
- add Kani proof checking `Bytes::downcast_to_owner` for matching and mismatched owners
45
- added Kani verification harnesses for `Bytes::pop_front` and `Bytes::pop_back`
56
- avoid flushing empty memory maps in `Section::freeze` to prevent macOS errors
67
- derived zerocopy traits for `SectionHandle` to allow storing handles in `ByteArea` sections

src/bytes.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,4 +690,32 @@ mod verification {
690690
drop(bytes);
691691
assert!(weak.upgrade().is_none());
692692
}
693+
694+
#[kani::proof]
695+
#[kani::unwind(16)]
696+
pub fn check_downcast_to_owner_preserves_data() {
697+
let data: Vec<u8> = Vec::bounded_any::<16>();
698+
kani::assume(data.len() <= 16);
699+
700+
let bytes = Bytes::from_source(data.clone());
701+
702+
// Invariant: when the owner really is a Vec<u8>, downcasting the Bytes
703+
// owner should succeed and recover the same Arc<Vec<u8>> that backs the
704+
// original allocation. This ensures Bytes keeps the concrete owner
705+
// type intact through cloning and slicing operations.
706+
let arc_vec = bytes
707+
.clone()
708+
.downcast_to_owner::<Vec<u8>>()
709+
.expect("downcast to Vec<u8>");
710+
assert_eq!(&*arc_vec, &data);
711+
712+
// Invariant: attempting to downcast to the wrong owner type must fail
713+
// without mutating the Bytes value. The returned Bytes should still
714+
// expose the same data slice so callers can continue using it.
715+
let result = bytes.downcast_to_owner::<String>();
716+
let Err(returned) = result else {
717+
panic!("downcast to String should fail");
718+
};
719+
assert_eq!(returned.as_ref(), data.as_slice());
720+
}
693721
}

0 commit comments

Comments
 (0)