diff --git a/core/src/main/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcher.java b/core/src/main/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcher.java
index cb848868d..24e5e9b35 100644
--- a/core/src/main/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcher.java
+++ b/core/src/main/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcher.java
@@ -18,6 +18,8 @@
*/
package com.opensymphony.xwork2.util;
+import org.apache.commons.lang3.StringUtils;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -57,7 +59,7 @@ import java.util.regex.Pattern;
*
*
*
- * Excaping hasn't been implemented since the intended use of these patterns will be in matching URLs.
+ * Escaping hasn't been implemented since the intended use of these patterns will be in matching URLs.
*
*
* @since 2.1
@@ -75,38 +77,47 @@ public class NamedVariablePatternMatcher implements PatternMatcher 0) {
- List varNames = new ArrayList<>();
- StringBuilder varName = null;
- for (int x=0; x varNames = new ArrayList<>();
+ int s = 0;
+ while (s < len) {
+ int e = data.indexOf('{', s);
+ if (e < 0 && data.indexOf('}') > -1) {
+ throw new IllegalArgumentException("Missing openning '{' in [" + data + "]!");
+ }
+ if (e < 0) {
+ regex.append(Pattern.quote(data.substring(s)));
+ break;
+ }
+ if (e > s) {
+ regex.append(Pattern.quote(data.substring(s, e)));
+ }
+ s = e + 1;
+ e = data.indexOf('}', s);
+ if (e < 0) {
+ return null;
+ }
+ String varName = data.substring(s, e);
+ if (StringUtils.isEmpty(varName)) {
+ throw new IllegalArgumentException("Missing variable name in [" + data + "]!");
+ }
+ varNames.add(varName);
+ regex.append("([^/]+)");
+ s = e + 1;
+ }
+ return new CompiledPattern(Pattern.compile(regex.toString()), varNames);
}
/**
* Tries to process the data against the compiled expression. If successful, the map will contain
* the matched data, using the specified variable names in the original pattern.
*
- * @param map The map of variables
+ * @param map The map of variables
* @param data The data to match
* @param expr The compiled pattern
* @return True if matched, false if not matched, the data was null, or the data was an empty string
@@ -116,8 +127,8 @@ public class NamedVariablePatternMatcher implements PatternMatcher 0) {
Matcher matcher = expr.getPattern().matcher(data);
if (matcher.matches()) {
- for (int x=0; x variableNames;
+ private final Pattern pattern;
+ private final List variableNames;
public CompiledPattern(Pattern pattern, List variableNames) {
diff --git a/core/src/test/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcherTest.java b/core/src/test/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcherTest.java
index e11fb6870..b5eda4f0a 100644
--- a/core/src/test/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcherTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcherTest.java
@@ -37,15 +37,18 @@ public class NamedVariablePatternMatcherTest {
assertNull(matcher.compilePattern(null));
assertNull(matcher.compilePattern(""));
- CompiledPattern pattern = matcher.compilePattern("foo");
- assertEquals("foo", pattern.getPattern().pattern());
+ CompiledPattern pattern = matcher.compilePattern("action.{format}");
+ assertEquals("\\Qaction.\\E([^/]+)", pattern.getPattern().pattern());
+
+ pattern = matcher.compilePattern("foo");
+ assertEquals("\\Qfoo\\E", pattern.getPattern().pattern());
pattern = matcher.compilePattern("foo{jim}");
- assertEquals("foo([^/]+)", pattern.getPattern().pattern());
+ assertEquals("\\Qfoo\\E([^/]+)", pattern.getPattern().pattern());
assertEquals("jim", pattern.getVariableNames().get(0));
pattern = matcher.compilePattern("foo{jim}/{bob}");
- assertEquals("foo([^/]+)/([^/]+)", pattern.getPattern().pattern());
+ assertEquals("\\Qfoo\\E([^/]+)\\Q/\\E([^/]+)", pattern.getPattern().pattern());
assertEquals("jim", pattern.getVariableNames().get(0));
assertEquals("bob", pattern.getVariableNames().get(1));
assertTrue(pattern.getPattern().matcher("foostar/jie").matches());
@@ -53,12 +56,26 @@ public class NamedVariablePatternMatcherTest {
}
@Test(expected = IllegalArgumentException.class)
- public void testCompileWithMismatchedBracketsParses() {
+ public void testCompileWithMissingVariableName() {
+ NamedVariablePatternMatcher matcher = new NamedVariablePatternMatcher();
+
+ matcher.compilePattern("{}");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCompileWithMissingOpeningBracket1() {
NamedVariablePatternMatcher matcher = new NamedVariablePatternMatcher();
matcher.compilePattern("}");
}
+ @Test(expected = IllegalArgumentException.class)
+ public void testCompileWithMissingOpeningBracket2() {
+ NamedVariablePatternMatcher matcher = new NamedVariablePatternMatcher();
+
+ matcher.compilePattern("test}");
+ }
+
@Test
public void testMatch() {
NamedVariablePatternMatcher matcher = new NamedVariablePatternMatcher();