Skip to content

Commit 3ec3b64

Browse files
mbhavephilwebb
authored andcommitted
Guard against binding non-instantiable types
Update `JavaBeanBinder` so that null instances that are non-instantiable are not bound. Fixes gh-10131
1 parent b7c37c2 commit 3ec3b64

File tree

2 files changed

+45
-7
lines changed
  • spring-boot-project/spring-boot/src

2 files changed

+45
-7
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/JavaBeanBinder.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,17 @@ public BeanSupplier<T> getSupplier(Bindable<T> target) {
168168
}
169169

170170
@SuppressWarnings("unchecked")
171-
public static <T> Bean<T> get(Bindable<T> bindable,
172-
boolean useExistingValueForType) {
171+
public static <T> Bean<T> get(Bindable<T> bindable, boolean canCallGetValue) {
173172
Class<?> type = bindable.getType().resolve();
174173
Supplier<T> value = bindable.getValue();
175-
if (value == null && !isInstantiable(type)) {
176-
return null;
177-
}
178-
if (useExistingValueForType && value != null) {
179-
T instance = value.get();
174+
T instance = null;
175+
if (canCallGetValue && value != null) {
176+
instance = value.get();
180177
type = (instance != null ? instance.getClass() : type);
181178
}
179+
if (instance == null && !isInstantiable(type)) {
180+
return null;
181+
}
182182
Bean<?> bean = Bean.cached;
183183
if (bean == null || !type.equals(bean.getType())) {
184184
bean = new Bean<>(type);

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/BinderTests.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.util.Collections;
2222
import java.util.List;
2323

24+
import javax.validation.Validation;
25+
2426
import org.assertj.core.matcher.AssertionMatcher;
2527
import org.junit.Before;
2628
import org.junit.Rule;
@@ -30,14 +32,21 @@
3032
import org.mockito.Answers;
3133
import org.mockito.InOrder;
3234

35+
import org.springframework.boot.context.properties.bind.validation.ValidationBindHandler;
3336
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
3437
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
38+
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
3539
import org.springframework.boot.context.properties.source.MockConfigurationPropertySource;
3640
import org.springframework.core.annotation.AnnotationUtils;
3741
import org.springframework.core.convert.ConversionFailedException;
42+
import org.springframework.core.env.PropertySource;
3843
import org.springframework.core.env.StandardEnvironment;
44+
import org.springframework.core.io.Resource;
3945
import org.springframework.format.annotation.DateTimeFormat;
4046
import org.springframework.test.context.support.TestPropertySourceUtils;
47+
import org.springframework.validation.Validator;
48+
import org.springframework.validation.annotation.Validated;
49+
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
4150

4251
import static org.assertj.core.api.Assertions.assertThat;
4352
import static org.hamcrest.Matchers.containsString;
@@ -239,6 +248,20 @@ public void assertion(BindException ex) throws AssertionError {
239248
this.binder.bind("foo", target);
240249
}
241250

251+
@Test
252+
public void bindToValidatedBeanWithResourceAndNonEnumerablePropertySource() {
253+
ConfigurationPropertySources.from(new PropertySource<String>("test") {
254+
@Override
255+
public Object getProperty(String name) {
256+
return null;
257+
}
258+
}).forEach(this.sources::add);
259+
Validator validator = new SpringValidatorAdapter(Validation.byDefaultProvider()
260+
.configure().buildValidatorFactory().getValidator());
261+
this.binder.bind("foo", Bindable.of(ResourceBean.class),
262+
new ValidationBindHandler(validator));
263+
}
264+
242265
public static class JavaBean {
243266

244267
private String value;
@@ -265,4 +288,19 @@ public enum ExampleEnum {
265288

266289
}
267290

291+
@Validated
292+
public static class ResourceBean {
293+
294+
private Resource resource;
295+
296+
public Resource getResource() {
297+
return this.resource;
298+
}
299+
300+
public void setResource(Resource resource) {
301+
this.resource = resource;
302+
}
303+
304+
}
305+
268306
}

0 commit comments

Comments
 (0)