use core::ptr::NonNull;
struct FakeCtx {
counter: u64,
last_op: u8,
}
unsafe fn fake_ssl_handshake(ctx: *mut FakeCtx) -> i32 {
(*ctx).counter += 1;
(*ctx).last_op = 1;
0
}
unsafe fn fake_ssl_read(ctx: *mut FakeCtx) -> i32 {
(*ctx).counter += 1;
(*ctx).last_op = 2;
0
}
unsafe fn fake_ssl_write(ctx: *mut FakeCtx) -> i32 {
(*ctx).counter += 1;
(*ctx).last_op = 3;
0
}
struct Owner {
ctx: FakeCtx,
}
impl Owner {
fn as_mut_ptr(&mut self) -> *mut FakeCtx {
&mut self.ctx as *mut FakeCtx
}
}
struct ReadHalf {
ctx: NonNull<FakeCtx>,
}
struct WriteHalf {
ctx: NonNull<FakeCtx>,
}
impl ReadHalf {
fn read(&mut self) -> i32 {
unsafe { fake_ssl_read(self.ctx.as_ptr()) }
}
}
impl WriteHalf {
fn write(&mut self) -> i32 {
unsafe { fake_ssl_write(self.ctx.as_ptr()) }
}
}
#[test]
fn write_through_unique_provenance_pointer_is_sound() {
let mut owner = Owner {
ctx: FakeCtx {
counter: 0,
last_op: 0,
},
};
let ctx = unsafe { NonNull::new_unchecked(owner.as_mut_ptr()) };
let mut read = ReadHalf { ctx };
let mut write = WriteHalf { ctx };
unsafe { fake_ssl_handshake(ctx.as_ptr()) };
assert_eq!(read.read(), 0);
assert_eq!(write.write(), 0);
assert_eq!(owner.ctx.counter, 3);
assert_eq!(owner.ctx.last_op, 3);
}