# safe-read
[](https://crates.io/crates/safe-read)
[](https://docs.rs/safe-read)
[](LICENSE)
**Fuzzed, panic-free-by-construction bounded integer readers over untrusted byte slices** — the shared front door for every offset/length field parsed from an attacker-controllable forensic image, so each reader crate stops re-deriving its own bounds-checked helpers.
```rust
use safe_read::{le_u32, be_u16, le_i32, try_bytes};
// In range → the value; out of range → 0, never a panic.
assert_eq!(le_u32(&[0x78, 0x56, 0x34, 0x12], 0), 0x1234_5678);
assert_eq!(le_u32(&[1, 2, 3], 0), 0); // too short
assert_eq!(be_u16(&[1, 2, 3, 4], usize::MAX), 0); // offset overflow
// Signed fields come back signed, not as their huge unsigned twin.
assert_eq!(le_i32(&[0xff, 0xff, 0xff, 0xff], 0), -1);
// Fixed-width byte windows — GUIDs, signatures, digests.
assert_eq!(try_bytes::<2>(&[0xaa, 0xbb, 0xcc], 1), Some([0xbb, 0xcc]));
```
`be_u16`/`be_u32`/`be_u64`, `le_u16`/`le_u32`/`le_u64` and their signed twins `be_i16`/`be_i32`/`be_i64`, `le_i16`/`le_i32`/`le_i64` each read a fixed-width integer at a byte offset, returning `0` when the window is out of range — too short, offset past EOF, or `off + width` overflowing `usize`. `try_bytes::<N>` copies out an `N`-byte window under the same rule, returning `None` instead. Every reader has a `try_` twin returning `None`, for the callers that must tell a genuine `0` from an absent field. `#![no_std]`, no dependencies, no `unsafe`.
## Install
```toml
[dependencies]
safe-read = "0.3"
```
---
[Privacy Policy](https://securityronin.github.io/safe-read/privacy/) · [Terms of Service](https://securityronin.github.io/safe-read/terms/) · © 2026 Security Ronin Ltd