Skip to content

fix: reject out-of-range integer cell values instead of wrapping them (#1100) - #1188

Closed
BigDataDZ wants to merge 1 commit into
apache:mainfrom
BigDataDZ:fix/integer-range-checks
Closed

BigDataDZ wants to merge 1 commit into
apache:mainfrom
BigDataDZ:fix/integer-range-checks

Conversation

@BigDataDZ

Copy link
Copy Markdown

What changed

  • New NumberUtils#narrowInRange(BigDecimal, long, long): truncates toward zero (preserving the previous fractional behavior) and then range-checks the truncated value with BigDecimal#compareTo, throwing ArithmeticException on overflow.
  • ByteNumberConverter, ShortNumberConverter, IntegerNumberConverter and LongNumberConverter narrow through it instead of calling byteValue() / shortValue() / intValue() / longValue() directly.
  • NumberUtils#parseByte / #parseShort / #parseInteger / #parseLong (the string-cell path) apply the same range check, on both the plain and the DecimalFormat-backed branches.

Why

An out-of-range cell silently wrapped instead of failing:

// cell 13800138000 into an Integer field printed 915236112 (13800138000 mod 2^32)
// Short 40000 -> -25536, Byte "300" -> 44, Long.MAX_VALUE -> -9223372036854771616

No exception was raised, so corrupted reads went unnoticed. Fractional values keep truncating as before (123.9 still reads as 123); only values whose truncated integer part falls outside the target range now throw.

Fixes #1100

How tested

  • New converter tests for all four types: in-range, boundary (MIN/MAX), fractional truncation, out-of-range throws.
  • New NumberUtilsTest cases: parse* rejects out-of-range strings, accepts boundary values, and keeps truncating fractions.
  • Full fesod-sheet suite (938 tests) passes locally on Temurin 25; spotless:check clean.

Byte, Short, Integer and Long number fields silently narrowed any cell
value with intValue()/shortValue()/byteValue()/longValue(), so an
out-of-range cell like 13800138000 read back as 13800138000 mod 2^32
with no error. This affected number cells and, through
NumberUtils.parse*, string cells alike.

Narrow through a new NumberUtils#narrowInRange that truncates toward
zero (preserving the previous fractional behavior) and then checks the
range with BigDecimal#compareTo, throwing ArithmeticException on
overflow.

Closes apache#1100
@nkuprins

nkuprins commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Hi @BigDataDZ,

Thank you for your interest. There is already a corresponding fix PR (#1101) for this issue. If you'd like, you're also welcome to review it or add further comments to the discussion there.

Therefore, this PR may be closed

@delei delei added the duplicate This issue or pull request already exists label Oct 7, 2026
@BigDataDZ

Copy link
Copy Markdown
Author

Thanks @nkuprins for the pointer - sorry I missed #1101 when scanning the tracker. Your approach (truncate toward zero, then range-check) matches what I had implemented, so there is no reason to keep two PRs for the same fix. Closing this one in favor of #1101.

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

Labels

duplicate This issue or pull request already exists

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Integer, Long, Short and Byte fields return wrong values when a cell is out of range

3 participants