From e7fd31a5bfca27b96182edbacdaa1683be5ef753 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Wed, 22 May 2024 15:02:08 +0800 Subject: [PATCH] Resolve nested placeholders if value is `CharSequence` Fix GH-34195 --- ...rationPropertySourcesPropertyResolver.java | 5 ++- ...nPropertySourcesPropertyResolverTests.java | 37 ++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolver.java index 9cb2d77b7364..ffa2f6b1bf1d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolver.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolver.java @@ -27,6 +27,7 @@ * underlying sources if the name is a value {@link ConfigurationPropertyName}. * * @author Phillip Webb + * @author Yanming Zhou */ class ConfigurationPropertySourcesPropertyResolver extends AbstractPropertyResolver { @@ -76,8 +77,8 @@ private T getProperty(String key, Class targetValueType, boolean resolveN if (value == null) { return null; } - if (resolveNestedPlaceholders && value instanceof String string) { - value = resolveNestedPlaceholders(string); + if (resolveNestedPlaceholders && value instanceof CharSequence cs) { + value = resolveNestedPlaceholders(cs.toString()); } return convertValueIfNecessary(value, targetValueType); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolverTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolverTests.java index 8032febc231e..e816575c4edb 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolverTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/source/ConfigurationPropertySourcesPropertyResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ * Tests for {@link ConfigurationPropertySourcesPropertyResolver}. * * @author Phillip Webb + * @author Yanming Zhou */ class ConfigurationPropertySourcesPropertyResolverTests { @@ -113,6 +114,40 @@ void getPropertyAsTypeWhenHasPlaceholder() { assertThat(environment.getProperty("v2", Integer.class)).isOne(); } + @Test // gh-34195 + void resolveNestedPlaceholdersIfValueIsCharSequence() { + ResolverEnvironment environment = new ResolverEnvironment(); + MockPropertySource propertySource = new MockPropertySource(); + propertySource.withProperty("v1", "1"); + propertySource.withProperty("v2", new CharSequence() { + + static final String underlying = "${v1}"; + + @Override + public int length() { + return underlying.length(); + } + + @Override + public char charAt(int index) { + return underlying.charAt(index); + } + + @Override + public CharSequence subSequence(int start, int end) { + return underlying.subSequence(start, end); + } + + @Override + public String toString() { + return underlying; + } + }); + environment.getPropertySources().addFirst(propertySource); + assertThat(environment.getProperty("v2")).isEqualTo("1"); + assertThat(environment.getProperty("v2", Integer.class)).isOne(); + } + private CountingMockPropertySource createMockPropertySource(StandardEnvironment environment, boolean attach) { CountingMockPropertySource propertySource = new CountingMockPropertySource(); propertySource.withProperty("spring", "boot");