Improve diagnostics for repeated text size overflow in SpEL
If the resulting size of repeated text in a SpEL expression (using the repeat operator '*') would exceed MAX_REPEATED_TEXT_SIZE, we currently throw a SpelEvaluationException with the MAX_REPEATED_TEXT_SIZE_EXCEEDED message. However, if the calculation of the repeated text size results in integer overflow, our max size check fails to detect that, and String#repeat(int) throws a preemptive OutOfMemoryError from which the application immediately recovers. To improve diagnostics for users, this commit ensures that we consistently throw a SpelEvaluationException with the MAX_REPEATED_TEXT_SIZE_EXCEEDED message when integer overflow occurs. Closes gh-31341
This commit is contained in:
parent
407113945d
commit
8e83f93bcb
|
|
@ -123,7 +123,8 @@ public class OpMultiply extends Operator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRepeatedTextSize(String text, int count) {
|
private void checkRepeatedTextSize(String text, int count) {
|
||||||
if (text.length() * count > MAX_REPEATED_TEXT_SIZE) {
|
int result = text.length() * count;
|
||||||
|
if (result < 0 || result > MAX_REPEATED_TEXT_SIZE) {
|
||||||
throw new SpelEvaluationException(getStartPosition(),
|
throw new SpelEvaluationException(getStartPosition(),
|
||||||
SpelMessage.MAX_REPEATED_TEXT_SIZE_EXCEEDED, MAX_REPEATED_TEXT_SIZE);
|
SpelMessage.MAX_REPEATED_TEXT_SIZE_EXCEEDED, MAX_REPEATED_TEXT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -579,6 +579,12 @@ class OperatorTests extends AbstractExpressionTests {
|
||||||
|
|
||||||
// 4 is the position of the '*' (repeat operator)
|
// 4 is the position of the '*' (repeat operator)
|
||||||
evaluateAndCheckError("'a' * 257", String.class, MAX_REPEATED_TEXT_SIZE_EXCEEDED, 4);
|
evaluateAndCheckError("'a' * 257", String.class, MAX_REPEATED_TEXT_SIZE_EXCEEDED, 4);
|
||||||
|
|
||||||
|
// Integer overflow: 2 * ((Integer.MAX_VALUE / 2) + 1) --> integer overflow
|
||||||
|
int repeatCount = (Integer.MAX_VALUE / 2) + 1;
|
||||||
|
assertThat(2 * repeatCount).isNegative();
|
||||||
|
// 5 is the position of the '*' (repeat operator)
|
||||||
|
evaluateAndCheckError("'ab' * " + repeatCount, String.class, MAX_REPEATED_TEXT_SIZE_EXCEEDED, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue