diff --git a/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java b/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java index b970baaba57..c71b0785214 100644 --- a/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java +++ b/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java @@ -23,11 +23,13 @@ import java.util.List; import java.util.Map; import java.util.function.Predicate; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; import java.util.stream.Stream; import com.fasterxml.jackson.annotation.JsonInclude; import org.jspecify.annotations.Nullable; +import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException; import org.springframework.boot.actuate.endpoint.OperationResponseBody; import org.springframework.boot.actuate.endpoint.SanitizableData; import org.springframework.boot.actuate.endpoint.Sanitizer; @@ -87,11 +89,21 @@ public class EnvironmentEndpoint { EnvironmentDescriptor getEnvironmentDescriptor(@Nullable String pattern, boolean showUnsanitized) { if (StringUtils.hasText(pattern)) { - return getEnvironmentDescriptor(Pattern.compile(pattern).asPredicate(), showUnsanitized); + return getEnvironmentDescriptor(parsePattern(pattern).asPredicate(), showUnsanitized); } return getEnvironmentDescriptor((name) -> true, showUnsanitized); } + private Pattern parsePattern(String pattern) { + try { + return Pattern.compile(pattern); + } + catch (PatternSyntaxException ex) { + throw new InvalidEndpointRequestException("Failed to parse regular expression: " + pattern, + "Invalid regular expression", ex); + } + } + private EnvironmentDescriptor getEnvironmentDescriptor(Predicate propertyNamePredicate, boolean showUnsanitized) { List propertySources = new ArrayList<>(); diff --git a/module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java b/module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java index b78025d25e5..d4d80f75eb0 100644 --- a/module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java +++ b/module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java @@ -23,11 +23,13 @@ import java.math.BigInteger; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.regex.PatternSyntaxException; import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException; import org.springframework.boot.actuate.endpoint.Show; import org.springframework.boot.actuate.env.EnvironmentEndpoint.EnvironmentDescriptor; import org.springframework.boot.actuate.env.EnvironmentEndpoint.EnvironmentEntryDescriptor; @@ -50,6 +52,7 @@ import org.springframework.core.io.InputStreamSource; import org.springframework.mock.env.MockPropertySource; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** * Tests for {@link EnvironmentEndpoint}. @@ -134,6 +137,15 @@ class EnvironmentEndpointTests { }); } + @Test + void responseWhenPatternIsInvalidThrowsInvalidEndpointRequestException() { + ConfigurableEnvironment environment = emptyEnvironment(); + EnvironmentEndpoint endpoint = new EnvironmentEndpoint(environment, Collections.emptyList(), Show.ALWAYS); + assertThatExceptionOfType(InvalidEndpointRequestException.class).isThrownBy(() -> endpoint.environment("[")) + .withMessageContaining("Failed to parse regular expression: [") + .withCauseInstanceOf(PatternSyntaxException.class); + } + @Test void compositeSourceIsHandledCorrectly() { ConfigurableEnvironment environment = emptyEnvironment();