You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2022/10/19 10:22:39 UTC
[struts] branch WW-3529-named-pattern created (now 993c4c4ca)
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a change to branch WW-3529-named-pattern
in repository https://gitbox.apache.org/repos/asf/struts.git
at 993c4c4ca WW-3529 Fixes using RegEx related characters in named pattern
This branch includes the following new commits:
new 993c4c4ca WW-3529 Fixes using RegEx related characters in named pattern
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[struts] 01/01: WW-3529 Fixes using RegEx related characters in named pattern
Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch WW-3529-named-pattern
in repository https://gitbox.apache.org/repos/asf/struts.git
commit 993c4c4cab21ace8970d094da03291b21547ab83
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Wed Oct 19 12:22:31 2022 +0200
WW-3529 Fixes using RegEx related characters in named pattern
---
.../xwork2/util/NamedVariablePatternMatcher.java | 67 +++++++++++++---------
.../util/NamedVariablePatternMatcherTest.java | 27 +++++++--
2 files changed, 61 insertions(+), 33 deletions(-)
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;
* </table>
*
* <p>
- * 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.
* </p>
*
* @since 2.1
@@ -75,38 +77,47 @@ public class NamedVariablePatternMatcher implements PatternMatcher<NamedVariable
* @return The compiled pattern, null if the pattern was null or empty
*/
public CompiledPattern compilePattern(String data) {
+ if (StringUtils.isEmpty(data)) {
+ return null;
+ }
+
+ int len = data.length();
StringBuilder regex = new StringBuilder();
- if (data != null && data.length() > 0) {
- List<String> varNames = new ArrayList<>();
- StringBuilder varName = null;
- for (int x=0; x<data.length(); x++) {
- char c = data.charAt(x);
- switch (c) {
- case '{' : varName = new StringBuilder(); break;
- case '}' : if (varName == null) {
- throw new IllegalArgumentException("Mismatched braces in pattern");
- }
- varNames.add(varName.toString());
- regex.append("([^/]+)");
- varName = null;
- break;
- default : if (varName == null) {
- regex.append(c);
- } else {
- varName.append(c);
- }
- }
+ List<String> 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 + "]!");
}
- return new CompiledPattern(Pattern.compile(regex.toString()), varNames);
+ varNames.add(varName);
+ regex.append("([^/]+)");
+ s = e + 1;
}
- return null;
+ 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<NamedVariable
if (data != null && data.length() > 0) {
Matcher matcher = expr.getPattern().matcher(data);
if (matcher.matches()) {
- for (int x=0; x<expr.getVariableNames().size(); x++) {
- map.put(expr.getVariableNames().get(x), matcher.group(x+1));
+ for (int x = 0; x < expr.getVariableNames().size(); x++) {
+ map.put(expr.getVariableNames().get(x), matcher.group(x + 1));
}
return true;
}
@@ -129,8 +140,8 @@ public class NamedVariablePatternMatcher implements PatternMatcher<NamedVariable
* Stores the compiled pattern and the variable names matches will correspond to.
*/
public static class CompiledPattern {
- private Pattern pattern;
- private List<String> variableNames;
+ private final Pattern pattern;
+ private final List<String> variableNames;
public CompiledPattern(Pattern pattern, List<String> 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();