Gouri Sankar A created WW-5834:
----------------------------------

             Summary:  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: 7.4.0, 7.3.0, 7.0.0, 6.12.0
            Reporter: Gouri Sankar A


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