From e9d7441e4d63ef0f39992cabb57d8fec6f3aac0f Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Wed, 17 May 2017 11:01:13 -0700 Subject: [PATCH] Restrict scalars in MapBinder to java.lang Fixes gh-9209 --- .../context/properties/bind/MapBinder.java | 8 ++--- .../properties/bind/MapBinderTests.java | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java index 8ccb23bda94..14aafbe6260 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java @@ -16,7 +16,6 @@ package org.springframework.boot.context.properties.bind; -import java.util.Collection; import java.util.Map; import java.util.Properties; @@ -28,6 +27,7 @@ import org.springframework.boot.context.properties.source.ConfigurationPropertyS import org.springframework.boot.context.properties.source.IterableConfigurationPropertySource; import org.springframework.core.CollectionFactory; import org.springframework.core.ResolvableType; +import org.springframework.util.ClassUtils; /** * {@link AggregateBinder} for Maps. @@ -130,9 +130,9 @@ class MapBinder extends AggregateBinder> { private boolean isScalarValue(ConfigurationPropertySource source, ConfigurationPropertyName name) { - if (Map.class.isAssignableFrom(this.valueType.resolve()) - || Collection.class.isAssignableFrom(this.valueType.resolve()) - || this.valueType.isArray()) { + Class resolved = this.valueType.resolve(); + String packageName = ClassUtils.getPackageName(resolved); + if (!packageName.startsWith("java.lang") && !resolved.isEnum()) { return false; } ConfigurationProperty property = source.getConfigurationProperty(name); diff --git a/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/MapBinderTests.java b/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/MapBinderTests.java index e2ed99037c1..9217e0efae3 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/MapBinderTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/MapBinderTests.java @@ -388,4 +388,39 @@ public class MapBinderTests { eq(target), any(), isA(Properties.class)); } + @Test + public void bindToMapShouldNotTreatClassWithStringConstructorAsScalar() throws Exception { + this.sources + .add(new MockConfigurationPropertySource("foo.bar.pattern", "1", "line1")); + BindHandler handler = mock(BindHandler.class, + withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS)); + Bindable> target = Bindable.of(ResolvableType.forClassWithGenerics(Map.class, String.class, Foo.class)); + this.binder.bind("foo", target, handler); + InOrder inOrder = inOrder(handler); + inOrder.verify(handler).onSuccess(eq(ConfigurationPropertyName.of("foo.bar.pattern")), + eq(Bindable.of(String.class)), any(), eq("1")); + inOrder.verify(handler).onSuccess(eq(ConfigurationPropertyName.of("foo")), + eq(target), any(), isA(Map.class)); + } + + public static class Foo { + private String pattern; + + public Foo() { + } + + public Foo(String pattern) { + this.pattern = pattern; + } + + public String getPattern() { + return this.pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + } + }