After updating to a recent version of spring-boot(2.7.9 -> 2.7.11). We run in a problem with our thymeleaf template, that has a SpEL expression with more than 10000 characters (whitespaces etc. reach the 10000 pretty fast if you want the SpEL readable). The character limit of 10000 (released in version 5.2.24) was released with spring-boot 2.7.11 as the spring-framework was updated to 5.3.27.

Is there a possibility that this MAX_EXPRESSION_LENGTH in the class InternalSpelExpressionParser can be made settable or maybe turned off? In the Issue #30329 and the linked storys I did not find any clue why this change had to be done. If there is any clue, please point me to the direction.

Best regards, Jonas

Comment From: mdeinum

Related: https://github.com/spring-projects/spring-framework/issues/30265

Comment From: sbrannen

As pointed out by @mdeinum, this is indeed related to the discussions in #30265.

@Wosch96, we may consider increasing the max length restriction, but before we do that could you please answer the following questions?

  1. Can you provide an example of one of the SpEL expressions you are using that are longer than 10,000 characters (if not publicly, then perhaps via a private communication channel such as email)?
  2. Would it be possible for you to move some of the logic contained in the SpEL expression to a static utility function or to a method within a registered bean?
  3. If we were to change the max length, what is the smallest "max length" that would be suitable for your application?

Comment From: Wosch96

@sbrannen

In our case, we use thymeleaf to create a template for a class.

Example Class (minimal scaled case):

class X { variable a; variable b; variable c; variable d; variable e;}

Our SpEL function (minimal scaled case):

ctx = class X model.convert(ctx, { "Example header": {"a", "b", "c"} }, "Example header 2": {"d", "e"} }

The convert method handels the further usage of the values. We basically use the SpEL to feed variables and headers to the thymeleaf template.

Right now this SpEL is written without many whitespaces etc. but to keep this SpEL readable (talking about 30 variables and headers +), we ofc used some whitespaces and newlines. This also adds to the expression length and hits the 10000 characters mark. Right now I think we have about 15000 characters.

The class variables keep growing over time as more functionality is added. Therefore, as the SpEL keeps growing we would need a complete new alternative to build our SpEL. Right now, our best choice is to use an older version of the spring-framerwork, which has no MAX_EXPRESSION_LENGTH set.

If we were to change the max length, what is the smallest "max length" that would be suitable for your application?

With the explanation above and the growing expression, I don't think I can declare a max length that can never be reached.

Comment From: rPraml

For our use case, it would be sufficient, if the max-expression-length lives in the SpelParserConfiguration

If set to zero (or MAX_INT), no limitation happens.

Comment From: sbrannen

Hi @Wosch96 and @rPraml,

Thanks for the feedback!

Two more questions...

  1. Am I correct in assuming that you have full control over your use of SpEL (instantiation of the SpelExpressionParser, which EvaluationContext you are using, etc.)?
  2. Are you only using SpEL to evaluate expressions created within your application (i.e., not expressions supplied by external or untrusted sources)?

Comment From: rPraml

@sbrannen 1. yes and 2. yes.

We instantiate a custom parser and pass it to Thymeleaf, so that we can generate HTML reports.

The report definition contains some bigger SpEL expressions that are passed to helper objects (like HTML table generators).

These definitions come from a trusted source and are not editable by the user.

In our case we could pass an individual SpelParserConfiguration, where the limit check is disabled (or set to a high enough value).

Comment From: rPraml

@sbrannen Thanks, the change in https://github.com/spring-projects/spring-framework/commit/aefcb9d2d6ee385c14d83852bee50b0307b42ce4 looks good to me 👍 Will test with next release.

Comment From: tsposato

@sbrannen Thanks, the change in aefcb9d looks good to me 👍 Will test with next release.

We are also running into this issue after upgrade to spring-boot 2.7.18 - where exactly can I configure this?

Comment From: sbrannen

@tsposato, in which context are you running into this issue?

If you are using SpEL programmatically, you can configure the max length when instantiating the SpelParserConfiguration which you then supply to the SpelExpressionParser.

If you are referring to SpEL expressions used within the ApplicationContext -- for example in XML bean definitions, @Value, etc. -- you can specify the max length via a JVM system property or Spring property named spring.context.expression.maxLength beginning with Spring Framework 6.1.3.

See Parser Configuration for details.

Comment From: tsposato

@sbrannen, we are using thymeleaf to create our template (which has a number of embedded base64 images going well over the limit), and then converting it to a PDF so a lot of the SpEL is not visible to us. It looks like spring-boot 2.7.18 uses Spring Framework 5.3.31 so that property doesn't work for my use case.

I'm not really sure what my options are here other than embedding the images in another way besides base64 which is proving somewhat difficult...

Comment From: sbrannen

@tsposato, you will need to configure the SpelExpressionParser that Thymeleaf uses.

See https://github.com/spring-projects/spring-framework/issues/30380#issuecomment-1528978845 above for details.

Comment From: tsposato

@sbrannen 1. yes and 2. yes.

We instantiate a custom parser and pass it to Thymeleaf, so that we can generate HTML reports.

The report definition contains some bigger SpEL expressions that are passed to helper objects (like HTML table generators).

These definitions come from a trusted source and are not editable by the user.

In our case we could pass an individual SpelParserConfiguration, where the limit check is disabled (or set to a high enough value).

Did this work for you? Do you have a snippet of how you did it?