Uploaded image for project: 'Magnolia'
  1. Magnolia
  2. MAGNOLIA-8738

Weird exception in freemarker when rendering empty string from expression (${""})

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Neutral
    • None
    • 6.2.26
    • None
    • None

    Description

      Steps to reproduce

      1. Have freemarker component that renders empty expression (${""})
      2. Render the page causes following stacktrace

       

      Caused by: java.lang.StringIndexOutOfBoundsException: endIndex must be valid
          at org.apache.commons.text.TextStringBuilder.append(TextStringBuilder.java:548) ~[commons-text-1.10.0.jar:1.10.0]
          at org.apache.commons.text.TextStringBuilder.append(TextStringBuilder.java:77) ~[commons-text-1.10.0.jar:1.10.0]
          at info.magnolia.rendering.util.AppendableWriter.write(AppendableWriter.java:66) ~[classes/:?]
          at java.io.Writer.write(Writer.java:290) ~[?:?]
          at java.io.Writer.write(Writer.java:249) ~[?:?]
          at java.io.Writer.append(Writer.java:322) ~[?:?]
          at java.io.Writer.append(Writer.java:366) ~[?:?]
          at java.io.Writer.append(Writer.java:51) ~[?:?]
          at info.magnolia.rendering.util.AppendableWriter.write(AppendableWriter.java:66) ~[classes/:?]
          at java.io.Writer.write(Writer.java:290) ~[?:?]
          at java.io.Writer.write(Writer.java:249) ~[?:?]
          at freemarker.core.DollarVariable.accept(DollarVariable.java:70) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:347) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:389) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.invokeMacroOrFunctionCommonPart(Environment.java:889) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.invokeMacro(Environment.java:825) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.UnifiedCall.accept(UnifiedCall.java:84) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:383) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.invokeNestedContent(Environment.java:633) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.BodyInstruction.accept(BodyInstruction.java:60) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:383) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.invokeMacroOrFunctionCommonPart(Environment.java:889) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.invokeMacro(Environment.java:825) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.UnifiedCall.accept(UnifiedCall.java:84) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:347) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:389) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.invokeMacroOrFunctionCommonPart(Environment.java:889) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.invokeMacro(Environment.java:825) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.UnifiedCall.accept(UnifiedCall.java:84) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:347) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:353) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.visit(Environment.java:353) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.core.Environment.process(Environment.java:326) ~[freemarker-2.3.31.jar:2.3.31]
          at freemarker.template.Template.process(Template.java:383) ~[freemarker-2.3.31.jar:2.3.31]
          at info.magnolia.freemarker.FreemarkerHelper.render(FreemarkerHelper.java:174) ~[magnolia-freemarker-support-6.2.26.jar:?]
          at info.magnolia.rendering.renderer.FreemarkerRenderer.onRender(FreemarkerRenderer.java:100) ~[magnolia-rendering-6.2.26.jar:?]
          at info.magnolia.rendering.renderer.AbstractRenderer.render(AbstractRenderer.java:166) ~[magnolia-rendering-6.2.26.jar:?]
          at jdk.internal.reflect.GeneratedMethodAccessor405.invoke(Unknown Source) ~[?:?]
          at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
          at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
          at info.magnolia.config.source.DefinitionProviderWrapperWithProxyFallback$DirectDelegator.interceptWithReturnValue(DefinitionProviderWrapperWithProxyFallback.java:151) ~[magnolia-configuration-6.2.26.jar:?]
          at info.magnolia.rendering.renderer.FreemarkerRenderer$ByteBuddy$wmpCBbn3.render(Unknown Source) ~[?:?]
          at info.magnolia.rendering.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:120) ~[magnolia-rendering-6.2.26.jar:?]
          at info.magnolia.rendering.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:101) ~[magnolia-rendering-6.2.26.jar:?]
          at info.magnolia.rendering.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:96) ~[magnolia-rendering-6.2.26.jar:?]
          at info.magnolia.rendering.engine.DefaultRenderingEngine$$EnhancerByCGLIB$$704b1c97.render(<generated>) ~[magnolia-rendering-6.2.26.jar:?]
          at info.magnolia.templating.elements.ComponentElement.begin(ComponentElement.java:122) ~[magnolia-templating-6.2.26.jar:?]
          at info.magnolia.templating.renderers.NoScriptRenderer.onRender(NoScriptRenderer.java:103) ~[magnolia-templating-6.2.26.jar:?]

       

       

      This is happening in some special situation when freemarker output is written to TextStringBuilder which might not always be the case as this was happening on some of our components and I could not reproduce it every where (like page template or some other component for example)

      I also don't know what has changed that started causing this as the components that started showing the error have been in use for several years.

       

      As a workraround it seems that it is enough to render e.g. space (${" "}) or if I wrap the component in  'attempt' block that probably changes the "sink" where output is written.

      Also overriding the info.magnolia.rendering.util.AppendableWriter#write with something like this seems to fix the issue

      @Override
      public void write(char[] chars, int start, int end) throws IOException {
          if(end > 0) {
              appendable.append(new String(chars), start, end);
          } 
      } 

       

      Expected results

      No exception

       

      Checklists

        Acceptance criteria

        Attachments

          Activity

            People

              Unassigned Unassigned
              ssaarinen Samuli Saarinen
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Checklists

                  Bug DoR
                  Task DoD