-
Bug
-
Resolution: Unresolved
-
Low
-
None
-
7.19.26, 9.0.1, 8.5.14
-
Severity 3 - Minor
-
-
CtB - Improve Existing
Issue Summary
Original report: here
I found a small bug with com.atlassian.confluence.user.actions.AbstractUserProfileAction#getRenderedAboutMe when called in a Velocity template for an Action class that is extending AbstractUserProfileAction:
- when called as $renderedAboutMe: all good, value is shown
- when called as $action.renderedAboutMe: value is not shown, but literal “$action.renderedAboutMe”, i.e. used value in Velocity is null
- when called as $action.getRenderedAboutMe(): Server error is thrown, with root-cause java.lang.IllegalArgumentException: Attempting to box an already boxed value.
After taking a deep-dive into how Velocity handles html-safe methods, I found out the following:
- According to com.atlassian.velocity.htmlsafe.HtmlSafeMethodNameAnnotator methods starting with “render” or “getRender” (or ending in “Html”) are treated as @HtmlSafe
- Problematic method AbstractUserProfileAction#getRenderedAboutMe returns a com.atlassian.velocity.htmlsafe.HtmlFragment instead of a normal String.
- → These 2 facts collide somehow: The method is treated as being doubly html-safe, which com.atlassian.velocity.htmlsafe.introspection.AnnotatedValue doesn’t like → Exception “Attempting to box an already boxed value” is thrown
I also looked into why it matters how that method is called. (Did that via the stacktrace):
- when called as $renderedAboutMe: Velocity’s introspection is not used, but Struts/OGNL stuff
- → Exception does not occur
- when called as $action.renderedAboutMe: Velocity’s introspection IS used → Exception IS thrown, but swallowed by try block in org.apache.velocity.runtime.parser.node.ASTIdentifier
- → null is used instead
- when called as $action.getRenderedAboutMe(): Velocity’s introspection IS used → Exception IS thrown, and NOT swallowed by org.apache.velocity.runtime.parser.node.ASTMethod
- → Exception bubbles up and is thrown in user’s face
Steps to Reproduce
- Define a Struts Action extending AbstractUserProfileAction and map it to a Velocity template result.
- Call $action.getRenderedAboutMe() from Velocity template.
Expected Results
Renders 'About Me' content.
Actual Results
The below exception is thrown:
Caused by: java.lang.IllegalArgumentException: Attempting to box an already boxed value at com.google.common.base.Preconditions.checkArgument(Preconditions.java:143) at com.atlassian.velocity.htmlsafe.introspection.AnnotatedValue.<init>(AnnotatedValue.java:45) at com.atlassian.velocity.htmlsafe.introspection.AnnotationBoxingMethod.invoke(AnnotationBoxingMethod.java:25) at com.atlassian.velocity.htmlsafe.introspection.UnboxingMethod.invoke(UnboxingMethod.java:28)
Workaround
Bypass Velocity Uberspect by using OGNL shortcut $renderedAboutMe.
- is related to
-
CONFSERVER-97879 Using the foreach directive with a context item that is blocked by the Introspector in a Velocity template will throw an unhandled exception
-
- Closed
-
- relates to
-
CONFSERVER-97828 Methods ending with 'html' whose return value is passed to a Soy template, renders an unexpected String value
-
- Gathering Impact
-