This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch WW-5095-cherry-pick in repository https://gitbox.apache.org/repos/asf/struts.git
commit 8bbe1949e17d58e1b5aef9c71e1279ad12ad7ba7 Author: Lukasz Lenart <lukaszlen...@apache.org> AuthorDate: Wed Nov 11 07:28:07 2020 +0100 Avoids recursion in tags --- .../org/apache/struts2/components/Component.java | 11 ++++++++++- .../java/org/apache/struts2/components/UIBean.java | 15 ++++++++------- .../apache/struts2/views/jsp/ui/AbstractUITag.java | 8 ++------ .../org/apache/struts2/components/UIBeanTest.java | 21 +++++++++++++++++++++ .../org/apache/struts2/util/StrutsUtilTest.java | 15 +++++++++++++++ .../struts2/views/java/simple/AbstractTest.java | 14 +++++++------- 6 files changed, 63 insertions(+), 21 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/components/Component.java b/core/src/main/java/org/apache/struts2/components/Component.java index e6c13d3..9d6742f 100644 --- a/core/src/main/java/org/apache/struts2/components/Component.java +++ b/core/src/main/java/org/apache/struts2/components/Component.java @@ -300,7 +300,7 @@ public class Component { * expression otherwise. */ protected String completeExpressionIfAltSyntax(String expr) { - if (altSyntax()) { + if (altSyntax() && !ComponentUtils.containsExpression(expr)) { return "%{" + expr + "}"; } return expr; @@ -383,6 +383,15 @@ public class Component { } /** + * Detects if altSyntax is enabled and then checks if expression contains %{...} + * @param expr a string to examined + * @return true if altSyntax is enabled and expr contains %{...} + */ + protected boolean recursion(String expr) { + return ComponentUtils.altSyntax(stack) && ComponentUtils.containsExpression(expr); + } + + /** * Renders an action URL by consulting the {@link org.apache.struts2.dispatcher.mapper.ActionMapper}. * @param action the action * @param namespace the namespace diff --git a/core/src/main/java/org/apache/struts2/components/UIBean.java b/core/src/main/java/org/apache/struts2/components/UIBean.java index f584f97..8c29beb 100644 --- a/core/src/main/java/org/apache/struts2/components/UIBean.java +++ b/core/src/main/java/org/apache/struts2/components/UIBean.java @@ -795,8 +795,11 @@ public abstract class UIBean extends Component { addParameter("nameValue", findValue(value, valueClazz)); } else if (name != null) { String expr = completeExpressionIfAltSyntax(name); - - addParameter("nameValue", findValue(expr, valueClazz)); + if (recursion(name)) { + addParameter("nameValue", expr); + } else { + addParameter("nameValue", findValue(expr, valueClazz)); + } } } else { if (value != null) { @@ -1030,9 +1033,7 @@ public abstract class UIBean extends Component { @StrutsTagAttribute(description="HTML id attribute") public void setId(String id) { - if (id != null) { - this.id = findString(id); - } + this.id = id; } @StrutsTagAttribute(description="The template directory.") @@ -1250,8 +1251,8 @@ public abstract class UIBean extends Component { this.tooltipIconPath = tooltipIconPath; } - public void setDynamicAttributes(Map<String, Object> tagDynamicAttributes) { - for (Map.Entry<String, Object> entry : tagDynamicAttributes.entrySet()) { + public void setDynamicAttributes(Map<String, String> tagDynamicAttributes) { + for (Map.Entry<String, String> entry : tagDynamicAttributes.entrySet()) { String key = entry.getKey(); if (!isValidTagAttribute(key)) { diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java index 3e4b8db..677892e 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java @@ -78,7 +78,7 @@ public abstract class AbstractUITag extends ComponentTagSupport implements Dynam protected String tooltipIconPath; // dynamic attributes. - protected Map<String, Object> dynamicAttributes = new HashMap<>(); + protected Map<String, String> dynamicAttributes = new HashMap<>(); protected void populateParams() { super.populateParams(); @@ -302,11 +302,7 @@ public abstract class AbstractUITag extends ComponentTagSupport implements Dynam } public void setDynamicAttribute(String uri, String localName, Object value) throws JspException { - if (ComponentUtils.altSyntax(getStack()) && ComponentUtils.isExpression(value.toString())) { - dynamicAttributes.put(localName, String.valueOf(ObjectUtils.defaultIfNull(findValue(value.toString()), value))); - } else { - dynamicAttributes.put(localName, value); - } + dynamicAttributes.put(localName, String.valueOf(value)); } } diff --git a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java index 3e8547e..387d6b5 100644 --- a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java +++ b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java @@ -281,6 +281,27 @@ public class UIBeanTest extends StrutsInternalTestCase { assertEquals(value, txtFld.getParameters().get("nameValue")); } + public void testValueParameterRecursion() { + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + + stack.push(new Object() { + public String getMyValue() { + return "%{myBad}"; + } + public String getMyBad() { + throw new IllegalStateException("Recursion detected!"); + } + }); + + TextField txtFld = new TextField(stack, req, res); + txtFld.setName("%{myValue}"); + txtFld.evaluateParams(); + + assertEquals("%{myBad}", txtFld.getParameters().get("nameValue")); + } + public void testSetClass() { String cssClass = "insertCssClassHere"; ValueStack stack = ActionContext.getContext().getValueStack(); diff --git a/core/src/test/java/org/apache/struts2/util/StrutsUtilTest.java b/core/src/test/java/org/apache/struts2/util/StrutsUtilTest.java index 28c4b34..02be0f2 100644 --- a/core/src/test/java/org/apache/struts2/util/StrutsUtilTest.java +++ b/core/src/test/java/org/apache/struts2/util/StrutsUtilTest.java @@ -189,6 +189,21 @@ public class StrutsUtilTest extends StrutsInternalTestCase { assertEquals(obj1, "try: bar"); } + public void testTranslateVariablesRecursion() throws Exception { + stack.push(new Object() { + public String getFoo() { + return "%{bar}"; + } + public String getBar() { + return "bar"; + } + }); + String obj1 = strutsUtil.translateVariables("try: %{foo}"); + + assertNotNull(obj1); + assertEquals("try: %{bar}", obj1); + } + // === Junit Hook protected void setUp() throws Exception { diff --git a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AbstractTest.java b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AbstractTest.java index 00f17fc..f35c03e 100644 --- a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AbstractTest.java +++ b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AbstractTest.java @@ -21,7 +21,6 @@ package org.apache.struts2.views.java.simple; -import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.conversion.impl.XWorkConverter; import com.opensymphony.xwork2.inject.Container; @@ -48,14 +47,15 @@ import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; public abstract class AbstractTest extends TestCase { - private Map<String, String> scriptingAttrs = new HashMap<>(); - private Map<String, String> commonAttrs = new HashMap<>(); - private Map<String, Object> dynamicAttrs = new HashMap<>(); + + private final Map<String, String> scriptingAttrs = new HashMap<>(); + private final Map<String, String> commonAttrs = new HashMap<>(); + private final Map<String, String> dynamicAttrs = new HashMap<>(); protected SimpleTheme theme; protected StringWriter writer; - protected Map map; + protected Map<String, Object> map; protected Template template; protected Map<String, Object> stackContext; @@ -101,7 +101,7 @@ public abstract class AbstractTest extends TestCase { stackContext = new HashMap<>(); context = new TemplateRenderingContext(template, writer, stack, map, null); - stackContext.put(Component.COMPONENT_STACK, new Stack()); + stackContext.put(Component.COMPONENT_STACK, new Stack<>()); ActionContext actionContext = ActionContext.of(stackContext).bind(); request = createNiceMock(HttpServletRequest.class); @@ -183,7 +183,7 @@ public abstract class AbstractTest extends TestCase { } protected void assertDynamicAttrs(String str) { - for (Map.Entry<String, Object> entry : dynamicAttrs.entrySet()) { + for (Map.Entry<String, String> entry : dynamicAttrs.entrySet()) { String substr = entry.getKey() + "=\"" + entry.getValue() + "\""; assertTrue("String [" + substr + "] was not found in [" + str + "]", str.contains(substr)); }