Merge branch '6.0.x'
This commit is contained in:
commit
96fbcb26c9
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -30,6 +30,12 @@ import org.springframework.lang.Nullable;
|
|||
*/
|
||||
public class SpelParserConfiguration {
|
||||
|
||||
/**
|
||||
* Default maximum length permitted for a SpEL expression.
|
||||
* @since 5.2.24
|
||||
*/
|
||||
private static final int DEFAULT_MAX_EXPRESSION_LENGTH = 10_000;
|
||||
|
||||
/** System property to configure the default compiler mode for SpEL expression parsers: {@value}. */
|
||||
public static final String SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME = "spring.expression.compiler.mode";
|
||||
|
||||
|
|
@ -54,6 +60,8 @@ public class SpelParserConfiguration {
|
|||
|
||||
private final int maximumAutoGrowSize;
|
||||
|
||||
private final int maximumExpressionLength;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance with default settings.
|
||||
|
|
@ -102,11 +110,30 @@ public class SpelParserConfiguration {
|
|||
public SpelParserConfiguration(@Nullable SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader,
|
||||
boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize) {
|
||||
|
||||
this(compilerMode, compilerClassLoader, autoGrowNullReferences, autoGrowCollections,
|
||||
maximumAutoGrowSize, DEFAULT_MAX_EXPRESSION_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code SpelParserConfiguration} instance.
|
||||
* @param compilerMode the compiler mode that parsers using this configuration object should use
|
||||
* @param compilerClassLoader the ClassLoader to use as the basis for expression compilation
|
||||
* @param autoGrowNullReferences if null references should automatically grow
|
||||
* @param autoGrowCollections if collections should automatically grow
|
||||
* @param maximumAutoGrowSize the maximum size that a collection can auto grow
|
||||
* @param maximumExpressionLength the maximum length of a SpEL expression;
|
||||
* must be a positive number
|
||||
* @since 5.2.25
|
||||
*/
|
||||
public SpelParserConfiguration(@Nullable SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader,
|
||||
boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize, int maximumExpressionLength) {
|
||||
|
||||
this.compilerMode = (compilerMode != null ? compilerMode : defaultCompilerMode);
|
||||
this.compilerClassLoader = compilerClassLoader;
|
||||
this.autoGrowNullReferences = autoGrowNullReferences;
|
||||
this.autoGrowCollections = autoGrowCollections;
|
||||
this.maximumAutoGrowSize = maximumAutoGrowSize;
|
||||
this.maximumExpressionLength = maximumExpressionLength;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -146,4 +173,12 @@ public class SpelParserConfiguration {
|
|||
return this.maximumAutoGrowSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum number of characters that a SpEL expression can contain.
|
||||
* @since 5.2.25
|
||||
*/
|
||||
public int getMaximumExpressionLength() {
|
||||
return this.maximumExpressionLength;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,13 +93,6 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
|
||||
private static final Pattern VALID_QUALIFIED_ID_PATTERN = Pattern.compile("[\\p{L}\\p{N}_$]+");
|
||||
|
||||
/**
|
||||
* Maximum length permitted for a SpEL expression.
|
||||
* @since 5.2.24
|
||||
*/
|
||||
private static final int MAX_EXPRESSION_LENGTH = 10_000;
|
||||
|
||||
|
||||
private final SpelParserConfiguration configuration;
|
||||
|
||||
// For rules that build nodes, they are stacked here for return
|
||||
|
|
@ -158,8 +151,9 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
}
|
||||
|
||||
private void checkExpressionLength(String string) {
|
||||
if (string.length() > MAX_EXPRESSION_LENGTH) {
|
||||
throw new SpelEvaluationException(SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED, MAX_EXPRESSION_LENGTH);
|
||||
int maxLength = this.configuration.getMaximumExpressionLength();
|
||||
if (string.length() > maxLength) {
|
||||
throw new SpelEvaluationException(SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED, maxLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -164,6 +164,24 @@ public abstract class AbstractExpressionTests {
|
|||
*/
|
||||
protected void evaluateAndCheckError(String expression, Class<?> expectedReturnType, SpelMessage expectedMessage,
|
||||
Object... otherProperties) {
|
||||
|
||||
evaluateAndCheckError(this.parser, expression, expectedReturnType, expectedMessage, otherProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the specified expression and ensure the expected message comes out.
|
||||
* The message may have inserts and they will be checked if otherProperties is specified.
|
||||
* The first entry in otherProperties should always be the position.
|
||||
* @param parser the expression parser to use
|
||||
* @param expression the expression to evaluate
|
||||
* @param expectedReturnType ask the expression return value to be of this type if possible
|
||||
* ({@code null} indicates don't ask for conversion)
|
||||
* @param expectedMessage the expected message
|
||||
* @param otherProperties the expected inserts within the message
|
||||
*/
|
||||
protected void evaluateAndCheckError(ExpressionParser parser, String expression, Class<?> expectedReturnType, SpelMessage expectedMessage,
|
||||
Object... otherProperties) {
|
||||
|
||||
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() -> {
|
||||
Expression expr = parser.parseExpression(expression);
|
||||
assertThat(expr).as("expression").isNotNull();
|
||||
|
|
|
|||
|
|
@ -77,6 +77,26 @@ class EvaluationTests extends AbstractExpressionTests {
|
|||
evaluateAndCheckError(expression, String.class, SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void maxExpressionLengthIsConfigurable() {
|
||||
int maximumExpressionLength = 20_000;
|
||||
|
||||
String expression = "'%s'".formatted("Y".repeat(19_998));
|
||||
assertThat(expression).hasSize(maximumExpressionLength);
|
||||
|
||||
SpelParserConfiguration configuration =
|
||||
new SpelParserConfiguration(null, null, false, false, 0, maximumExpressionLength);
|
||||
ExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
|
||||
Expression expr = parser.parseExpression(expression);
|
||||
String result = expr.getValue(String.class);
|
||||
assertThat(result).hasSize(19_998);
|
||||
|
||||
expression = "'%s'".formatted("Y".repeat(25_000));
|
||||
assertThat(expression).hasSize(25_002);
|
||||
evaluateAndCheckError(parser, expression, String.class, SpelMessage.MAX_EXPRESSION_LENGTH_EXCEEDED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createListsOnAttemptToIndexNull01() throws EvaluationException, ParseException {
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
|
|
|
|||
Loading…
Reference in New Issue