From 49d0ced16c9a3c3d7c477b10c320212a0ca9c3ab Mon Sep 17 00:00:00 2001 From: Igor Motov Date: Fri, 3 Jan 2014 12:44:44 -0500 Subject: [PATCH] Fix potential infinite loop in double wildcard processing Fixes #4610 --- .../org/elasticsearch/common/regex/Regex.java | 3 +++ .../common/regex/RegexTests.java | 27 ++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/elasticsearch/common/regex/Regex.java b/src/main/java/org/elasticsearch/common/regex/Regex.java index 95b9461d48d..c27544f6b84 100644 --- a/src/main/java/org/elasticsearch/common/regex/Regex.java +++ b/src/main/java/org/elasticsearch/common/regex/Regex.java @@ -71,6 +71,9 @@ public class Regex { int nextIndex = pattern.indexOf('*', firstIndex + 1); if (nextIndex == -1) { return str.endsWith(pattern.substring(1)); + } else if (nextIndex == 1) { + // Double wildcard "**" - skipping the first "*" + return simpleMatch(pattern.substring(1), str); } String part = pattern.substring(1, nextIndex); int partIndex = str.indexOf(part); diff --git a/src/test/java/org/elasticsearch/common/regex/RegexTests.java b/src/test/java/org/elasticsearch/common/regex/RegexTests.java index 1272a16d821..88eb7806b1d 100644 --- a/src/test/java/org/elasticsearch/common/regex/RegexTests.java +++ b/src/test/java/org/elasticsearch/common/regex/RegexTests.java @@ -25,25 +25,26 @@ import java.util.Random; import java.util.regex.Pattern; import static org.hamcrest.Matchers.equalTo; + public class RegexTests extends ElasticsearchTestCase { @Test public void testFlags() { - String[] supportedFlags = new String[] { "CASE_INSENSITIVE", "MULTILINE", "DOTALL", "UNICODE_CASE", "CANON_EQ", "UNIX_LINES", - "LITERAL", "COMMENTS", "UNICODE_CHAR_CLASS" }; - int[] flags = new int[] { Pattern.CASE_INSENSITIVE, Pattern.MULTILINE, Pattern.DOTALL, Pattern.UNICODE_CASE, Pattern.CANON_EQ, - Pattern.UNIX_LINES, Pattern.LITERAL, Pattern.COMMENTS, Regex.UNICODE_CHARACTER_CLASS }; + String[] supportedFlags = new String[]{"CASE_INSENSITIVE", "MULTILINE", "DOTALL", "UNICODE_CASE", "CANON_EQ", "UNIX_LINES", + "LITERAL", "COMMENTS", "UNICODE_CHAR_CLASS"}; + int[] flags = new int[]{Pattern.CASE_INSENSITIVE, Pattern.MULTILINE, Pattern.DOTALL, Pattern.UNICODE_CASE, Pattern.CANON_EQ, + Pattern.UNIX_LINES, Pattern.LITERAL, Pattern.COMMENTS, Regex.UNICODE_CHARACTER_CLASS}; Random random = getRandom(); int num = 10 + random.nextInt(100); for (int i = 0; i < num; i++) { - int numFlags = random.nextInt(flags.length+1); + int numFlags = random.nextInt(flags.length + 1); int current = 0; StringBuilder builder = new StringBuilder(); for (int j = 0; j < numFlags; j++) { int index = random.nextInt(flags.length); current |= flags[index]; builder.append(supportedFlags[index]); - if (j < numFlags-1) { + if (j < numFlags - 1) { builder.append("|"); } } @@ -53,4 +54,18 @@ public class RegexTests extends ElasticsearchTestCase { Pattern.compile("\\w\\d{1,2}", current); // accepts the flags? } } + + @Test(timeout = 1000) + public void testDoubleWildcardMatch() { + assertTrue(Regex.simpleMatch("ddd", "ddd")); + assertTrue(Regex.simpleMatch("d*d*d", "dadd")); + assertTrue(Regex.simpleMatch("**ddd", "dddd")); + assertFalse(Regex.simpleMatch("**ddd", "fff")); + assertTrue(Regex.simpleMatch("fff*ddd", "fffabcddd")); + assertTrue(Regex.simpleMatch("fff**ddd", "fffabcddd")); + assertFalse(Regex.simpleMatch("fff**ddd", "fffabcdd")); + assertTrue(Regex.simpleMatch("fff*******ddd", "fffabcddd")); + assertFalse(Regex.simpleMatch("fff******ddd", "fffabcdd")); + } + } \ No newline at end of file