Skip to content

[SPARK-57659][CORE] Fix integer/long overflow in ArrayWrappers numeric array key comparators#56731

Open
LuciferYang wants to merge 1 commit into
apache:masterfrom
LuciferYang:SPARK-kvstore-intarray-overflow
Open

[SPARK-57659][CORE] Fix integer/long overflow in ArrayWrappers numeric array key comparators#56731
LuciferYang wants to merge 1 commit into
apache:masterfrom
LuciferYang:SPARK-kvstore-intarray-overflow

Conversation

@LuciferYang

@LuciferYang LuciferYang commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

ComparableIntArray and ComparableLongArray in ArrayWrappers compared keys by subtracting elements (array[i] - other.array[i]). That subtraction overflows for large opposite-sign values and flips the sign of the result. Comparing Integer.MIN_VALUE with Integer.MAX_VALUE is enough to trigger it for int, and Long.MAX_VALUE - Long.MIN_VALUE wraps around to -1 for long. The long version's diff > 0 ? 1 : -1 looked like it dealt with this, but it only kept the long difference from being truncated to int; the overflow had already happened by then. Both comparators now use Integer.compare / Long.compare, which can't overflow. ComparableByteArray is left as is, since bytes promote into a small int range and its subtraction can't overflow.

Why are the changes needed?

These wrappers order keys and index values in InMemoryStore. AppStatusStore uses int[] keys (stage id and attempt id), so the int comparator runs for real, but those ids are small so the overflow never surfaced. No in-tree entity uses long[] keys today. The bug is real but latent, and the fix keeps the ordering correct if larger values ever flow through.

Does this PR introduce any user-facing change?

No. It only fixes orderings that were already wrong.

How was this patch tested?

Added two cases to ArrayWrappersSuite, one per comparator, covering MIN/MAX and other large opposite-sign values in both directions. To confirm they actually guard the bug, I reverted each fix on its own and checked that only that comparator's new test failed.

Was this patch authored or co-authored using generative AI tooling?

No

…c array key comparators

### What changes were proposed in this pull request?

`ComparableIntArray` and `ComparableLongArray` in `ArrayWrappers` compared keys by subtracting elements (`array[i] - other.array[i]`). That subtraction overflows for large opposite-sign values and flips the sign of the result. Comparing `Integer.MIN_VALUE` with `Integer.MAX_VALUE` is enough to trigger it for int, and `Long.MAX_VALUE - Long.MIN_VALUE` wraps around to `-1` for long. The long version's `diff > 0 ? 1 : -1` looked like it dealt with this, but it only kept the long difference from being truncated to int; the overflow had already happened by then. Both comparators now use `Integer.compare` / `Long.compare`, which can't overflow. `ComparableByteArray` is left as is, since bytes promote into a small int range and its subtraction can't overflow.

### Why are the changes needed?

These wrappers order keys and index values in `InMemoryStore`. `AppStatusStore` uses `int[]` keys (stage id and attempt id), so the int comparator runs for real, but those ids are small so the overflow never surfaced. No in-tree entity uses `long[]` keys today. The bug is real but latent, and the fix keeps the ordering correct if larger values ever flow through.

### Does this PR introduce _any_ user-facing change?

No. It only fixes orderings that were already wrong.

### How was this patch tested?

Added two cases to `ArrayWrappersSuite`, one per comparator, covering `MIN`/`MAX` and other large opposite-sign values in both directions. To confirm they actually guard the bug, I reverted each fix on its own and checked that only that comparator's new test failed.

### Was this patch authored or co-authored using generative AI tooling?

No
@LuciferYang LuciferYang force-pushed the SPARK-kvstore-intarray-overflow branch from 22ebdd9 to 4a03bd6 Compare June 24, 2026 07:25
}
}

return array.length - other.array.length;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: here we still use subtraction. Should we switch to Integer.compare for consistency?

@uros-b uros-b left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @LuciferYang!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants