|
| 1 | +# Panic Policy |
| 2 | + |
| 3 | +`base64-ng` treats runtime panics in public scalar APIs as denial-of-service |
| 4 | +risk. Public encode, decode, validation, length, in-place, streaming, and |
| 5 | +profile APIs should report malformed input and size failures with `Result` or |
| 6 | +`Option` rather than unwinding. |
| 7 | + |
| 8 | +This policy is enforced by: |
| 9 | + |
| 10 | +```sh |
| 11 | +scripts/validate-panic-policy.sh |
| 12 | +``` |
| 13 | + |
| 14 | +The validator scans non-test source before Kani/test-only modules and fails on |
| 15 | +new `panic!`, `unreachable!`, `.unwrap()`, or `.expect()` sites unless they |
| 16 | +match an allowlisted pattern documented here. |
| 17 | + |
| 18 | +## Allowed Non-Test Sites |
| 19 | + |
| 20 | +The current reviewed exceptions are: |
| 21 | + |
| 22 | +- `Engine::encode_array` may panic during const evaluation when the caller |
| 23 | + supplies an output array length that does not match the compile-time encoded |
| 24 | + length, or when that const length calculation overflows. This is documented |
| 25 | + as a const-array API contract and is not used for runtime untrusted length |
| 26 | + metadata. |
| 27 | +- Internal remainder matches use `_ => unreachable!()` after matching |
| 28 | + `len % 3` or equivalent remainder values. The preceding arithmetic bounds |
| 29 | + make those arms unreachable. |
| 30 | +- `String::from_utf8` conversions after Base64 encoding use `unreachable!` |
| 31 | + because crate encoders produce ASCII bytes by construction. |
| 32 | +- Stream `get_ref`, `get_mut`, and `into_inner` internal helpers use |
| 33 | + `unreachable!` if a wrapper has already consumed its inner value. The public |
| 34 | + API consumes `self` for `into_inner`/`finish`, so this state is not reachable |
| 35 | + through safe public calls. |
| 36 | + |
| 37 | +Test code, doctest examples, and Kani proof harnesses may use `unwrap`, |
| 38 | +`expect`, or panic-like macros when they are asserting expected outcomes. |
| 39 | + |
| 40 | +## Caller Guidance |
| 41 | + |
| 42 | +For untrusted input and untrusted length metadata, prefer: |
| 43 | + |
| 44 | +- `checked_encoded_len` |
| 45 | +- `encoded_len` |
| 46 | +- `wrapped_encoded_len` |
| 47 | +- `decoded_capacity` |
| 48 | +- `decoded_len` |
| 49 | +- caller-owned `encode_slice` and `decode_slice` |
| 50 | +- in-place APIs that return `Result` |
| 51 | + |
| 52 | +Compile-time array encoding is intentionally stricter: an incorrect destination |
| 53 | +array length fails const evaluation so the mistake cannot silently produce a |
| 54 | +truncated or oversized static value. |
0 commit comments