From 67b548dafb5b6efe2cdafe06514e4a022ab60478 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 4 Jun 2018 14:59:29 -0700 Subject: [PATCH] Protect against infinite property include loop Update `ConfigFileApplicationListener` to ensure that a `spring.profiles.include` property that refers to an already processed profile doesn't cause an infinite loop. Closes gh-13361 --- .../context/config/ConfigFileApplicationListener.java | 1 + .../config/ConfigFileApplicationListenerTests.java | 11 +++++++++++ .../test/resources/applicationloop-loop.properties | 1 + .../src/test/resources/applicationloop.properties | 1 + 4 files changed, 14 insertions(+) create mode 100644 spring-boot-project/spring-boot/src/test/resources/applicationloop-loop.properties create mode 100644 spring-boot-project/spring-boot/src/test/resources/applicationloop.properties diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java index 126d5e30d83..92584ec1d37 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java @@ -543,6 +543,7 @@ public class ConfigFileApplicationListener LinkedList existingProfiles = new LinkedList<>(this.profiles); this.profiles.clear(); this.profiles.addAll(includeProfiles); + this.profiles.removeAll(this.processedProfiles); this.profiles.addAll(existingProfiles); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java index f08200a093c..e0be4d14625 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java @@ -892,6 +892,17 @@ public class ConfigFileApplicationListenerTests { assertThat(this.environment.getProperty("value")).isNull(); } + @Test + public void includeLoop() { + // gh-13361 + SpringApplication application = new SpringApplication(Config.class); + application.setWebApplicationType(WebApplicationType.NONE); + this.context = application.run("--spring.config.name=applicationloop"); + ConfigurableEnvironment environment = this.context.getEnvironment(); + assertThat(environment.acceptsProfiles("loop")).isTrue(); + + } + private Condition matchingPropertySource( final String sourceName) { return new Condition( diff --git a/spring-boot-project/spring-boot/src/test/resources/applicationloop-loop.properties b/spring-boot-project/spring-boot/src/test/resources/applicationloop-loop.properties new file mode 100644 index 00000000000..0602540b20b --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/applicationloop-loop.properties @@ -0,0 +1 @@ +spring.profiles.include=loop diff --git a/spring-boot-project/spring-boot/src/test/resources/applicationloop.properties b/spring-boot-project/spring-boot/src/test/resources/applicationloop.properties new file mode 100644 index 00000000000..0602540b20b --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/applicationloop.properties @@ -0,0 +1 @@ +spring.profiles.include=loop