Stop xsd2inst building digit-facet bounds as strings - #99
Merged
Conversation
formatDecimal turned xsd:totalDigits into a string of that many nines and xsd:fractionDigits into "0.00...1", then parsed each back. Both facets are positiveInteger and have no ceiling, so once a schema asked for more digits than the maximum allowed for a number, parsing the string it had just built threw and no sample could be generated: IllegalArgumentException: Number has more than 1024 characters 5.3.0 used new BigDecimal(...) here and was unaffected. Compute both directly instead - 10^totalDigits - 1, and 1 shifted fractionDigits places right. The totalDigits bound can only narrow a limit at least as wide, so it is computed only when it can bind, which also keeps 10^n away from a totalDigits far larger than any bound the schema declares. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Branched from trunk, independent of #98.
The bug
SampleXmlUtil.formatDecimalderived both digit-facet bounds by building a string and parsing it back —xsd:totalDigitsas that many nines,xsd:fractionDigitsas"0.00...1". Both facets arepositiveIntegerwith no ceiling of their own, so as soon as a schema asks for more digits thanmaxNumberOfCharsForNumbersallows,parseAsBigDecimalrejects the string the method just built:and
xsd2instcannot generate a sample for the schema at all. 5.3.0 usednew BigDecimal(...)here and was unaffected; the limit arrived in 5.4.0.A minimal reproducer — nothing else in the schema:
The
fractionDigitsbranch fails the same way at 1023.The fix
Compute both values instead of spelling them out:
10^totalDigits - 1for the widest value the facet allows;BigDecimal.ONE.scaleByPowerOfTen(-fractionDigits)for the increment, which only sets a scale and expands nothing.The
totalDigitsbound can only narrow amin/maxthat is at least as wide, so it is now computed only when it can actually bind. That is what keeps10^naway from atotalDigitsfar larger than any bound the schema declares — the previous code built its string of nines unconditionally, even when nominormaxfacet existed for it to constrain.Behaviour for schemas within the limit is unchanged:
totalDigitsstill pulls the seed value down to the widest value it permits.Tests
testDigitFacetsWiderThanTheNumberLengthLimitcovers both facets past the limit — it fails on trunk with the exception above.testTotalDigitsStillNarrowsTheBoundspins the normal case (seed1000.00,totalDigits=3→999) and passes both before and after, so it guards the semantics rather than the fix.Full suite: 3084 tests, 0 failures.
🤖 Generated with Claude Code