Reject null and empty SpEL expressions

Prior to gh-30325, supplying a null reference for a SpEL expression was
effectively equivalent to supplying the String "null" as the
expression. Consequently, evaluation of a null reference expression
always evaluated to a null reference. However, that was accidental
rather than by design.

Due to the introduction of the checkExpressionLength(String) method in
InternalSpelExpressionParser (in conjunction with gh-30325), an attempt
to evaluate a null reference as a SpEL expression now results in a
NullPointerException.

To address both of these issues,
TemplateAwareExpressionParser.parseExpression() and
SpelExpressionParser.parseRaw() now reject null and empty SpEL
expressions.

See gh-30371
Closes gh-30373
This commit is contained in:
Sam Brannen
2023-04-25 13:16:10 +02:00
parent 5afd94f90f
commit 964950a8b9
4 changed files with 43 additions and 2 deletions

View File

@@ -30,6 +30,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* @author Andy Clement
@@ -72,6 +73,13 @@ class TemplateExpressionParsingTests extends AbstractExpressionTests {
private final SpelExpressionParser parser = new SpelExpressionParser();
@Test
void nullTemplateExpressionIsRejected() {
assertThatIllegalArgumentException()
.isThrownBy(() -> parser.parseExpression(null, DEFAULT_TEMPLATE_PARSER_CONTEXT))
.withMessage("'expressionString' must not be null");
}
@Test
void parsingSimpleTemplateExpression01() {
Expression expr = parser.parseExpression("hello ${'world'}", DEFAULT_TEMPLATE_PARSER_CONTEXT);

View File

@@ -33,6 +33,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.springframework.expression.spel.SpelMessage.MISSING_CONSTRUCTOR_ARGS;
import static org.springframework.expression.spel.SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING;
import static org.springframework.expression.spel.SpelMessage.NON_TERMINATING_QUOTED_STRING;
@@ -53,6 +54,32 @@ class SpelParserTests {
private final SpelExpressionParser parser = new SpelExpressionParser();
@Test
void nullExpressionIsRejected() {
assertNullOrEmptyExpressionIsRejected(() -> parser.parseExpression(null));
assertNullOrEmptyExpressionIsRejected(() -> parser.parseRaw(null));
}
@Test
void emptyExpressionIsRejected() {
assertNullOrEmptyExpressionIsRejected(() -> parser.parseExpression(""));
assertNullOrEmptyExpressionIsRejected(() -> parser.parseRaw(""));
}
@Test
void blankExpressionIsRejected() {
assertNullOrEmptyExpressionIsRejected(() -> parser.parseExpression(" "));
assertNullOrEmptyExpressionIsRejected(() -> parser.parseExpression("\t\n"));
assertNullOrEmptyExpressionIsRejected(() -> parser.parseRaw(" "));
assertNullOrEmptyExpressionIsRejected(() -> parser.parseRaw("\t\n"));
}
private static void assertNullOrEmptyExpressionIsRejected(ThrowingCallable throwingCallable) {
assertThatIllegalArgumentException()
.isThrownBy(throwingCallable)
.withMessage("'expressionString' must not be null or blank");
}
@Test
void theMostBasic() {
SpelExpression expr = parser.parseRaw("2");