Skip to content

Compare exact bound in AbstractNumberValidator range checks#416

Merged
garydgregory merged 2 commits into
apache:masterfrom
sahvx655-wq:integer-range-exact-bound
Jul 4, 2026
Merged

Compare exact bound in AbstractNumberValidator range checks#416
garydgregory merged 2 commits into
apache:masterfrom
sahvx655-wq:integer-range-exact-bound

Conversation

@sahvx655-wq

Copy link
Copy Markdown
Contributor

The DoubleValidator range fix in #410 left the same narrowing in the shared parent. AbstractNumberValidator.minValue(Number, Number) and maxValue(Number, Number) fall back to value.longValue() against min.longValue() on the integer branch, and ByteValidator, ShortValidator, IntegerValidator and LongValidator inherit that branch without overriding it, so a bound that does not fit in a long is mangled before the comparison ever happens. LongValidator.maxValue(Long.MAX_VALUE, 2^63 held as a BigInteger) narrows the bound to Long.MIN_VALUE and reports the in-range value as over the maximum, while a fractional bound such as minValue(5, 5.5) is floored to 5 and wrongly passes. The visible behaviour is a validator quietly comparing against the wrong bound whenever a small integer value meets a BigInteger, BigDecimal or fractional limit, which is easy to miss because no error is raised.

The BigInteger, BigDecimal and Double overloads already compare the operands exactly and keep the doubleValue() fallback for a non-finite bound, so I put the same treatment on the parent's integer branch rather than repeat an override in all four subclasses. Sitting the fix in the shared base keeps the NaN and infinity handling identical across the hierarchy and avoids a fifth copy of the comparison. Each of the four affected validator tests gets a regression that fails on the old narrowing branch and passes now.

Before you push a pull request, review this list:

  • Read the contribution guidelines for this project.
  • Read the ASF Generative Tooling Guidance if you use Artificial Intelligence (AI).
  • I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute?
  • Run a successful build using the default Maven goal with mvn; that's mvn on the command line by itself.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.

Signed-off-by: Sahana Bogar <sahvx655@gmail.com>
@garydgregory garydgregory changed the title compare exact bound in AbstractNumberValidator range checks Compare exact bound in AbstractNumberValidator range checks Jul 4, 2026
@garydgregory

Copy link
Copy Markdown
Member

Hello @sahvx655-wq
The PR changes an abstract main class. Make sure ALL concrete subclasses of the abstract class have tests that check the changes in main.
TY!

@sahvx655-wq

Copy link
Copy Markdown
Contributor Author

Makes sense. I'd only added the regression to the four integer validators that route straight through the changed non-fraction branch (Byte/Short/Integer/Long), but you're right that every concrete subclass should exercise the inherited overloads. I've now added the same testNumberRangeExactBound to FloatValidatorTest, CurrencyValidatorTest and PercentValidatorTest. Float hits the unchanged fraction branch and Currency/Percent inherit BigDecimalValidator's exact-compare override, so those assert the behaviour stays correct through each concrete class rather than failing on the old tree.

Double, BigDecimal and BigInteger already carry equivalent coverage from the earlier range fixes (testDoubleNumberRangeExactBound, testNumberRangeBeyondDoublePrecision, and testNumberRangeOutsideLongRange/testNumberRangeFractionalBound/testNumberRangeNonFiniteBound), so the whole hierarchy is now covered. Full mvn build is green.

@garydgregory garydgregory merged commit 339b525 into apache:master Jul 4, 2026
10 checks passed
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