# Unchecked parser length arithmetic

Computed lengths/offsets used before checking non-negative, in-range, cursor advanced

_Area: Memory corruption and native code. Seen in 7 disclosed reports; 4 confirmed bounties, median $1,250, range $250-$5,000; latest 2025-06-13. Updated 2026-10-23._

## How it works
A parser computes a length or offset by arithmetic (subtract a constant, decrement a counter, divide, widen a signed value into an unsigned size) and uses the result without confirming it is still valid. The broken assumption is "the computed value is non-negative, bounded, and consistent with the buffer." When input drives the intermediate negative or zero, the value wraps to a huge unsigned number or a small wrong one, and the following copy, scan, allocation or loop trusts it. The defect is the missing check on the computed value, not the arithmetic itself.

## Where it shows up
- `size_t` assigned from a signed difference, e.g. `end - crlf - 8`, `bufsize - 1` [E6](https://bugbountylibrary.com/r/h1%3A1434056.md)[E2](https://bugbountylibrary.com/r/h1%3A784186.md)
- Unsigned loop counters decremented in `for(...; i--; ...)` after an early-exit branch can reach 0 first [E1](https://bugbountylibrary.com/r/h1%3A593229.md)
- Signed `int` length forwarded to an unsigned size parameter at an API boundary [E5](https://bugbountylibrary.com/r/h1%3A1595299.md)
- Division used as a multiplication validator, discarding remainders [E4](https://bugbountylibrary.com/r/h1%3A73258.md)
- Decoders that can return negative lengths, with callers that do not advance the read cursor [E3](https://bugbountylibrary.com/r/h1%3A2105808.md)
- Library-returned offset pairs where callers compute `end - start` unvalidated [E7](https://bugbountylibrary.com/r/h1%3A141839.md)

## How to review
For every computed length or offset, name the invariant it must satisfy (non-negative, within the buffer, cursor advanced) and confirm it is enforced before use, not assumed. Trace unsigned counters through every early-exit path. Test the zero and boundary cases explicitly: `bufsize==0`, empty boundary, minimal length prefix, non-divisible sizes. At signed/unsigned boundaries, confirm the value is range-checked before conversion. For library-returned offsets, verify the caller checks `start <= end` rather than trusting the contract [E7](https://bugbountylibrary.com/r/h1%3A141839.md). For decoders, confirm a negative or error return is rejected and the cursor advances.

## Variants seen
- Unsigned loop counter underflow turning a bounded scan into an unbounded read [E1](https://bugbountylibrary.com/r/h1%3A593229.md)
- `bufsize-1` underflow plus trailing NUL write past buffer [E2](https://bugbountylibrary.com/r/h1%3A784186.md)
- Negative decoder result accepted, cursor not advanced, infinite loop [E3](https://bugbountylibrary.com/r/h1%3A2105808.md)
- Integer division truncation letting a bad size pass a validator [E4](https://bugbountylibrary.com/r/h1%3A73258.md)
- Signed int sign-extending to a giant bucket length [E5](https://bugbountylibrary.com/r/h1%3A1595299.md)
- Boundary-length subtraction wrapping to SIZE_MAX, zero allocation then overflow [E6](https://bugbountylibrary.com/r/h1%3A1434056.md)
- Offsets violating `start<=end` from regex constructs, unvalidated by consumers [E7](https://bugbountylibrary.com/r/h1%3A141839.md)

## Why fixes fail
E7 notes the PCRE issues were "already fixed" yet recurred: offset-contract violations are patched per call site rather than enforced centrally, so new consumers reintroduce the bug.

## Impact and severity
Heap out-of-bounds read/write leading to memory disclosure, crash or RCE [E1](https://bugbountylibrary.com/r/h1%3A593229.md)[E2](https://bugbountylibrary.com/r/h1%3A784186.md)[E5](https://bugbountylibrary.com/r/h1%3A1595299.md)[E6](https://bugbountylibrary.com/r/h1%3A1434056.md)[E7](https://bugbountylibrary.com/r/h1%3A141839.md); DoS via hang and OOM [E3](https://bugbountylibrary.com/r/h1%3A2105808.md). Severity rises when the path is reachable from remote unauthenticated input and the wrapped length feeds a copy rather than a comparison.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A593229.md
- E2: https://bugbountylibrary.com/r/h1%3A784186.md
- E3: https://bugbountylibrary.com/r/h1%3A2105808.md
- E4: https://bugbountylibrary.com/r/h1%3A73258.md
- E5: https://bugbountylibrary.com/r/h1%3A1595299.md
- E6: https://bugbountylibrary.com/r/h1%3A1434056.md
- E7: https://bugbountylibrary.com/r/h1%3A141839.md
