Lane: reflection/parse (sweep 2, finding 7)
verify uses plain Number.isInteger for the int32 family (src/verifier.js:47-54), so verify({a: 2147483648}) returns null and encode then wraps via |0 (src/writer.js:163) — silent data corruption with no error. Same for uint32 negatives (>>>0).
Repro (executed by sweep, luna, grok): verify → null; encode/decode round-trips to -2147483648.
Verdicts: both Confirm Strong — runtime footgun, not .proto pedantry.
Upstream: believed unreported for verify.
Decision question: Evaluate whether to fix: range-check int32/uint32 families in genVerifyValue. NOTE this is a behavior change for currently-"valid" callers — that compatibility cost is the open question, so this ticket is evaluate-whether, not implement-by-default.
Lane: reflection/parse (sweep 2, finding 7)
verifyuses plainNumber.isIntegerfor the int32 family (src/verifier.js:47-54), soverify({a: 2147483648})returns null and encode then wraps via|0(src/writer.js:163) — silent data corruption with no error. Same for uint32 negatives (>>>0).Repro (executed by sweep, luna, grok):
verify→ null; encode/decode round-trips to-2147483648.Verdicts: both Confirm Strong — runtime footgun, not .proto pedantry.
Upstream: believed unreported for verify.
Decision question: Evaluate whether to fix: range-check int32/uint32 families in
genVerifyValue. NOTE this is a behavior change for currently-"valid" callers — that compatibility cost is the open question, so this ticket is evaluate-whether, not implement-by-default.