Skip to content

Commit 35f458f

Browse files
committed
Improve diagnostics for negative repeated text count in SpEL
Due to the changes in gh-31341, if the repeat count in a SpEL expression (using the repeat operator '*') is negative, we throw a SpelEvaluationException with the MAX_REPEATED_TEXT_SIZE_EXCEEDED message which is incorrect and misleading. Prior to gh-31341, a negative repeat count resulted in an IllegalArgumentException being thrown by String#repeat(), which was acceptable in terms of diagnostics, but that did not make it immediately clear to the user what the underlying cause was. In light of the above, this commit improves diagnostics for a negative repeated text count in SpEL expressions by throwing a SpelEvaluationException with a new NEGATIVE_REPEATED_TEXT_COUNT error message. Closes gh-31342
1 parent 8e83f93 commit 35f458f

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,11 @@ public enum SpelMessage {
284284

285285
/** @since 5.2.24 */
286286
VARIABLE_ASSIGNMENT_NOT_SUPPORTED(Kind.ERROR, 1080,
287-
"Assignment to variable ''{0}'' is not supported");
287+
"Assignment to variable ''{0}'' is not supported"),
288+
289+
/** @since 6.0.13 */
290+
NEGATIVE_REPEATED_TEXT_COUNT(Kind.ERROR, 1081,
291+
"Repeat count ''{0}'' must not be negative");
288292

289293

290294
private final Kind kind;

spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ else if (CodeFlow.isIntegerForNumericOp(leftNumber) || CodeFlow.isIntegerForNume
123123
}
124124

125125
private void checkRepeatedTextSize(String text, int count) {
126+
if (count < 0) {
127+
throw new SpelEvaluationException(getStartPosition(),
128+
SpelMessage.NEGATIVE_REPEATED_TEXT_COUNT, count);
129+
}
126130
int result = text.length() * count;
127131
if (result < 0 || result > MAX_REPEATED_TEXT_SIZE) {
128132
throw new SpelEvaluationException(getStartPosition(),

spring-expression/src/test/java/org/springframework/expression/spel/OperatorTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import static org.assertj.core.api.Assertions.assertThat;
2929
import static org.springframework.expression.spel.SpelMessage.MAX_CONCATENATED_STRING_LENGTH_EXCEEDED;
3030
import static org.springframework.expression.spel.SpelMessage.MAX_REPEATED_TEXT_SIZE_EXCEEDED;
31+
import static org.springframework.expression.spel.SpelMessage.NEGATIVE_REPEATED_TEXT_COUNT;
3132

3233
/**
3334
* Tests the evaluation of expressions using various operators.
@@ -587,6 +588,13 @@ void stringRepeat() {
587588
evaluateAndCheckError("'ab' * " + repeatCount, String.class, MAX_REPEATED_TEXT_SIZE_EXCEEDED, 5);
588589
}
589590

591+
@Test
592+
void stringRepeatWithNegativeRepeatCount() {
593+
// 4 is the position of the '*' (repeat operator)
594+
// -1 is the negative repeat count
595+
evaluateAndCheckError("'a' * -1", String.class, NEGATIVE_REPEATED_TEXT_COUNT, 4, -1);
596+
}
597+
590598
@Test
591599
void stringConcatenation() {
592600
evaluate("'' + ''", "", String.class);

0 commit comments

Comments
 (0)