Add: windows mvp - transparent bugs not fixed

This commit is contained in:
DaZuo0122
2026-02-12 22:58:33 +08:00
commit 61825f647d
147 changed files with 28498 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
---
id: safety-03
original_id: P.UNS.SAS.03
level: P
impact: CRITICAL
clippy: uninit_assumed_init
---
# Do Not Expose Uninitialized Memory in Public APIs
## Summary
Public APIs must never return or expose uninitialized memory to callers.
## Rationale
Reading uninitialized memory is undefined behavior in Rust. Safe code should never be able to access uninitialized memory through your API.
## Bad Example
```rust
// DON'T: Expose uninitialized memory
pub struct Buffer {
data: [u8; 1024],
len: usize,
}
impl Buffer {
pub fn new() -> Self {
// BAD: data is uninitialized
unsafe {
Self {
data: std::mem::MaybeUninit::uninit().assume_init(),
len: 0,
}
}
}
// BAD: Returns reference to potentially uninitialized data
pub fn as_slice(&self) -> &[u8] {
&self.data[..self.len] // What if len > initialized portion?
}
}
```
## Good Example
```rust
use std::mem::MaybeUninit;
// DO: Use MaybeUninit properly and only expose initialized data
pub struct Buffer {
data: Box<[MaybeUninit<u8>; 1024]>,
len: usize, // Invariant: data[0..len] is initialized
}
impl Buffer {
pub fn new() -> Self {
Self {
// MaybeUninit doesn't require initialization
data: Box::new([MaybeUninit::uninit(); 1024]),
len: 0,
}
}
pub fn push(&mut self, byte: u8) {
if self.len < 1024 {
self.data[self.len].write(byte);
self.len += 1;
}
}
// Only returns initialized portion
pub fn as_slice(&self) -> &[u8] {
// SAFETY: self.len bytes are initialized (invariant)
unsafe {
std::slice::from_raw_parts(
self.data.as_ptr() as *const u8,
self.len
)
}
}
}
impl Drop for Buffer {
fn drop(&mut self) {
// Only drop initialized elements
// For u8 this is a no-op, but important for Drop types
}
}
```
## Patterns for Uninitialized Memory
```rust
// Pattern 1: MaybeUninit for delayed initialization
let mut value: MaybeUninit<ExpensiveType> = MaybeUninit::uninit();
initialize_expensive(&mut value);
let value = unsafe { value.assume_init() };
// Pattern 2: Vec::with_capacity for growable buffers
let mut vec = Vec::with_capacity(100);
// vec.len() is 0, capacity is 100
// No uninitialized memory is accessible
// Pattern 3: Box::new_uninit (nightly)
let mut boxed = Box::<[u8; 1024]>::new_uninit();
boxed.write([0u8; 1024]);
let boxed = unsafe { boxed.assume_init() };
```
## Checklist
- [ ] Does my API ever return references to uninitialized memory?
- [ ] Are length/capacity invariants properly maintained?
- [ ] Is MaybeUninit used instead of transmute for uninitialized data?
## Related Rules
- `mem-06`: Use MaybeUninit<T> for uninitialized memory
- `safety-01`: Panic safety with partial initialization