i64decdrain declares u64 x; uninitialized, fills it via call(u64decdrain, &x, dec) but never checks the return code; when u64decdrain rejects the input (empty / non-digit after a sign) it returns SBADARG without writing x, so the function then computes the out-parameter *i from garbage stack memory and applies a stale-value INTBAD test. The goal is to propagate the parse error and stop reading uninitialized memory.
Unchecked error return leaves an out-parameter set from uninitialized stack.
abc/INT.c:5-22 — o = u64decdrain(&x, dec) (line 10) is captured but never checked; on early SBADARG (abc/01.h:394-405) x is never written.x to set *i = -x / *i = x and run test(x<=lim, INTBAD) on the garbage value.i64decdrain on a lone sign or sign+non-digit ("-", "+a"); sane() only enforces !$empty(tok), so after the sign skip dec is empty/non-numeric.None.
Check the decode result before using the value.
"-", "+", "+a", "-z" rows to the INT decode table test; confirm garbage/UB under ASan/MSan-style scrutiny.try/call propagation: ok64 o = u64decdrain(&x, dec); if (o!=OK) return o; (and defensively u64 x = 0;).