From 7b553d9093502bb5c9a5efa3eeb39ccd7bc8c046 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 19 Jun 2025 08:53:43 -0700 Subject: [PATCH] Protect against null names when filter is applied more than once Update `FilteredIterableConfigurationPropertiesSource` to fix a regression caused by commit 8f14dca1 that occurs if the `filter()` method is called on an already filtered source. Fixes gh-46032 --- ...dIterableConfigurationPropertiesSource.java | 3 +++ ...ableConfigurationPropertiesSourceTests.java | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSource.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSource.java index a5e0ef2af62..961beceb92a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSource.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSource.java @@ -41,6 +41,9 @@ class FilteredIterableConfigurationPropertiesSource extends FilteredConfiguratio this.filteredNames = new ConfigurationPropertyName[filterableNames.length]; this.numerOfFilteredNames = 0; for (ConfigurationPropertyName name : filterableNames) { + if (name == null) { + break; + } if (filter.test(name)) { this.filteredNames[this.numerOfFilteredNames++] = name; } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSourceTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSourceTests.java index c8367b65415..62df388ca4d 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSourceTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSourceTests.java @@ -74,6 +74,24 @@ class FilteredIterableConfigurationPropertiesSourceTests extends FilteredConfigu .containsExactly("a", "b", "c"); } + @Test + void iteratorWhenSpringPropertySourceAndAnotherFilterFiltersNames() { + IterableConfigurationPropertySource testSource = (IterableConfigurationPropertySource) createTestSource(); + Map map = new LinkedHashMap<>(); + for (ConfigurationPropertyName name : testSource) { + map.put(name.toString(), testSource.getConfigurationProperty(name).getValue()); + } + PropertySource propertySource = new OriginTrackedMapPropertySource("test", map, true); + SpringConfigurationPropertySource source = SpringConfigurationPropertySource.from(propertySource); + IterableConfigurationPropertySource filtered = (IterableConfigurationPropertySource) source + .filter(this::noBrackets); + IterableConfigurationPropertySource secondFiltered = filtered.filter((name) -> !name.toString().contains("c")); + assertThat(Extractors.byName("filteredNames").apply(filtered)).isNotNull(); + assertThat(secondFiltered.iterator()).toIterable() + .extracting(ConfigurationPropertyName::toString) + .containsExactly("a", "b"); + } + @Test void containsDescendantOfWhenSpringPropertySourceUsesContents() { Map map = new LinkedHashMap<>();