Categories
Tags
algorithms APIT Arc arm assembly asynchronous base64 BitHacks Blogging box c clang-format client cmake compiler concat concurrency const_fn contravariant cos covariant cpp Customization cybersecurity DataStructure db debugging Demo deserialization discrete doc DP dtruss Dynamic Example FFI flat_map format FP fsanitize Functional functions futures Fuwari GATs gccrs generics gitignore glibc GUI hacking hashmap haskell heap interop invariant iterator join justfile kernel LaTeX leak LFU linux lto MachineLearning macOS Markdown math ML mmap nc OnceLock optimization OS panic parallels perf physics pin postgresql radare2 release reverse RPIT rust sanitizer science Science serialization server shift sin SmallProjects socket std strace String StringView strip strlen surrealdb SWAR swisstable synchronous tan toml traits triangulation UnsafeRust utf16 utf8 Video wsl x86_64 xilem zig
661 words
3 minutes
prevent_Crashes_Overflow_UB_Invalid_memory_access
link
These patterns prevent crashes, overflow, UB, or invalid memory access.
- In systems programming (C, C++, Rust, Zig, kernel code, compilers, parsers, allocators, etc.), there are several very common defensive patterns like
0. Your pattern in context
- Your code uses these patterns:
| pattern | where |
|---|---|
| clamp | min(count) |
| pointer + len | StringView |
| check before move | chop_left |
| check before subtract | chop_right |
| slice instead pointer | Rust version |
| defensive programming | whole code |
- This is exactly the style used in:
- Zig std
- Rust std
- LLVM
- Linux kernel
- SQLite
- Redis
- game engines
00. Core rule of systems programming
- Most common rules:
never trust input
never exceed length
never underflow
never overflow
never move pointer blindly
always clamp
always check- These patterns appear everywhere in low-level code.
절대 신뢰할 수 없는 입력
길이를 초과하지 않음
절대로 흐르지 않음
절대 넘치지 않음
포인터를 맹목적으로 움직이지 않기
항상 클램프
항상 확인- clamp
- In computer science, clamping, or clipping is the process of limiting a value to a range between a minimum and a maximum value. Unlike wrapping, Clamping moves a value to the nearest boundary if it is outside the allowed range.
- 컴퓨터 과학에서 클램핑 또는 클리핑은 값을 최소 값과 최대 값 사이의 범위로 제한하는 프로세스입니다. 래핑과 달리 클램핑은 허용 범위를 벗어난 경우 값을 가장 가까운 경계로 이동합니다.
- https://en.wikipedia.org/wiki/Clamp_(function)
1. Clamp pattern (min / max)
- Pattern
// main.c
if (n > len)
n = len;- Rust:
let n = n.min(len);- Meaning:
Never exceed bounds
Used in:
- string slicing
- buffer writing
- reading files
- network packets
- parsers
Example:
fn read(buf: &mut [u8], n: usize) {
let n = n.min(buf.len());
}2. Clamp to range (min + max)
- Pattern:
// main.rs
x = x.clamp(min, max);- Same as:
// main.c
if (x < min) x = min;
if (x > max) x = max;- Example:
// main.rs
let volume = volume.clamp(0, 100);- Used in:
- graphics
- audio
- physics
- UI
- game engines
3. Check before pointer move
- Very common in C.
// main.c
if (ptr + n <= end)
ptr += n;- Rust equivalent:
// main.rs
if n <= slice.len() {
slice = &slice[n..];
}- Meaning:
Never move pointer past end
- Used in:
- parsers
- lexers
- binary readers
- networking
4. Length + pointer pair pattern
- Used in your example.
pointer + length- C:
// main.c
char *data;
size_t len;- Rust:
&[u8]
&strUsed in:
- string_view
- slices
- buffers
- kernel code
- compilers
Example:
struct View<'a> {
data: &'a [u8],
len: usize,
}5. Check before subtract
- Pattern:
// main.c
if (n > len)
n = len;
len -= n;// main.rs
let n = n.min(len);
len -= n;- Meaning:
Never underflow
- Why?
- Because unsigned:
// main.c
size_t len = 5;
len -= 10; - Result:
huge number (underflow)Very dangerous.
Used in:
- allocators
- containers
- string_view
- ring buffers
6. Null / empty check pattern
- C:
// main.c
if (ptr == NULL)
return;- Rust
if slice.is_empty() {
return;
}- Meaning:
Handle empty case first
- Used everywhere.
7. Early return pattern
- Very common in kernel / Rust / C.
// main.rs
if n == 0 {
return;
}- or
// main.c
if (!ptr)
return;- Meaning:
Exit early to keep code safe
- Used in:
- OS kernels
- drivers
- parsers
- allocators
8. Saturating arithmetic pattern
- Rust:
// main.rs
x = x.saturating_add(y);
x = x.saturating_sub(y);- Meaning:
Never overflow
- Example:
// main.rs
let x: u8 = 250;
let y = x.saturating_add(10); // 255, not overflowUsed in:
- embedded
- kernel
- graphics
- DSP
C equivalent:
// main.c
if (x > MAX - y)
x = MAX;
else
x += y;9. Checked arithmetic pattern
- Rust:
// main.rs
x.checked_add(y)Returns Option.
Used when overflow must be detected.
Example:
// main.rs
if let Some(v) = x.checked_add(y) {
x = v;
}- Used in:
- crypto
- big integers
- parsers
- compilers
10. Slice instead of pointer math (Rust pattern)
- C:
// main.c
ptr += n;
len -= n;- Rust:
// main.rs
slice = &slice[n..];Safer.
Used everywhere in Rust std.
11. Defensive copy length pattern
- C:
// main.c
memcpy(dst, src, min(dst_size, src_size));- Rust:
// main.rs
let n = dst.len().min(src.len());
dst[..n].copy_from_slice(&src[..n]);- Used in:
- networking
- kernel
- file IO
- serialization
12. Bounds check before index
- C:
// main.c
if (i < len)
x = arr[i];- Rust:
// main.rs
if let Some(x) = arr.get(i) {
}- Used everywhere.
13. Sentinel / end pointer pattern
- C parsers use this:
// main.c
while (ptr < end)- Rust:
// main.rs
while !slice.is_empty()- Used in:
- compilers
- lexers
- JSON parsers
- HTTP parsers
prevent_Crashes_Overflow_UB_Invalid_memory_access
https://younghakim7.github.io/blog/posts/prevent_crashes_overflow_ub_invalid_memory_access/