Skip to content

Commit c98f314

Browse files
committed
Throw ParseException for unsupported character in SpEL expression
Prior to this commit, the SpEL Tokenizer threw an IllegalStateException when an unsupported character was detected in a SpEL expression; however, the Javadoc for ExpressionParser.parseExpression() states that it throws a ParseException if an exception occurred during parsing. This commit addresses that issue by throwing a SpelParseException for an unsupported character in a SpEL expression, using a new UNSUPPORTED_CHARACTER enum constant in SpelMessage. Closes gh-33767
1 parent d22924c commit c98f314

File tree

4 files changed

+18
-17
lines changed

4 files changed

+18
-17
lines changed

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,11 @@ public enum SpelMessage {
291291

292292
/** @since 6.0.13 */
293293
NEGATIVE_REPEATED_TEXT_COUNT(Kind.ERROR, 1081,
294-
"Repeat count ''{0}'' must not be negative");
294+
"Repeat count ''{0}'' must not be negative"),
295+
296+
/** @since 6.1.15 */
297+
UNSUPPORTED_CHARACTER(Kind.ERROR, 1082,
298+
"Unsupported character ''{0}'' ({1}) encountered in expression");
295299

296300

297301
private final Kind kind;

Diff for: spring-expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,7 @@ else if (isTwoCharToken(TokenKind.SAFE_NAVI)) {
266266
raiseParseException(this.pos, SpelMessage.UNEXPECTED_ESCAPE_CHAR);
267267
break;
268268
default:
269-
throw new IllegalStateException(
270-
"Unsupported character '%s' (%d) encountered at position %d in expression."
271-
.formatted(ch, (int) ch, (this.pos + 1)));
269+
raiseParseException(this.pos + 1, SpelMessage.UNSUPPORTED_CHARACTER, ch, (int) ch);
272270
}
273271
}
274272
}

Diff for: spring-expression/src/test/java/org/springframework/expression/spel/AbstractExpressionTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public abstract class AbstractExpressionTests {
4242
protected static final boolean SHOULD_NOT_BE_WRITABLE = false;
4343

4444

45-
protected final ExpressionParser parser = new SpelExpressionParser();
45+
protected final SpelExpressionParser parser = new SpelExpressionParser();
4646

4747
protected final StandardEvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
4848

Diff for: spring-expression/src/test/java/org/springframework/expression/spel/ParsingTests.java

+11-12
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818

1919
import org.junit.jupiter.api.Nested;
2020
import org.junit.jupiter.api.Test;
21+
import org.junit.jupiter.params.ParameterizedTest;
22+
import org.junit.jupiter.params.provider.CsvSource;
2123

2224
import org.springframework.expression.spel.standard.SpelExpression;
23-
import org.springframework.expression.spel.standard.SpelExpressionParser;
2425

2526
import static org.assertj.core.api.Assertions.assertThat;
26-
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
2727

2828
/**
2929
* Parse some expressions and check we get the AST we expect.
@@ -34,10 +34,7 @@
3434
* @author Andy Clement
3535
* @author Sam Brannen
3636
*/
37-
class ParsingTests {
38-
39-
private final SpelExpressionParser parser = new SpelExpressionParser();
40-
37+
class ParsingTests extends AbstractExpressionTests {
4138

4239
@Nested
4340
class Miscellaneous {
@@ -104,12 +101,14 @@ void supportedCharactersInIdentifiers() {
104101
parseCheck("have乐趣()");
105102
}
106103

107-
@Test
108-
void unsupportedCharactersInIdentifiers() {
109-
// Invalid syntax
110-
assertThatIllegalStateException()
111-
.isThrownBy(() -> parser.parseRaw("apple~banana"))
112-
.withMessage("Unsupported character '~' (126) encountered at position 6 in expression.");
104+
@ParameterizedTest(name = "expression = ''{0}''")
105+
@CsvSource(textBlock = """
106+
apple~banana, ~, 6
107+
map[‘c], ‘, 5
108+
A § B, §, 3
109+
""")
110+
void unsupportedCharacter(String expression, char ch, int position) {
111+
parseAndCheckError(expression, SpelMessage.UNSUPPORTED_CHARACTER, position, ch, (int) ch);
113112
}
114113

115114
@Test

0 commit comments

Comments
 (0)