Skip to content

Commit b73f5fc

Browse files
sbrannenbclozel
authored andcommitted
Limit SpEL expression length
This commit enforces a limit of the maximum size of a single SpEL expression. Closes gh-30325
1 parent bc1511d commit b73f5fc

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,19 @@ public enum SpelMessage {
268268

269269
/** @since 5.2.23 */
270270
MAX_REPEATED_TEXT_SIZE_EXCEEDED(Kind.ERROR, 1076,
271-
"Repeated text results in too many characters, exceeding the threshold of ''{0}''"),
271+
"Repeated text is too long, exceeding the threshold of ''{0}'' characters"),
272272

273273
/** @since 5.2.23 */
274274
MAX_REGEX_LENGTH_EXCEEDED(Kind.ERROR, 1077,
275-
"Regular expression contains too many characters, exceeding the threshold of ''{0}''"),
275+
"Regular expression is too long, exceeding the threshold of ''{0}'' characters"),
276276

277277
/** @since 5.2.24 */
278278
MAX_CONCATENATED_STRING_LENGTH_EXCEEDED(Kind.ERROR, 1078,
279-
"Concatenated string is too long, exceeding the threshold of ''{0}'' characters");
279+
"Concatenated string is too long, exceeding the threshold of ''{0}'' characters"),
280+
281+
/** @since 5.2.24 */
282+
MAX_EXPRESSION_LENGTH_EXCEEDED(Kind.ERROR, 1079,
283+
"SpEL expression is too long, exceeding the threshold of ''{0}'' characters");
280284

281285

282286
private final Kind kind;

spring-expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.expression.ParserContext;
3030
import org.springframework.expression.common.TemplateAwareExpressionParser;
3131
import org.springframework.expression.spel.InternalParseException;
32+
import org.springframework.expression.spel.SpelEvaluationException;
3233
import org.springframework.expression.spel.SpelMessage;
3334
import org.springframework.expression.spel.SpelParseException;
3435
import org.springframework.expression.spel.SpelParserConfiguration;
@@ -92,6 +93,12 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
9293

9394
private static final Pattern VALID_QUALIFIED_ID_PATTERN = Pattern.compile("[\\p{L}\\p{N}_$]+");
9495

96+
/**
97+
* Maximum length permitted for a SpEL expression.
98+
* @since 5.2.24
99+
*/
100+
private static final int MAX_EXPRESSION_LENGTH = 10_000;
101+
95102

96103
private final SpelParserConfiguration configuration;
97104

@@ -127,6 +134,8 @@ public InternalSpelExpressionParser(SpelParserConfiguration configuration) {
127134
protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context)
128135
throws ParseException {
129136

137+
checkExpressionLength(expressionString);
138+
130139
try {
131140
this.expressionString = expressionString;
132141
Tokenizer tokenizer = new Tokenizer(expressionString);
@@ -148,6 +157,12 @@ protected SpelExpression doParseExpression(String expressionString, @Nullable Pa
148157
}
149158
}
150159

160+
private void checkExpressionLength(String string) {
161+
if (string.length() > MAX_EXPRESSION_LENGTH) {
162+
throw new SpelEvaluationException(SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED, MAX_EXPRESSION_LENGTH);
163+
}
164+
}
165+
151166
// expression
152167
// : logicalOrExpression
153168
// ( (ASSIGN^ logicalOrExpression)

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,20 @@ class EvaluationTests extends AbstractExpressionTests {
6060
@Nested
6161
class MiscellaneousTests {
6262

63+
@Test
64+
void expressionLength() {
65+
String expression = "'X' + '%s'".formatted(" ".repeat(9_992));
66+
assertThat(expression).hasSize(10_000);
67+
Expression expr = parser.parseExpression(expression);
68+
String result = expr.getValue(context, String.class);
69+
assertThat(result).hasSize(9_993);
70+
assertThat(result.trim()).isEqualTo("X");
71+
72+
expression = "'X' + '%s'".formatted(" ".repeat(9_993));
73+
assertThat(expression).hasSize(10_001);
74+
evaluateAndCheckError(expression, String.class, SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED);
75+
}
76+
6377
@Test
6478
void createListsOnAttemptToIndexNull01() throws EvaluationException, ParseException {
6579
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));

0 commit comments

Comments
 (0)