This is an automated email from the ASF dual-hosted git repository.
chibenwa pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-jsieve.git
The following commit(s) were added to refs/heads/master by this push:
new a8c9fc9 [ENHANCEMENT] Remove legacy regexp
a8c9fc9 is described below
commit a8c9fc9e9f678211fe5a7831b76f6db155fe44ed
Author: Benoit TELLIER <[email protected]>
AuthorDate: Thu Oct 29 14:33:07 2026 +0100
[ENHANCEMENT] Remove legacy regexp
---
.../apache/jsieve/comparators/ComparatorUtils.java | 69 ----------------------
.../jsieve/comparator/ComparatorUtilsTest.java | 38 +++++-------
2 files changed, 15 insertions(+), 92 deletions(-)
diff --git
a/core/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java
b/core/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java
index 63af3eb..b979cc6 100644
--- a/core/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java
+++ b/core/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java
@@ -183,75 +183,6 @@ public class ComparatorUtils {
return string1.equals(string2);
}
- /**
- * Returns true if the char is a special char for regex
- */
- private static boolean isRegexSpecialChar(char ch) {
- return (ch == '*' || ch == '?' || ch == '+' || ch == '[' || ch == ']'
- || ch == '(' || ch == ')' || ch == '|' || ch == '^'
- || ch == '$' || ch == '.' || ch == '{' || ch == '}' || ch ==
'\\');
- }
-
- /**
- * Returns true if the char is a special char for sieve matching
- */
- private static boolean isSieveMatcherSpecialChar(char ch) {
- return (ch == '*' || ch == '?' || ch == '\\');
- }
-
- /**
- * Converts a Sieve pattern in a java regex pattern.
- *
- * @deprecated no longer used for matching: the resulting regex
- * backtracks catastrophically on globs with several stars.
- * Use {@link #matches(String, String)}.
- */
- @Deprecated
- public static String sieveToJavaRegex(String pattern) {
- int ch;
- StringBuilder buffer = new StringBuilder(2 * pattern.length());
- boolean lastCharWasStar = false;
- for (ch = 0; ch < pattern.length(); ch++) {
- final char nextChar = pattern.charAt(ch);
- switch (nextChar) {
- case '*':
- //
- // Java Matcher has issues with repeated stars
- //
- if (!lastCharWasStar) {
- buffer.append(".*");
- }
- break;
- case '?':
- buffer.append('.');
- break;
- case '\\':
- buffer.append('\\');
- if (ch == pattern.length() - 1)
- buffer.append('\\');
- else if (isSieveMatcherSpecialChar(pattern.charAt(ch + 1)))
- buffer.append(pattern.charAt(++ch));
- else {
- // Undefined escape: the next character stands for itself
- buffer.setLength(buffer.length() - 1);
- final char escaped = pattern.charAt(++ch);
- if (isRegexSpecialChar(escaped))
- buffer.append('\\');
- buffer.append(escaped);
- }
- break;
- default:
- if (isRegexSpecialChar(nextChar))
- buffer.append('\\');
- buffer.append(nextChar);
- break;
- }
- // Workaround for issue with Java Matcher
- lastCharWasStar = '*' == nextChar;
- }
- return buffer.toString();
- }
-
/**
* Method <code>contains<code> answers a boolean indicating if the
parameter
* <code>container</code> contains the parameter <code>contents</code>
using an
diff --git
a/core/src/test/java/org/apache/jsieve/comparator/ComparatorUtilsTest.java
b/core/src/test/java/org/apache/jsieve/comparator/ComparatorUtilsTest.java
index 45b5e8e..1eccbfc 100644
--- a/core/src/test/java/org/apache/jsieve/comparator/ComparatorUtilsTest.java
+++ b/core/src/test/java/org/apache/jsieve/comparator/ComparatorUtilsTest.java
@@ -21,7 +21,9 @@ package org.apache.jsieve.comparator;
import java.util.Random;
+import org.apache.jsieve.comparators.AsciiCasemap;
import org.apache.jsieve.comparators.ComparatorUtils;
+import org.apache.jsieve.comparators.Octet;
import org.apache.jsieve.exception.SievePatternException;
import org.junit.Assert;
import org.junit.Test;
@@ -58,23 +60,6 @@ public class ComparatorUtilsTest {
.matches("[test] a\\x?foo\\bar*", sievematch));
}
- /**
- * The ":matches" version specifies a wildcard match using the characters
- * "*" and "?". "*" matches zero or more characters, and "?" matches a
- * single character. "?" and "*" may be escaped as "\\?" and "\\*" in
- * strings to match against themselves. The first backslash escapes the
- * second backslash; together, they escape the "*". This is awkward, but it
- * is commonplace in several programming languages that use globs and
- * regular expressions.
- */
- @Test
- public void testSieveToJavaRegex() {
- String sievematch = "[test] ?\\\\?\\?*\\\\*\\*\\";
- String res = ComparatorUtils.sieveToJavaRegex(sievematch);
- String expected = "\\[test\\] .\\\\.\\?.*\\\\.*\\*\\\\";
- Assert.assertEquals(expected, res);
- }
-
@Test(timeout = 2000)
public void multiStarGlobShouldMatchInLinearishTime() throws Exception {
StringBuilder target = new StringBuilder();
@@ -94,6 +79,19 @@ public class ComparatorUtilsTest {
"*2\u00e9*^\u00e9*a*a*e*a*a*a*a\u00df*a****\\\\a?*"));
}
+ /**
+ * Exact input found by the fuzzer (GHSA-pfrv-hjfq-x5wr): this glob made
the former regex
+ * translation backtrack catastrophically on a 181-character target.
+ */
+ @Test(timeout = 2000)
+ public void fuzzerFoundGlobShouldMatchInBoundedTime() throws Exception {
+ String glob = "*2\ufffd*^\ufffd*a*a*e*a*a*a*a\u00df*a****\\\\\\a?*";
+ String target =
"\\aA!a*a*a*\ufffd\u00df*a*a*a\u0018*a|*3\ufffd*^\ufffd*a*a*e*a\u059e\u0561*\u0018*a|*2\ufffd*^\ufffd*a*a*e*a*a*a*a\u00df*a*a*a\u0018*a\ufffd*a*a*a*a*a*a*a\u00df*a*a*a\u0018*a|\u0018*^^^^^*a*a*a\u00dfl\ufffd*a*a*aa**e*a\u00df*a*a*a\u0018*a|\u0018a\u0018*\ufffd*a*a|\ufffd*a*a*a\u0018*\u0018a\u0018*\ufffd*a|l\ufffd*\u0018a\u0018*\ufffd*a|\u0005l\ufffd*\u0005";
+ Assert.assertEquals(181, target.length());
+ Assert.assertFalse(new Octet().matches(target, glob));
+ Assert.assertFalse(new AsciiCasemap().matches(target, glob));
+ }
+
@Test
public void wildcardsShouldMatchLineTerminators() throws Exception {
Assert.assertTrue(ComparatorUtils.matches("foo\r\n bar", "foo*bar"));
@@ -125,12 +123,6 @@ public class ComparatorUtilsTest {
Assert.assertFalse(ComparatorUtils.matches("foo", "foo\\"));
}
- @Test
- @SuppressWarnings("deprecation")
- public void regexTranslationShouldHandleUndefinedEscapes() {
- Assert.assertEquals("a\\.b",
ComparatorUtils.sieveToJavaRegex("\\a\\.b"));
- }
-
@Test
public void edgeCases() throws Exception {
assertMatch("", "");
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]