diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecrypt.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecrypt.java index 1a0f6c36c..762fbaa06 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecrypt.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecrypt.java @@ -71,7 +71,7 @@ protected Map decrypt(TextEncryptor encryptor, PropertySources p for (PropertySource propertySource : propertySources) { if (propertySource instanceof EnumerablePropertySource enumerable) { for (String propertyName : enumerable.getPropertyNames()) { - if (visitor.isVisited(propertyName)) { + if (propertyName == null || visitor.isVisited(propertyName)) { continue; } @@ -136,7 +136,7 @@ private IndexedValue getPropertyValues(EnumerablePropertySource source, TextE boolean containsDecrypted = false; Map elements = new HashMap<>(); for (String name : source.getPropertyNames()) { - if (COLLECTION_PROPERTY.matcher(name).matches() && name.startsWith(prefix)) { + if (name != null && COLLECTION_PROPERTY.matcher(name).matches() && name.startsWith(prefix)) { var value = getPropertyValue(source, encryptor, name); elements.put(name, value.value); if (value.isDecrypted) { diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecryptTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecryptTests.java index 20a785c63..a27722ee3 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecryptTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecryptTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.bootstrap.encrypt; +import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.BeforeEach; @@ -230,6 +231,20 @@ void indexedPropertiesWithSimilarNamesAreHandledCorrectly() { then(environment.getProperty("fooBar[0]")).isEqualTo("updated"); } + @Test + void nullKeyedPropertyNamesAreIgnored() { + // Simulates OS environment blocks (seen on Linux/Docker) that can contain + // entries with a null key. + Map sourceWithNullKey = new HashMap<>(); + sourceWithNullKey.put(null, "some-value"); + sourceWithNullKey.put("foo", "{cipher}bar"); + environment.getPropertySources().addFirst(new MapPropertySource("source-1", sourceWithNullKey)); + + decrypt(); + + then(environment.getProperty("foo")).isEqualTo("bar"); + } + private void decrypt() { decrypt(Encryptors.noOpText()); }