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)