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
If the resulting size of repeated text in a SpEL expression (using the
repeat operator '*') would exceed MAX_REPEATED_TEXT_SIZE, we currently
throw a SpelEvaluationException with the
MAX_REPEATED_TEXT_SIZE_EXCEEDED message.
However, if the calculation of the repeated text size results in
integer overflow, our max size check fails to detect that, and
String#repeat(int) throws a preemptive OutOfMemoryError from which the
application immediately recovers.
To improve diagnostics for users, this commit ensures that we
consistently throw a SpelEvaluationException with the
MAX_REPEATED_TEXT_SIZE_EXCEEDED message when integer overflow occurs.
Closes gh-31341
Prior to this commit the Spring Expression Language (SpEL) was able to
properly parse an expression that uses the safe navigation operator
(?.) with a method that has a `void` return type (for example,
"myObject?.doSomething()"); however, SpEL was not able to evaluate or
compile such expressions.
This commit addresses the evaluation issue by selectively not boxing
the exit type descriptor (for inclusion in the generated bytecode) when
the method's return type is `void`.
This commit addresses the compilation issue by pushing a null object
reference onto the stack in the generated byte code when the method's
return type is `void`.
Closes gh-27421
Prior to this commit, if a Spring Expression Language (SpEL) expression
contained property, field, or method references using the null-safe
navigation operator (?.), the generated AST String representation
incorrectly omitted the '?' characters.
For example, 'myProperty?.myMethod()' had a generated AST string
representation of 'myProperty.myMethod()'.
This commit addresses this by introducing isNullSafe() in
MethodReference and reworking the logic in
CompoundExpression.toStringAST().
Closes gh-31326
Prior to this commit, it was unclear to users and third parties that it
is necessary to manually configure a StandardTypeLocator with a
specific ClassLoader to ensure that the SpEL expression parser is able
to reliably locate user types.
For example, the StandardBeanExpressionResolver in the spring-context
module configures a StandardTypeLocator using the bean ClassLoader of
the corresponding BeanFactory.
This commit improves the documentation to raise awareness of this fact.
Closes gh-26253
Prior to this commit, if a Spring Expression Language (SpEL) expression
contained indexed access to an object, the generated AST String
representation incorrectly included a dot ('.') before the index access.
For example, 'property[0]' had a generated AST string representation of
'property.[0]'.
This commit addresses this by reworking the logic in
CompoundExpression.toStringAST().
Closes gh-30610
Prior to this commit, when an unsupported character such as "ü" was
encountered in a SpEL expression, the error message was:
Cannot handle (252) 'ü'
With this commit, the error message is now similar to:
Unsupported character 'ü' (252) encountered at position 5 in expression.
See gh-30580
Closes gh-30602
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.
Closes gh-30371
This commit introduces infrastructure to differentiate between
programmatic setting of a variable in an EvaluationContext versus the
assignment of a variable within a SpEL expression using the assignment
operator (=). In addition, this commit disables variable assignment
within expressions when using the SimpleEvaluationContext.
Closes gh-30326
This commit introduces support for limiting the maximum length of a
string resulting from the concatenation operator (+) in SpEL
expressions.
Closes gh-30324
This commit changes the max regex length in SpEL expressions from 1024
to 1000 in order to consistently use "round" numbers for recently
introduced limits.
See gh-30265
This commit increases the max regex length in SpEL expressions from 256
to 1024 in order to support use cases where a regex may be rather long
without necessarily increasing the complexity of the regex.
Closes gh-30265
This commit refactors some AssertJ assertions into more idiomatic and
readable ones. Using the dedicated assertion instead of a generic one
will produce more meaningful error messages.
For instance, consider collection size:
```
// expected: 5 but was: 2
assertThat(collection.size()).equals(5);
// Expected size: 5 but was: 2 in: [1, 2]
assertThat(collection).hasSize(5);
```
Closes gh-30104
Supplying a large regular expression to the `matches` operator in a
SpEL expression can result in errors that are not very helpful to the
user.
This commit improves the diagnostics in SpEL for the `matches` operator
by throwing a SpelEvaluationException with a meaningful error message
to better assist the user.
Closes gh-30144
Attempting to create repeated text in a SpEL expression using the
repeat operator can result in errors that are not very helpful to the
user.
This commit improves the diagnostics in SpEL for the repeat operator by
throwing a SpelEvaluationException with a meaningful error message in
order to better assist the user.
Closes gh-30142
Prior to this commit, the pattern cache for the SpEL `matches` operator
only applied to expressions such as the following where the same
`matches` operator is invoked multiple times with different input:
"map.keySet().?[#this matches '.+xyz']"
The pattern cache did not apply to expressions such as the following
where the same pattern ('.+xyz') is used in multiple `matches`
operations:
"foo matches '.+xyz' AND bar matches '.+xyz'"
This commit addresses this by moving the instance of the pattern cache
map from OperatorMatches to InternalSpelExpressionParser so that the
cache can be reused for all `matches` operations for the given parser.
Closes gh-30140
This commit ensures that methods declared in java.lang.Object (such as
toString() can be invoked on a JDK proxy instance in a SpEL expression.
Closes gh-25316