Improve diagnostics in SpEL for repeated text

Attempting to create repeated text in a SpEL expression using the
repeat operator can result in errors that are not very helpful to the
user.

This commit improves the diagnostics in SpEL for the repeat operator by
throwing a SpelEvaluationException with a meaningful error message in
order to better assist the user.

Closes gh-30143
This commit is contained in:
Sam Brannen
2023-03-16 17:28:37 +01:00
parent 430fc25aca
commit 4d5e7207f2
3 changed files with 46 additions and 12 deletions

View File

@@ -21,10 +21,12 @@ import java.math.BigInteger;
import org.junit.jupiter.api.Test;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.ast.Operator;
import org.springframework.expression.spel.standard.SpelExpression;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.expression.spel.SpelMessage.MAX_REPEATED_TEXT_SIZE_EXCEEDED;
/**
* Tests the evaluation of expressions using various operators.
@@ -32,6 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Clement
* @author Juergen Hoeller
* @author Giovanni Dall'Oglio Risso
* @author Sam Brannen
*/
class OperatorTests extends AbstractExpressionTests {
@@ -324,11 +327,6 @@ class OperatorTests extends AbstractExpressionTests {
evaluate("3.5", 3.5d, Double.class);
}
@Test
void multiplyStringInt() {
evaluate("'a' * 5", "aaaaa", String.class);
}
@Test
void multiplyDoubleDoubleGivesDouble() {
evaluate("3.0d * 5.0d", 15.0d, Double.class);
@@ -576,6 +574,19 @@ class OperatorTests extends AbstractExpressionTests {
evaluate("'abc' != 'def'", true, Boolean.class);
}
@Test
void stringRepeat() {
evaluate("'abc' * 0", "", String.class);
evaluate("'abc' * 1", "abc", String.class);
evaluate("'abc' * 2", "abcabc", String.class);
Expression expr = parser.parseExpression("'a' * 256");
assertThat(expr.getValue(context, String.class)).hasSize(256);
// 4 is the position of the '*' (repeat operator)
evaluateAndCheckError("'a' * 257", String.class, MAX_REPEATED_TEXT_SIZE_EXCEEDED, 4);
}
@Test
void longs() {
evaluate("3L == 4L", false, Boolean.class);