[ 
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)

Reply via email to