Avoids recursion in tags

This commit is contained in:
Lukasz Lenart
2020-11-11 07:28:07 +01:00
parent a6cd7a0c25
commit 8bbe1949e1
6 changed files with 63 additions and 21 deletions
@@ -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;
@@ -382,6 +382,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
@@ -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)) {
@@ -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));
}
}
@@ -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();
@@ -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 {
@@ -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));
}