Skip to content

Jackson 3: numeric functions/operators throw on out-of-range values ($fromMillis, $sum, unary minus, range, array index) #433

Description

@wnm3

Summary

After the Jackson 3 migration (#430, PR #431), several numeric functions and operators call asInt()/asLong() on values that are outside int/long range. Jackson 3 makes these coercions fail‑fast — they throw tools.jackson.databind.node.JsonNodeException for out‑of‑range DoubleNode/BigIntegerNode values. Jackson 2 silently narrowed (a plain cast), so these paths previously produced a (possibly wrong but non‑throwing) value or a controlled JSONata error. The lines were not changed by the migration, so behavior flipped from "return/handle" to "crash".

Not caught by the test suite — no test exercises out‑of‑range magnitudes at these sites.

Where & reproductions

Site Code Repro Jackson 2 Jackson 3
ExpressionsVisitor.java:381 isWholeNumber n.asInt() == n.asDouble() [1..1e19] (range bound) returns false → controlled "must be an integer" error throws raw JsonNodeException
ExpressionsVisitor.java:994 (array index) indexInContext.asInt() ["a","b"][3000000000] narrows → harmless out‑of‑bounds throws
ExpressionsVisitor.java:2919/2925 (unary minus) operand.asLong() on BigIntegerNode -99999999999999999999999999 narrowed long throws
FromMillisFunction.java:90 argNumber.asLong() (guarded only by isNumber()) $fromMillis(1e30) narrowed → wrong date throws
FromMillisZonedFunction.java:90 argNumber.asLong() $fromMillisTz(1e30, '[Y]') narrowed throws
SumFunction.java:95 and :107 a.asLong() / argArray.asLong() on out‑of‑range BigIntegerNode $sum([99999999999999999999999999]) narrowed throws

Verified empirically against jackson‑databind 3.2.0

DoubleNode(1.0E46).asInt()   -> THROWS JsonNodeException
DoubleNode(1.0E46).asLong()  -> THROWS JsonNodeException
BigIntegerNode(99999999999999999999).asLong() -> THROWS JsonNodeException
LongNode(3000000000).asInt() -> THROWS JsonNodeException

Suggested fix

Before calling asInt()/asLong() at these sites, pre‑check magnitude (canConvertToInt() / canConvertToLong()) or operate on doubleValue()/bigIntegerValue() and range‑check, restoring the Jackson‑2 narrowing (or converting to the appropriate controlled JSONata error) rather than allowing a raw JsonNodeException to escape. This mirrors the guard already applied to AgnosticTestSuite's (long) d fix in this migration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions