This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch legacy-regexp in repository https://gitbox.apache.org/repos/asf/james-jsieve.git
commit c8d9db2356bff4ced6fa02c49b869ac639d93630 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]
