Repository navigation
[2.x] Fix silent numeric overflow in argument and input binding - #2782
RoMiRoSSaN wants to merge 2 commits into
Conversation
3f7cde8 to
7f7661d
Compare
Reject out-of-range numbers instead of silently wrapping them, and accept Int.MIN_VALUE. Narrowing to Java numeric types is exact, including fields of input objects; overflow, fractions and non-finite floats are errors. Add exact JSON-B AtomicInteger/AtomicLong serializers and deserializers. Preserve converted numeric default values in SDL and introspection. Distinguish fractional Int literals from values outside the Int range. Cover numeric bindings, literal conversion, default values and diagnostics with regression tests.
7139250 to
7a3ae87
Compare
phillip-kruger
left a comment
There was a problem hiding this comment.
The FieldHelper.getArrayType change breaks @NumberFormat on numeric array outputs. See the inline comment. The rest of server/implementation passes locally.
Two behaviour changes that aren't in the description and should go in the release notes:
- Output serialization also goes through the new
convertImpl, so a resolver returningNaNorInfinityfor aFloatfield now gets a field error instead of passing the value through. - A missing
OptionalInt/OptionalLong/OptionalDoubleargument is nowempty()instead ofnull.
|
|
||
| @Override | ||
| protected Class<?> getArrayType(final Field field) { | ||
| if (Classes.isNumberLikeType(field.getReference().getClassName())) { |
There was a problem hiding this comment.
This breaks @NumberFormat on arrays. For a formatted number the reference keeps className = the number type but graphQLClassName = String. This branch returns the number class, so recursiveTransformArray hits the "component type already matches" shortcut and never applies the format:
@Query @NumberFormat("#,##0.00") public Double[] boxedDoubles() { return new Double[]{1234.5, 2.0}; }
@Query @NumberFormat("#,##0.00") public int[] primitiveInts() { return new int[]{1234, 2}; }2.x returns ["1,234.50","2.00"] / ["1,234.00","2.00"]. With this PR it returns ["1234.5","2.0"] / ["1234","2"]. Please skip this branch when field.hasTransformation() and add a test for formatted arrays.
Skip the numeric component shortcut when a field has a transformation so that NumberFormat still formats each array element as a string. Cover primitive and boxed arrays, arrays inside lists, and null elements. Characterize Optional argument, POJO field, and record component binding without changing the existing Optional contract.
|
@phillip-kruger Thanks for pointing that out. I missed it. I've fixed it and added more tests. Looking forward to your further feedback. I've applied the fixes to both pull requests. In the meantime, I'll also test the fixes in my projects using my local fork. |
Fixes #2781
Changes
IntegerScalar: the range check is exact and includes both bounds.Int.MIN_VALUEis accepted.byte,short,int,long, atomic andOptional*wrappers): the conversion is exact.intValue()and casts are replaced with*ValueExact, so overflow and fractions return a GraphQL error.float,double,OptionalDouble):NaN,Infinityand finite overflow return a GraphQL error. Normal IEEE rounding is kept.OptionalInt/OptionalLong/OptionalDoublearguments: passed asOptional*.empty()instead ofnull.BigInteger,BigDecimaland the schema.Before / after
int2147483648-2147483648int-2147483648-2147483648int1.51byte128-128long9223372036854775808-9223372036854775808float1e39Infinityintfield-999999999999999999999999999991610612737, or an unrelatedUnknown Scalar TypeerrorExample error after the fix: