test: u64/u32 upper-bound schema tests never pin the actual boundary because boon compares numbers as f64 #179

Closed
opened 2026-09-07 15:45:20 +09:00 by natsukium · 0 comments
Owner

boon's numeric validation (validator.rs num_validate, minimum/maximum/exclusiveMinimum/exclusiveMaximum) converts both the schema bound and the instance value with Number::as_f64() before comparing (boon 0.6.1, src/validator.rs:517-555).

The integer-bounds fixtures therefore never pin the actual 64-bit boundary. out-check-errors-above-u64.json pairs an "exactly u64::MAX" valid twin with an invalid instance of errors: 99999999999999999999 (~1e20), far above the boundary rather than u64::MAX + 1 (18446744073709551616). Because f64 cannot represent integers of this magnitude exactly, the fixture does catch a materially wrong bound (off by many orders of magnitude) but does not exercise the boundary the fix claims to pin, and no fixture sits at the closest representable failing value.

Correction: add max-plus-one fixtures immediately adjacent to the true 64-bit boundary for both signed and unsigned fields, each paired with an exact-maximum valid twin, and document that boon's f64-based comparison means true off-by-one precision at the 2^63/2^64 boundary cannot be distinguished by this validator — the same class of inherent-limitation disclosure already used for the id byte-length schema annotation.

Reason deferred from #29: boon's f64-based numeric comparison is an inherent validator limitation (the same class already disclosed for the id byte-length annotation), not a defect in the diff. Adding max-plus-one fixtures is precision hardening beyond the acceptance criterion (out-of-range integers fail fixtures), which the existing fixtures already satisfy.

Split from #29.

boon's numeric validation (`validator.rs` `num_validate`, `minimum`/`maximum`/`exclusiveMinimum`/`exclusiveMaximum`) converts both the schema bound and the instance value with `Number::as_f64()` before comparing (boon 0.6.1, `src/validator.rs:517-555`). The integer-bounds fixtures therefore never pin the actual 64-bit boundary. `out-check-errors-above-u64.json` pairs an "exactly `u64::MAX`" valid twin with an invalid instance of `errors: 99999999999999999999` (~1e20), far above the boundary rather than `u64::MAX + 1` (18446744073709551616). Because f64 cannot represent integers of this magnitude exactly, the fixture does catch a materially wrong bound (off by many orders of magnitude) but does not exercise the boundary the fix claims to pin, and no fixture sits at the closest representable failing value. Correction: add max-plus-one fixtures immediately adjacent to the true 64-bit boundary for both signed and unsigned fields, each paired with an exact-maximum valid twin, and document that boon's f64-based comparison means true off-by-one precision at the 2^63/2^64 boundary cannot be distinguished by this validator — the same class of inherent-limitation disclosure already used for the id byte-length schema annotation. Reason deferred from #29: boon's f64-based numeric comparison is an inherent validator limitation (the same class already disclosed for the id byte-length annotation), not a defect in the diff. Adding max-plus-one fixtures is precision hardening beyond the acceptance criterion (out-of-range integers fail fixtures), which the existing fixtures already satisfy. Split from #29.
Sign in to join this conversation.
No description provided.