Skip to content

Commit b4963d2

Browse files
committed
Fix legacy environment names in isAncestorOf
Fix the `SystemEnvironmentPropertyMapper.isAncestorOf` implementation to convert names based on their dashed form and to silently ignore any invalid results. Closes gh-14479
1 parent 70c4bae commit b4963d2

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/SystemEnvironmentPropertyMapper.java

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ final class SystemEnvironmentPropertyMapper implements PropertyMapper {
3939
@Override
4040
public PropertyMapping[] map(ConfigurationPropertyName configurationPropertyName) {
4141
String name = convertName(configurationPropertyName);
42-
String legacyName = convertLegacyName(configurationPropertyName, '_', true);
42+
String legacyName = convertLegacyName(configurationPropertyName);
4343
if (name.equals(legacyName)) {
4444
return new PropertyMapping[] { new PropertyMapping(name, configurationPropertyName) };
4545
}
@@ -62,7 +62,25 @@ public boolean isAncestorOf(ConfigurationPropertyName name, ConfigurationPropert
6262
}
6363

6464
private boolean isLegacyAncestorOf(ConfigurationPropertyName name, ConfigurationPropertyName candidate) {
65-
return ConfigurationPropertyName.of(convertLegacyName(name, '.', false)).isAncestorOf(candidate);
65+
if (!hasDashedEntries(name)) {
66+
return false;
67+
}
68+
StringBuilder legacyCompatibleName = new StringBuilder();
69+
for (int i = 0; i < name.getNumberOfElements(); i++) {
70+
legacyCompatibleName.append((i != 0) ? "." : "");
71+
legacyCompatibleName.append(name.getElement(i, Form.DASHED).replace('-', '.'));
72+
}
73+
return ConfigurationPropertyName.isValid(legacyCompatibleName)
74+
&& ConfigurationPropertyName.of(legacyCompatibleName).isAncestorOf(candidate);
75+
}
76+
77+
boolean hasDashedEntries(ConfigurationPropertyName name) {
78+
for (int i = 0; i < name.getNumberOfElements(); i++) {
79+
if (name.getElement(i, Form.DASHED).indexOf('-') != -1) {
80+
return true;
81+
}
82+
}
83+
return false;
6684
}
6785

6886
private ConfigurationPropertyName convertName(String propertySourceName) {
@@ -89,21 +107,19 @@ private String convertName(ConfigurationPropertyName name, int numberOfElements)
89107
return result.toString();
90108
}
91109

92-
private String convertLegacyName(ConfigurationPropertyName name, char joinChar, boolean uppercase) {
110+
private String convertLegacyName(ConfigurationPropertyName name) {
93111
StringBuilder result = new StringBuilder();
94112
for (int i = 0; i < name.getNumberOfElements(); i++) {
95113
if (result.length() > 0) {
96-
result.append(joinChar);
114+
result.append("_");
97115
}
98-
String element = name.getElement(i, Form.ORIGINAL);
99-
result.append(convertLegacyNameElement(element, joinChar, uppercase));
116+
result.append(convertLegacyNameElement(name.getElement(i, Form.ORIGINAL)));
100117
}
101118
return result.toString();
102119
}
103120

104-
private Object convertLegacyNameElement(String element, char joinChar, boolean uppercase) {
105-
String converted = element.replace('-', joinChar);
106-
return !uppercase ? converted : converted.toUpperCase(Locale.ENGLISH);
121+
private Object convertLegacyNameElement(String element) {
122+
return element.replace('-', '_').toUpperCase(Locale.ENGLISH);
107123
}
108124

109125
private CharSequence processElementValue(CharSequence value) {

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/SystemEnvironmentPropertyMapperTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,12 @@ void isAncestorOfConsidersLegacyNames() {
8383
assertThat(getMapper().isAncestorOf(name, ConfigurationPropertyName.of("my.boot.property"))).isFalse();
8484
}
8585

86+
@Test
87+
void isAncestorOfWhenCamelCaseSourceConsidersLegacyNames() {
88+
ConfigurationPropertyName name = ConfigurationPropertyName.adapt("my.springBoot", '.');
89+
assertThat(getMapper().isAncestorOf(name, ConfigurationPropertyName.of("my.spring-boot.property"))).isTrue();
90+
assertThat(getMapper().isAncestorOf(name, ConfigurationPropertyName.of("my.springboot.property"))).isTrue();
91+
assertThat(getMapper().isAncestorOf(name, ConfigurationPropertyName.of("my.boot.property"))).isFalse();
92+
}
93+
8694
}

0 commit comments

Comments
 (0)