Commit 1c3f147c authored by Phillip Webb's avatar Phillip Webb

Merge branch '2.2.x'

Closes gh-21598
parents 2ff2d525 af906040
...@@ -27,6 +27,7 @@ import org.yaml.snakeyaml.LoaderOptions; ...@@ -27,6 +27,7 @@ import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.BaseConstructor; import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.error.Mark; import org.yaml.snakeyaml.error.Mark;
import org.yaml.snakeyaml.nodes.MappingNode; import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node; import org.yaml.snakeyaml.nodes.Node;
...@@ -79,7 +80,7 @@ class OriginTrackedYamlLoader extends YamlProcessor { ...@@ -79,7 +80,7 @@ class OriginTrackedYamlLoader extends YamlProcessor {
/** /**
* {@link Constructor} that tracks property origins. * {@link Constructor} that tracks property origins.
*/ */
private class OriginTrackingConstructor extends Constructor { private class OriginTrackingConstructor extends SafeConstructor {
@Override @Override
protected Object constructObject(Node node) { protected Object constructObject(Node node) {
......
...@@ -16,10 +16,15 @@ ...@@ -16,10 +16,15 @@
package org.springframework.boot.json; package org.springframework.boot.json;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
/** /**
* Thin wrapper to adapt Snake {@link Yaml} to {@link JsonParser}. * Thin wrapper to adapt Snake {@link Yaml} to {@link JsonParser}.
...@@ -31,16 +36,36 @@ import org.yaml.snakeyaml.Yaml; ...@@ -31,16 +36,36 @@ import org.yaml.snakeyaml.Yaml;
*/ */
public class YamlJsonParser extends AbstractJsonParser { public class YamlJsonParser extends AbstractJsonParser {
private final Yaml yaml = new Yaml(new TypeLimitedConstructor());
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Map<String, Object> parseMap(String json) { public Map<String, Object> parseMap(String json) {
return parseMap(json, (trimmed) -> new Yaml().loadAs(trimmed, Map.class)); return parseMap(json, (trimmed) -> this.yaml.loadAs(trimmed, Map.class));
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<Object> parseList(String json) { public List<Object> parseList(String json) {
return parseList(json, (trimmed) -> new Yaml().loadAs(trimmed, List.class)); return parseList(json, (trimmed) -> this.yaml.loadAs(trimmed, List.class));
}
private static class TypeLimitedConstructor extends Constructor {
private static final Set<String> SUPPORTED_TYPES;
static {
Set<Class<?>> supportedTypes = new LinkedHashSet<>();
supportedTypes.add(List.class);
supportedTypes.add(Map.class);
SUPPORTED_TYPES = supportedTypes.stream().map(Class::getName)
.collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
}
@Override
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
return (SUPPORTED_TYPES.contains(name)) ? super.getClassForName(name) : null;
}
} }
} }
...@@ -16,18 +16,22 @@ ...@@ -16,18 +16,22 @@
package org.springframework.boot.env; package org.springframework.boot.env;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.yaml.snakeyaml.constructor.ConstructorException;
import org.springframework.boot.origin.OriginTrackedValue; import org.springframework.boot.origin.OriginTrackedValue;
import org.springframework.boot.origin.TextResourceOrigin; import org.springframework.boot.origin.TextResourceOrigin;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/** /**
* Tests for {@link OriginTrackedYamlLoader}. * Tests for {@link OriginTrackedYamlLoader}.
...@@ -116,6 +120,14 @@ class OriginTrackedYamlLoaderTests { ...@@ -116,6 +120,14 @@ class OriginTrackedYamlLoaderTests {
assertThat(getLocation(nullValue)).isEqualTo("28:13"); assertThat(getLocation(nullValue)).isEqualTo("28:13");
} }
@Test
void unsupportedType() throws Exception {
String yaml = "value: !!java.net.URL [!!java.lang.String [!!java.lang.StringBuilder [\"http://localhost:9000/\"]]]";
Resource resource = new ByteArrayResource(yaml.getBytes(StandardCharsets.UTF_8));
this.loader = new OriginTrackedYamlLoader(resource);
assertThatExceptionOfType(ConstructorException.class).isThrownBy(this.loader::load);
}
private OriginTrackedValue getValue(String name) { private OriginTrackedValue getValue(String name) {
if (this.result == null) { if (this.result == null) {
this.result = this.loader.load(); this.result = this.loader.load();
......
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
package org.springframework.boot.json; package org.springframework.boot.json;
import org.junit.Test;
import org.yaml.snakeyaml.constructor.ConstructorException;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/** /**
* Tests for {@link YamlJsonParser}. * Tests for {@link YamlJsonParser}.
* *
...@@ -28,4 +33,10 @@ public class YamlJsonParserTests extends AbstractJsonParserTests { ...@@ -28,4 +33,10 @@ public class YamlJsonParserTests extends AbstractJsonParserTests {
return new YamlJsonParser(); return new YamlJsonParser();
} }
@Test
public void customTypesAreNotLoaded() throws Exception {
assertThatExceptionOfType(ConstructorException.class)
.isThrownBy(() -> getParser().parseMap("{value: !!java.net.URL [\"http://localhost:9000/\"]}"));
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment