From c29d1c756aae1a84f5199e7a4a16c7280473cb4f Mon Sep 17 00:00:00 2001 From: dbego Date: Tue, 11 Jul 2017 11:05:12 -0400 Subject: [PATCH] Handle possible regexes defensively in NamePatternFilter Previously, if a name contained part of a regex but wasn't actually a regex, a PatternSyntaxException would be thrown and the request would fail. This commit updates NamePatternFilter to catch PatternSyntaxException and treat the regex-like input as a name insteead. See gh-9730 --- .../actuate/endpoint/mvc/NamePatternFilter.java | 17 ++++++++++++----- .../endpoint/mvc/NamePatternFilterTests.java | 8 ++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/NamePatternFilter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/NamePatternFilter.java index 270a507aaa..7cc3ec12c5 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/NamePatternFilter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/NamePatternFilter.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; /** * Utility class that can be used to filter source data using a name regular expression. @@ -31,6 +32,7 @@ import java.util.regex.Pattern; * @author Phillip Webb * @author Sergei Egorov * @author Andy Wilkinson + * @author Dylian Bego * @since 1.3.0 */ abstract class NamePatternFilter { @@ -44,13 +46,13 @@ abstract class NamePatternFilter { } public Map getResults(String name) { - if (!isRegex(name)) { + Pattern pattern = getRegexPattern(name); + if (pattern == null) { // this is not a regex Object value = getValue(this.source, name); Map result = new HashMap(); result.put(name, value); return result; } - Pattern pattern = Pattern.compile(name); ResultCollectingNameCallback resultCollector = new ResultCollectingNameCallback( pattern); getNames(this.source, resultCollector); @@ -58,13 +60,18 @@ abstract class NamePatternFilter { } - private boolean isRegex(String name) { + private Pattern getRegexPattern(String name) { for (String part : REGEX_PARTS) { if (name.contains(part)) { - return true; + try { + return Pattern.compile(name); + } + catch (PatternSyntaxException e) { + return null; + } } } - return false; + return null; } protected abstract void getNames(T source, NameCallback callback); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/NamePatternFilterTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/NamePatternFilterTests.java index 1cdee18298..3ed021000d 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/NamePatternFilterTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/NamePatternFilterTests.java @@ -27,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Phillip Webb * @author Andy Wilkinson + * @author Dylian Bego */ public class NamePatternFilterTests { @@ -38,6 +39,13 @@ public class NamePatternFilterTests { assertThat(filter.isGetNamesCalled()).isFalse(); } + @Test + public void nonRegexThatContainsRegexPart() throws Exception { + MockNamePatternFilter filter = new MockNamePatternFilter(); + assertThat(filter.getResults("*")).containsEntry("*", "*"); + assertThat(filter.isGetNamesCalled()).isFalse(); + } + @Test public void regexRepetitionZeroOrMore() { MockNamePatternFilter filter = new MockNamePatternFilter();