[
https://issues.apache.org/jira/browse/WW-5834?focusedWorklogId=1051649&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1051649
]
ASF GitHub Bot logged work on WW-5834:
--------------------------------------
Author: ASF GitHub Bot
Created on: 31/Oct/26 17:08
Start Date: 31/Oct/26 17:08
Worklog Time Spent: 10m
Work Description: g0w6y opened a new pull request, #2092:
URL: https://github.com/apache/struts/pull/2092
Fixes [WW-5834](https://issues.apache.org/jira/browse/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.
Issue Time Tracking
-------------------
Worklog Id: (was: 1051649)
Remaining Estimate: 0h
Time Spent: 10m
> NumberConverter parses numeric strings of any length
> -----------------------------------------------------
>
> Key: WW-5834
> URL: https://issues.apache.org/jira/browse/WW-5834
> Project: Struts 2
> Issue Type: Bug
> Components: Core
> Affects Versions: 6.12.0, 7.0.0, 7.3.0, 7.4.0
> Reporter: Gouri Sankar A
> Priority: Minor
> Time Spent: 10m
> Remaining Estimate: 0h
>
> NumberConverter converts a String to a boxed number, BigInteger, BigDecimal,
> Double or Float with new BigInteger(String), new BigDecimal(String) and
> DecimalFormat.parse. Parsing a digit string with these is quadratic in its
> length. The value of a request parameter has no length limit in
> ParametersInterceptor (only the parameter name is limited to 100 characters),
> so a long digit string bound to such a property costs CPU out of proportion
> to its size. A primitive int property is not affected in the same way (the
> parse fails fast).
> Measured on main against a running Struts Boot app: one POST with an Integer
> property and a BigDecimal property, each given the same N-digit value. N =
> 100 digits: 0.03 s; 100,000 digits: 0.31 s; 400,000 digits: 3.98 s (the cost
> grows faster than the input). With the change: 100,000 digits 0.014 s and
> 400,000 digits 0.016 s (the value is rejected as a conversion error).
> Limits: the cost is CPU, not memory. It needs a boxed number, BigInteger or
> BigDecimal property that can be set from a request parameter (with
> @StrutsParameter). The request body size is still bounded by the container.
> Affected versions: the same parsing code (new BigInteger(stringValue),
> NumberFormat.parse on the unbounded string) is present in the NumberConverter
> of the 6.12.0, 7.0.0, 7.3.0 and 7.4.0 tags, by source inspection. The
> measurement was only run on main.
> Proposal: reject strings longer than 1000 characters with a
> TypeConversionException before any parsing. 1000 is well above any number the
> framework produces (StringConverter output is at most 681 characters:
> grouping off, 340 integer + 340 fraction digits + separator) and above the
> longest existing test value. The exception is reported as the usual field
> conversion error. Surrounding whitespace is trimmed by XWorkBasicConverter
> before NumberConverter sees the value, so it does not count against the limit.
> Tests: NumberConverterTest.testExceptionWhenNumberIsTooLong,
> testStringToBigDecimalConversionWithMaxLength;
> XWorkConverterTest.testFieldErrorMessageAddedWhenNumberIsTooLong,
> testSurroundingWhitespaceIsNotCountedAgainstMaxNumberLength.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)