Skip to content

WW-5834 fix(conversion): reject over-long numeric strings before parsing them - #2092

Open
g0w6y wants to merge 1 commit into
apache:mainfrom
g0w6y:WW-5834-number-converter-length-limit
Open

g0w6y wants to merge 1 commit into
apache:mainfrom
g0w6y:WW-5834-number-converter-length-limit

Conversation

@g0w6y

@g0w6y g0w6y commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Fixes WW-5834

NumberConverter parses numeric strings with BigInteger, BigDecimal and DecimalFormat, which are quadratic in the length of the string. A request parameter value has no length limit (ParametersInterceptor limits only the name), so a long digit string bound to a boxed number, BigInteger or BigDecimal property costs CPU out of proportion to its size: on a running Struts Boot app, one POST with an Integer and a BigDecimal property given the same value took 0.31 s at 100,000 digits and 3.98 s at 400,000 digits on main.

Strings longer than 1000 characters are now rejected with a TypeConversionException at the top of the String branch of convertValue, before any parsing. That one place covers BigInteger (which bypasses isInRange), BigDecimal, Double, Float, boxed and primitive types. XWorkConverter reports the exception as the usual field conversion error (covered by a test).

Why 1000: StringConverter never produces more than 681 characters (grouping off, 340 integer + 340 fraction digits + separator), doubles need about 330, and the longest existing test value is about 636. XWorkBasicConverter trims surrounding whitespace before calling NumberConverter, so padding does not count (covered by a test).

How verified: with the production change reverted NumberConverterTest.testExceptionWhenNumberIsTooLong and XWorkConverterTest.testFieldErrorMessageAddedWhenNumberIsTooLong fail; with it they pass. testStringToBigDecimalConversionWithMaxLength (exactly 1000 digits still converts) and the whitespace test pass both ways. Full core suite: 3629 run, 0 failures, 2 skipped.

On the running app with this change the same requests take 0.014 s (100,000 digits) and 0.016 s (400,000 digits), ordinary values (count=12345&amount=12345.67) still convert, and a 1001-character value is reported as a conversion error.

Not changed: StringConverter, isInRange, any configuration option. Risk: numbers longer than 1000 characters can no longer be converted.

…ing them

NumberConverter parsed numeric strings of any length with BigInteger,
BigDecimal and DecimalFormat, whose string parsing is quadratic in the
length of the string. A request parameter value is not length-limited
(only the parameter name is), so a long digit string bound to a boxed
number, BigInteger or BigDecimal property cost seconds of CPU.

Strings longer than 1000 characters are now rejected with a
TypeConversionException, which is reported as the usual conversion error
for the field. 1000 is well above any number the framework itself
produces; surrounding whitespace is trimmed before the check.
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