Skip to content

WW-5828 Bound integer digits when formatting BigDecimal (6.x) - #2086

Merged
lukaszlenart merged 2 commits into
support/struts-6-x-xfrom
WW-5828-bound-bigdecimal-integer-digits-6x
Nov 1, 2026
Merged

lukaszlenart merged 2 commits into
support/struts-6-x-xfrom
WW-5828-bound-bigdecimal-integer-digits-6x

Conversation

@lukaszlenart

Copy link
Copy Markdown
Member

Fixes WW-5828

Backport of the change on main to the 6.x line, adjusted for the com.opensymphony.xwork2 package layout and the X.class.isInstance(value) style this line uses.

WW-5711 bounded maximumFractionDigits to 340 in StringConverter, so the length of a formatted BigDecimal no longer follows a large positive scale. The integer side had no equivalent bound: DecimalFormat keeps its default maximumIntegerDigits of Integer.MAX_VALUE and pads the integer part of a value with a large negative scale out in full, so the output length followed the scale of the value rather than its precision.

setMaximumIntegerDigits is not the right bound: DecimalFormat applies it by dropping the leading digits rather than by rounding.

This change bounds the integer digit count (precision - scale, computed in long because the subtraction overflows int at the extreme of the scale range) to 340 and, past it, falls back to BigDecimal.toString(). Every double still formats in full; the existing test pins Double.MAX_VALUE at 309 integer digits.

The regression test pins both sides of the bound, the far case, and the scale boundary.

Observable change: a value with more than 340 integer digits now renders as 1E+340 style scientific notation instead of its full digits, and such a value no longer round-trips through a form because the parser does not accept the E+ form. The same kind of trade-off as the rounding introduced by WW-5711.

🤖 Generated with Claude Code

WW-5711 bounded maximumFractionDigits to 340, so the length of a
formatted BigDecimal no longer follows a large positive scale. The
integer side had no equivalent bound: DecimalFormat keeps its default
maximumIntegerDigits of Integer.MAX_VALUE and pads the integer part of
a value with a large negative scale out in full, so the output length
followed the scale of the value rather than its precision.

setMaximumIntegerDigits is not the right bound, because DecimalFormat
applies it by dropping the leading digits rather than by rounding.

Bound the integer digit count (precision - scale, computed in long
because the subtraction overflows int at the edge of the scale range)
to 340 and, past it, fall back to BigDecimal.toString(), which renders
the value compactly in scientific notation. Every double still formats
in full; the widest, Double.MAX_VALUE, has 309 integer digits and the
existing test pins it.

Backport of the same change on main, adjusted for the
com.opensymphony.xwork2 package layout of this line.

Fixes: https://issues.apache.org/jira/browse/WW-5828

Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
@lukaszlenart
lukaszlenart marked this pull request as ready for review October 31, 2026 14:26
Use instanceof for the BigDecimal check (S6202) and drop the throws
clause the new test does not need (S1130).

Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@lukaszlenart
lukaszlenart merged commit 61daa30 into support/struts-6-x-x Nov 1, 2026
10 checks passed
@lukaszlenart
lukaszlenart deleted the WW-5828-bound-bigdecimal-integer-digits-6x branch November 1, 2026 07:50
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.

1 participant