From 6e87474f9ad0549f07dd2c37d50a9ccd0977c6e5 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Thu, 21 Jun 2018 09:19:46 +0200 Subject: [PATCH] Validates action, namespace and method in the same way --- .../org/apache/struts2/StrutsConstants.java | 5 + .../mapper/DefaultActionMapper.java | 35 +++- .../mapper/DefaultActionMapperTest.java | 197 ++++++++++-------- .../apache/struts2/rest/RestActionMapper.java | 2 +- 4 files changed, 150 insertions(+), 89 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java index d01e150886..81a4f803ae 100644 --- a/core/src/main/java/org/apache/struts2/StrutsConstants.java +++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java @@ -282,6 +282,11 @@ public final class StrutsConstants { public static final String STRUTS_EXPRESSION_PARSER = "struts.expression.parser"; + /** namespaces names' whitelist **/ + public static final String STRUTS_ALLOWED_NAMESPACE_NAMES = "struts.allowed.namespace.names"; + /** default namespace name to use when namespace didn't match the whitelist **/ + public static final String STRUTS_DEFAULT_NAMESPACE_NAME = "struts.default.namespace.name"; + /** actions names' whitelist **/ public static final String STRUTS_ALLOWED_ACTION_NAMES = "struts.allowed.action.names"; /** default action name to use when action didn't match the whitelist **/ diff --git a/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java b/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java index 224e36a7c1..95bd5c1639 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java @@ -31,7 +31,6 @@ import org.apache.struts2.RequestUtils; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.StrutsException; import org.apache.struts2.util.PrefixTrie; import javax.servlet.http.HttpServletRequest; @@ -117,6 +116,10 @@ public class DefaultActionMapper implements ActionMapper { protected boolean allowSlashesInActionNames = false; protected boolean alwaysSelectFullNamespace = false; protected PrefixTrie prefixTrie = null; + + protected Pattern allowedNamespaceNames = Pattern.compile("[a-zA-Z0-9._/\\-]*"); + protected String defaultNamespaceName = "/"; + protected Pattern allowedActionNames = Pattern.compile("[a-zA-Z0-9._!/\\-]*"); protected String defaultActionName = "index"; @@ -202,6 +205,16 @@ public void setAlwaysSelectFullNamespace(String alwaysSelectFullNamespace) { this.alwaysSelectFullNamespace = BooleanUtils.toBoolean(alwaysSelectFullNamespace); } + @Inject(value = StrutsConstants.STRUTS_ALLOWED_NAMESPACE_NAMES, required = false) + public void setAllowedNamespaceNames(String allowedNamespaceNames) { + this.allowedNamespaceNames = Pattern.compile(allowedNamespaceNames); + } + + @Inject(value = StrutsConstants.STRUTS_DEFAULT_NAMESPACE_NAME, required = false) + public void setDefaultNamespaceName(String defaultNamespaceName) { + this.defaultNamespaceName = defaultNamespaceName; + } + @Inject(value = StrutsConstants.STRUTS_ALLOWED_ACTION_NAMES, required = false) public void setAllowedActionNames(String allowedActionNames) { this.allowedActionNames = Pattern.compile(allowedActionNames); @@ -389,10 +402,28 @@ protected void parseNameAndNamespace(String uri, ActionMapping mapping, Configur } } - mapping.setNamespace(namespace); + mapping.setNamespace(cleanupNamespaceName(namespace)); mapping.setName(cleanupActionName(name)); } + /** + * Checks namespace name against allowed pattern if not matched returns default namespace + * + * @param rawNamespace name extracted from URI + * @return safe namespace name + */ + protected String cleanupNamespaceName(final String rawNamespace) { + if (allowedNamespaceNames.matcher(rawNamespace).matches()) { + return rawNamespace; + } else { + LOG.warn( + "{} did not match allowed namespace names {} - default namespace {} will be used!", + rawNamespace, allowedActionNames, defaultActionName + ); + return defaultNamespaceName; + } + } + /** * Checks action name against allowed pattern if not matched returns default action name * diff --git a/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java b/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java index 3c012e8a88..479494b168 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java @@ -27,12 +27,12 @@ import com.opensymphony.xwork2.config.impl.DefaultConfiguration; import com.opensymphony.xwork2.inject.Container; import org.apache.struts2.ServletActionContext; -import org.apache.struts2.StrutsException; import org.apache.struts2.StrutsInternalTestCase; import org.apache.struts2.result.StrutsResultSupport; import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -65,7 +65,7 @@ public Configuration getConfiguration() { }; } - public void testGetMapping() throws Exception { + public void testGetMapping() { req.setupGetRequestURI("/my/namespace/actionName.action"); req.setupGetServletPath("/my/namespace/actionName.action"); req.setupGetAttribute(null); @@ -79,7 +79,7 @@ public void testGetMapping() throws Exception { assertNull(mapping.getMethod()); } - public void testGetMappingWithMethod() throws Exception { + public void testGetMappingWithMethod() { req.setupGetParameterMap(new HashMap()); req.setupGetRequestURI("/my/namespace/actionName!add.action"); req.setupGetServletPath("/my/namespace/actionName!add.action"); @@ -95,7 +95,7 @@ public void testGetMappingWithMethod() throws Exception { assertEquals("add", mapping.getMethod()); } - public void testGetMappingWithSlashedName() throws Exception { + public void testGetMappingWithSlashedName() { req.setupGetRequestURI("/my/foo/actionName.action"); req.setupGetServletPath("/my/foo/actionName.action"); @@ -111,7 +111,7 @@ public void testGetMappingWithSlashedName() throws Exception { assertNull(mapping.getMethod()); } - public void testGetMappingWithSlashedNameAtRootButNoSlashPackage() throws Exception { + public void testGetMappingWithSlashedNameAtRootButNoSlashPackage() { req.setupGetRequestURI("/foo/actionName.action"); req.setupGetServletPath("/foo/actionName.action"); @@ -127,7 +127,7 @@ public void testGetMappingWithSlashedNameAtRootButNoSlashPackage() throws Except assertNull(mapping.getMethod()); } - public void testGetMappingWithSlashedNameAtRoot() throws Exception { + public void testGetMappingWithSlashedNameAtRoot() { config = new DefaultConfiguration(); PackageConfig pkg = new PackageConfig.Builder("myns") .namespace("/my/namespace").build(); @@ -158,7 +158,7 @@ public Configuration getConfiguration() { - public void testGetMappingWithNamespaceSlash() throws Exception { + public void testGetMappingWithNamespaceSlash() { req.setupGetRequestURI("/my-hh/abc.action"); req.setupGetServletPath("/my-hh/abc.action"); @@ -181,7 +181,7 @@ public void testGetMappingWithNamespaceSlash() throws Exception { assertEquals("my-hh/abc", mapping.getName()); } - public void testGetMappingWithUnknownNamespace() throws Exception { + public void testGetMappingWithUnknownNamespace() { req.setupGetRequestURI("/bo/foo/actionName.action"); req.setupGetServletPath("/bo/foo/actionName.action"); req.setupGetAttribute(null); @@ -195,7 +195,7 @@ public void testGetMappingWithUnknownNamespace() throws Exception { assertNull(mapping.getMethod()); } - public void testGetMappingWithUnknownNamespaceButFullNamespaceSelect() throws Exception { + public void testGetMappingWithUnknownNamespaceButFullNamespaceSelect() { req.setupGetRequestURI("/bo/foo/actionName.action"); req.setupGetServletPath("/bo/foo/actionName.action"); req.setupGetAttribute(null); @@ -210,7 +210,7 @@ public void testGetMappingWithUnknownNamespaceButFullNamespaceSelect() throws Ex assertNull(mapping.getMethod()); } - public void testGetMappingWithActionName_methodAndName() throws Exception { + public void testGetMappingWithActionName_methodAndName() { DefaultActionMapper mapper = new DefaultActionMapper(); mapper.setAllowDynamicMethodCalls("true"); ActionMapping mapping = mapper.getMappingFromActionName("actionName!add"); @@ -218,24 +218,24 @@ public void testGetMappingWithActionName_methodAndName() throws Exception { assertEquals("add", mapping.getMethod()); } - public void testGetMappingWithActionName_name() throws Exception { + public void testGetMappingWithActionName_name() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping mapping = mapper.getMappingFromActionName("actionName"); assertEquals("actionName", mapping.getName()); - assertEquals(null, mapping.getMethod()); + assertNull(mapping.getMethod()); } - public void testGetMappingWithActionName_noDynamicMethod() throws Exception { + public void testGetMappingWithActionName_noDynamicMethod() { DefaultActionMapper mapper = new DefaultActionMapper(); mapper.setAllowDynamicMethodCalls("false"); ActionMapping mapping = mapper.getMappingFromActionName("actionName!add"); assertEquals("actionName!add", mapping.getName()); - assertEquals(null, mapping.getMethod()); + assertNull(mapping.getMethod()); } - public void testGetMappingWithActionName_noDynamicMethodColonPrefix() throws Exception { + public void testGetMappingWithActionName_noDynamicMethodColonPrefix() { - Map parameterMap = new HashMap(); + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.METHOD_PREFIX + "someMethod", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -247,16 +247,16 @@ public void testGetMappingWithActionName_noDynamicMethodColonPrefix() throws Exc ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager); assertEquals("someServletPath", actionMapping.getName()); - assertEquals(null, actionMapping.getMethod()); + assertNull(actionMapping.getMethod()); } - public void testGetMappingWithActionName_null() throws Exception { + public void testGetMappingWithActionName_null() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping mapping = mapper.getMappingFromActionName(null); assertNull(mapping); } - public void testGetUri() throws Exception { + public void testGetUri() { req.setupGetParameterMap(new HashMap()); req.setupGetRequestURI("/my/namespace/actionName.action"); req.setupGetServletPath("/my/namespace/actionName.action"); @@ -268,7 +268,7 @@ public void testGetUri() throws Exception { assertEquals("/my/namespace/actionName.action", mapper.getUriFromActionMapping(mapping)); } - public void testGetUriWithSemicolonPresent() throws Exception { + public void testGetUriWithSemicolonPresent() { req.setupGetParameterMap(new HashMap()); req.setupGetRequestURI("/my/namespace/actionName.action;abc=123rty56"); req.setupGetServletPath("/my/namespace/actionName.action;abc=123rty56"); @@ -280,7 +280,7 @@ public void testGetUriWithSemicolonPresent() throws Exception { assertEquals("/my/namespace/actionName.action", mapper.getUriFromActionMapping(mapping)); } - public void testGetUriWithMethod() throws Exception { + public void testGetUriWithMethod() { req.setupGetParameterMap(new HashMap()); req.setupGetRequestURI("/my/namespace/actionName!add.action"); req.setupGetServletPath("/my/namespace/actionName!add.action"); @@ -293,8 +293,8 @@ public void testGetUriWithMethod() throws Exception { assertEquals("/my/namespace/actionName!add.action", mapper.getUriFromActionMapping(mapping)); } - public void testGetUriWithOriginalExtension() throws Exception { - ActionMapping mapping = new ActionMapping("actionName", "/ns", null, new HashMap()); + public void testGetUriWithOriginalExtension() { + ActionMapping mapping = new ActionMapping("actionName", "/ns", null, new HashMap()); ActionMapping orig = new ActionMapping(); orig.setExtension("foo"); @@ -304,7 +304,7 @@ public void testGetUriWithOriginalExtension() throws Exception { assertEquals("/ns/actionName.foo", mapper.getUriFromActionMapping(mapping)); } - public void testGetMappingWithNoExtension() throws Exception { + public void testGetMappingWithNoExtension() { req.setupGetParameterMap(new HashMap()); req.setupGetRequestURI("/my/namespace/actionName"); req.setupGetServletPath("/my/namespace/actionName"); @@ -320,7 +320,7 @@ public void testGetMappingWithNoExtension() throws Exception { assertNull(mapping.getMethod()); } - public void testGetMappingWithNoExtensionButUriHasExtension() throws Exception { + public void testGetMappingWithNoExtensionButUriHasExtension() { req.setupGetParameterMap(new HashMap()); req.setupGetRequestURI("/my/namespace/actionName.html"); req.setupGetServletPath("/my/namespace/actionName.html"); @@ -340,7 +340,7 @@ public void testGetMappingWithNoExtensionButUriHasExtension() throws Exception { // === test name & namespace === // ============================= - public void testParseNameAndNamespace1() throws Exception { + public void testParseNameAndNamespace1() { ActionMapping actionMapping = new ActionMapping(); DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); @@ -350,7 +350,7 @@ public void testParseNameAndNamespace1() throws Exception { assertEquals(actionMapping.getNamespace(), ""); } - public void testParseNameAndNamespace2() throws Exception { + public void testParseNameAndNamespace2() { ActionMapping actionMapping = new ActionMapping(); DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); @@ -360,7 +360,7 @@ public void testParseNameAndNamespace2() throws Exception { assertEquals(actionMapping.getNamespace(), "/"); } - public void testParseNameAndNamespace3() throws Exception { + public void testParseNameAndNamespace3() { ActionMapping actionMapping = new ActionMapping(); DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); @@ -370,7 +370,7 @@ public void testParseNameAndNamespace3() throws Exception { assertEquals(actionMapping.getNamespace(), "/my"); } - public void testParseNameAndNamespace_NoSlashes() throws Exception { + public void testParseNameAndNamespace_NoSlashes() { ActionMapping actionMapping = new ActionMapping(); DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); @@ -381,7 +381,7 @@ public void testParseNameAndNamespace_NoSlashes() throws Exception { assertEquals(actionMapping.getNamespace(), ""); } - public void testParseNameAndNamespace_AllowSlashes() throws Exception { + public void testParseNameAndNamespace_AllowSlashes() { ActionMapping actionMapping = new ActionMapping(); DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); @@ -397,8 +397,8 @@ public void testParseNameAndNamespace_AllowSlashes() throws Exception { // === test special prefix === // =========================== - public void testActionPrefixWhenDisabled() throws Exception { - Map parameterMap = new HashMap(); + public void testActionPrefixWhenDisabled() { + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -411,8 +411,8 @@ public void testActionPrefixWhenDisabled() throws Exception { assertEquals("someServletPath", actionMapping.getName()); } - public void testActionPrefixWhenEnabled() throws Exception { - Map parameterMap = new HashMap(); + public void testActionPrefixWhenEnabled() { + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -426,8 +426,8 @@ public void testActionPrefixWhenEnabled() throws Exception { assertEquals("myAction", actionMapping.getName()); } - public void testActionPrefixWhenSlashesAndCrossNamespaceDisabled() throws Exception { - Map parameterMap = new HashMap(); + public void testActionPrefixWhenSlashesAndCrossNamespaceDisabled() { + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "my/Action", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -442,8 +442,8 @@ public void testActionPrefixWhenSlashesAndCrossNamespaceDisabled() throws Except assertEquals("my/Action", actionMapping.getName()); } - public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespaceDisabled() throws Exception { - Map parameterMap = new HashMap(); + public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespaceDisabled() { + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "my/Action", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -458,8 +458,8 @@ public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespaceDisabl assertEquals("Action", actionMapping.getName()); } - public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespace() throws Exception { - Map parameterMap = new HashMap(); + public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespace() { + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "my/Action", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -475,8 +475,8 @@ public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespace() thr assertEquals("my/Action", actionMapping.getName()); } - public void testActionPrefixWhenCrossNamespace() throws Exception { - Map parameterMap = new HashMap(); + public void testActionPrefixWhenCrossNamespace() { + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "/my/Action", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -491,8 +491,8 @@ public void testActionPrefixWhenCrossNamespace() throws Exception { assertEquals("/my/Action", actionMapping.getName()); } - public void testActionPrefix_fromImageButton() throws Exception { - Map parameterMap = new HashMap(); + public void testActionPrefix_fromImageButton() { + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction", ""); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.x", ""); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.y", ""); @@ -508,8 +508,8 @@ public void testActionPrefix_fromImageButton() throws Exception { assertEquals("myAction", actionMapping.getName()); } - public void testActionPrefix_fromIEImageButton() throws Exception { - Map parameterMap = new HashMap(); + public void testActionPrefix_fromIEImageButton() { + Map parameterMap = new HashMap<>(); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.x", ""); parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.y", ""); @@ -524,8 +524,8 @@ public void testActionPrefix_fromIEImageButton() throws Exception { assertEquals("myAction", actionMapping.getName()); } - public void testRedirectPrefix() throws Exception { - Map parameterMap = new HashMap(); + public void testRedirectPrefix() { + Map parameterMap = new HashMap<>(); parameterMap.put("redirect:" + "http://www.google.com", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -540,8 +540,8 @@ public void testRedirectPrefix() throws Exception { assertNull(result); } - public void testUnsafeRedirectPrefix() throws Exception { - Map parameterMap = new HashMap(); + public void testUnsafeRedirectPrefix() { + Map parameterMap = new HashMap<>(); parameterMap.put("redirect:" + "http://%{3*4}", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -556,8 +556,8 @@ public void testUnsafeRedirectPrefix() throws Exception { assertNull(result); } - public void testRedirectActionPrefix() throws Exception { - Map parameterMap = new HashMap(); + public void testRedirectActionPrefix() { + Map parameterMap = new HashMap<>(); parameterMap.put("redirectAction:" + "myAction", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -573,8 +573,8 @@ public void testRedirectActionPrefix() throws Exception { assertNull(result); } - public void testUnsafeRedirectActionPrefix() throws Exception { - Map parameterMap = new HashMap(); + public void testUnsafeRedirectActionPrefix() { + Map parameterMap = new HashMap<>(); parameterMap.put("redirectAction:" + "%{3*4}", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -590,8 +590,8 @@ public void testUnsafeRedirectActionPrefix() throws Exception { assertNull(result); } - public void testRedirectActionPrefixWithEmptyExtension() throws Exception { - Map parameterMap = new HashMap(); + public void testRedirectActionPrefixWithEmptyExtension() { + Map parameterMap = new HashMap<>(); parameterMap.put("redirectAction:" + "myAction", ""); StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -608,8 +608,8 @@ public void testRedirectActionPrefixWithEmptyExtension() throws Exception { assertNull(result); } - public void testCustomActionPrefix() throws Exception { - Map parameterMap = new HashMap(); + public void testCustomActionPrefix() { + Map parameterMap = new HashMap<>(); parameterMap.put("foo:myAction", ""); final StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest(); @@ -627,39 +627,39 @@ public void execute(String key, ActionMapping mapping) { assertEquals(actionMapping.getName(), "myAction"); } - public void testDropExtension() throws Exception { + public void testDropExtension() { DefaultActionMapper mapper = new DefaultActionMapper(); String name = mapper.dropExtension("foo.action", new ActionMapping()); - assertTrue("Name not right: "+name, "foo".equals(name)); + assertEquals("Name not right: " + name, "foo", name); name = mapper.dropExtension("foo.action.action", new ActionMapping()); - assertTrue("Name not right: "+name, "foo.action".equals(name)); + assertEquals("Name not right: " + name, "foo.action", name); } - public void testDropExtensionWhenBlank() throws Exception { + public void testDropExtensionWhenBlank() { DefaultActionMapper mapper = new DefaultActionMapper(); mapper.setExtensions("action,,"); String name = mapper.dropExtension("foo.action", new ActionMapping()); - assertTrue("Name not right: "+name, "foo".equals(name)); + assertEquals("Name not right: " + name, "foo", name); name = mapper.dropExtension("foo", new ActionMapping()); - assertTrue("Name not right: "+name, "foo".equals(name)); + assertEquals("Name not right: " + name, "foo", name); assertNull(mapper.dropExtension("foo.bar", new ActionMapping())); assertNull(mapper.dropExtension("foo.", new ActionMapping())); } - public void testDropExtensionEmbeddedDot() throws Exception { + public void testDropExtensionEmbeddedDot() { DefaultActionMapper mapper = new DefaultActionMapper(); mapper.setExtensions("action,,"); String name = mapper.dropExtension("/foo/bar-1.0/baz.action", new ActionMapping()); - assertTrue("Name not right: "+name, "/foo/bar-1.0/baz".equals(name)); + assertEquals("Name not right: " + name, "/foo/bar-1.0/baz", name); name = mapper.dropExtension("/foo/bar-1.0/baz", new ActionMapping()); - assertTrue("Name not right: "+name, "/foo/bar-1.0/baz".equals(name)); + assertEquals("Name not right: " + name, "/foo/bar-1.0/baz", name); } - public void testGetUriFromActionMapper1() throws Exception { + public void testGetUriFromActionMapper1() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setMethod("myMethod"); @@ -670,7 +670,7 @@ public void testGetUriFromActionMapper1() throws Exception { assertEquals("/myNamespace/myActionName!myMethod.action", uri); } - public void testGetUriFromActionMapper2() throws Exception { + public void testGetUriFromActionMapper2() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setMethod("myMethod"); @@ -681,7 +681,7 @@ public void testGetUriFromActionMapper2() throws Exception { assertEquals("/myActionName!myMethod.action", uri); } - public void testGetUriFromActionMapper3() throws Exception { + public void testGetUriFromActionMapper3() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setMethod("myMethod"); @@ -693,7 +693,7 @@ public void testGetUriFromActionMapper3() throws Exception { } - public void testGetUriFromActionMapper4() throws Exception { + public void testGetUriFromActionMapper4() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setName("myActionName"); @@ -703,7 +703,7 @@ public void testGetUriFromActionMapper4() throws Exception { assertEquals("/myActionName.action", uri); } - public void testGetUriFromActionMapper5() throws Exception { + public void testGetUriFromActionMapper5() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setName("myActionName"); @@ -714,7 +714,7 @@ public void testGetUriFromActionMapper5() throws Exception { } // - public void testGetUriFromActionMapper6() throws Exception { + public void testGetUriFromActionMapper6() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setMethod("myMethod"); @@ -725,7 +725,7 @@ public void testGetUriFromActionMapper6() throws Exception { assertEquals("/myNamespace/myActionName!myMethod.action?test=bla", uri); } - public void testGetUriFromActionMapper7() throws Exception { + public void testGetUriFromActionMapper7() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setMethod("myMethod"); @@ -736,7 +736,7 @@ public void testGetUriFromActionMapper7() throws Exception { assertEquals("/myActionName!myMethod.action?test=bla", uri); } - public void testGetUriFromActionMapper8() throws Exception { + public void testGetUriFromActionMapper8() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setMethod("myMethod"); @@ -748,7 +748,7 @@ public void testGetUriFromActionMapper8() throws Exception { } - public void testGetUriFromActionMapper9() throws Exception { + public void testGetUriFromActionMapper9() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setName("myActionName?test=bla"); @@ -758,7 +758,7 @@ public void testGetUriFromActionMapper9() throws Exception { assertEquals("/myActionName.action?test=bla", uri); } - public void testGetUriFromActionMapper10() throws Exception { + public void testGetUriFromActionMapper10() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setName("myActionName?test=bla"); @@ -768,7 +768,7 @@ public void testGetUriFromActionMapper10() throws Exception { assertEquals("/myActionName.action?test=bla", uri); } - public void testGetUriFromActionMapper11() throws Exception { + public void testGetUriFromActionMapper11() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setName("myActionName.action"); @@ -778,7 +778,7 @@ public void testGetUriFromActionMapper11() throws Exception { assertEquals("/myActionName.action", uri); } - public void testGetUriFromActionMapper12() throws Exception { + public void testGetUriFromActionMapper12() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setName("myActionName.action"); @@ -788,7 +788,7 @@ public void testGetUriFromActionMapper12() throws Exception { assertEquals("/myActionName.action", uri); } - public void testGetUriFromActionMapper_justActionAndMethod() throws Exception { + public void testGetUriFromActionMapper_justActionAndMethod() { DefaultActionMapper mapper = new DefaultActionMapper(); ActionMapping actionMapping = new ActionMapping(); actionMapping.setMethod("myMethod"); @@ -799,7 +799,7 @@ public void testGetUriFromActionMapper_justActionAndMethod() throws Exception { assertEquals("myActionName!myMethod", uri); } - public void testGetUriFromActionMapperWhenBlankExtension() throws Exception { + public void testGetUriFromActionMapperWhenBlankExtension() { DefaultActionMapper mapper = new DefaultActionMapper(); mapper.setExtensions(",,"); ActionMapping actionMapping = new ActionMapping(); @@ -811,7 +811,7 @@ public void testGetUriFromActionMapperWhenBlankExtension() throws Exception { assertEquals("/myNamespace/myActionName!myMethod", uri); } - public void testSetExtension() throws Exception { + public void testSetExtension() { DefaultActionMapper mapper = new DefaultActionMapper(); mapper.setExtensions(""); assertNull(mapper.extensions); @@ -828,15 +828,40 @@ public void testSetExtension() throws Exception { assertEquals(Arrays.asList("html", "", "xml"), mapper.extensions); mapper.setExtensions("xml"); - assertEquals(Arrays.asList("xml"), mapper.extensions); + assertEquals(Collections.singletonList("xml"), mapper.extensions); mapper.setExtensions(","); - assertEquals(Arrays.asList(""), mapper.extensions); + assertEquals(Collections.singletonList(""), mapper.extensions); + + + } + + public void testAllowedNamespaceNames() { + DefaultActionMapper mapper = new DefaultActionMapper(); + + String namespace = "/"; + assertEquals(namespace, mapper.cleanupNamespaceName(namespace)); + + namespace = "${namespace}"; + assertEquals(mapper.defaultNamespaceName, mapper.cleanupNamespaceName(namespace)); + + namespace = "${${%{namespace}}}"; + assertEquals(mapper.defaultNamespaceName, mapper.cleanupNamespaceName(namespace)); + + namespace = "${#foo='namespace',#foo}"; + assertEquals(mapper.defaultNamespaceName, mapper.cleanupNamespaceName(namespace)); + + namespace = "/test-namespace/namespace/"; + assertEquals("/test-namespace/namespace/", mapper.cleanupNamespaceName(namespace)); + namespace = "/test_namespace/namespace-test/"; + assertEquals("/test_namespace/namespace-test/", mapper.cleanupNamespaceName(namespace)); + namespace = "/test_namespace/namespace.test/"; + assertEquals("/test_namespace/namespace.test/", mapper.cleanupActionName(namespace)); } - public void testAllowedActionNames() throws Exception { + public void testAllowedActionNames() { DefaultActionMapper mapper = new DefaultActionMapper(); String actionName = "action"; @@ -861,7 +886,7 @@ public void testAllowedActionNames() throws Exception { assertEquals("test!bar.action", mapper.cleanupActionName(actionName)); } - public void testAllowedMethodNames() throws Exception { + public void testAllowedMethodNames() { DefaultActionMapper mapper = new DefaultActionMapper(); assertEquals("", mapper.cleanupMethodName("")); diff --git a/plugins/rest/src/main/java/org/apache/struts2/rest/RestActionMapper.java b/plugins/rest/src/main/java/org/apache/struts2/rest/RestActionMapper.java index 1503ae2249..d2631f0eb8 100644 --- a/plugins/rest/src/main/java/org/apache/struts2/rest/RestActionMapper.java +++ b/plugins/rest/src/main/java/org/apache/struts2/rest/RestActionMapper.java @@ -364,7 +364,7 @@ protected void parseNameAndNamespace(String uri, ActionMapping mapping, Configur name = uri.substring(namespace.length() + 1); } - mapping.setNamespace(namespace); + mapping.setNamespace(cleanupNamespaceName(namespace)); mapping.setName(name); }