mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
65c39790fc
## Description
`format_int(x, base)` corrupts integers that need more than 64 bits of
precision, in every base. It routes the value through
`builtins.NumberToFloat` (a `big.Float` with a 64-bit mantissa) then
`f.Int()`, so any integer above ~2^64 is rounded before formatting:
```rego
format_int(18446744073709551617, 16) # "10000000000000000" (should be "10000000000000001")
format_int(18446744073709551617, 10) # "18446744073709551616" (should be "...617")
```
`sprintf("%x", [18446744073709551617])` returns the correct
`10000000000000001`, so two builtins disagree on the same exact-integer
value.
## Fix
Format integer inputs through an exact `big.Int` (mirroring
`builtinSprintf`). Fractional/exponent inputs still fall through to the
existing float-truncation path, so `format_int(15.9, 16) == "f"` and
`format_int(-15.9, 16) == "-f"` are unchanged.
## Test
Added a golden case covering a >2^64 integer in bases 2/8/10/16,
negatives, and the fractional-truncation cases. Full `go test
./v1/topdown/` passes (900+ existing string golden cases, no
regressions).
---------
Signed-off-by: Synvoya <16019863+Synvoya@users.noreply.github.com>
Co-authored-by: Synvoya <16019863+Synvoya@users.noreply.github.com>