Skip to content

Commit add7375

Browse files
committed
Prevent object creation when loading YAML files.
When creating a new Yaml instance from SnakeYaml to read in a configuration file the instance is now configured that no objects are created automatically.
1 parent 342f3b3 commit add7375

File tree

2 files changed

+87
-7
lines changed

2 files changed

+87
-7
lines changed

src/main/java/org/apache/commons/configuration2/YAMLConfiguration.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
package org.apache.commons.configuration2;
1919

2020
import org.apache.commons.configuration2.ex.ConfigurationException;
21+
import org.apache.commons.configuration2.ex.ConfigurationRuntimeException;
2122
import org.apache.commons.configuration2.io.InputStreamSupport;
2223
import org.apache.commons.configuration2.tree.ImmutableNode;
2324
import org.yaml.snakeyaml.DumperOptions;
2425
import org.yaml.snakeyaml.LoaderOptions;
2526
import org.yaml.snakeyaml.Yaml;
27+
import org.yaml.snakeyaml.constructor.Constructor;
28+
import org.yaml.snakeyaml.representer.Representer;
2629

2730
import java.io.IOException;
2831
import java.io.InputStream;
@@ -65,7 +68,7 @@ public void read(final Reader in) throws ConfigurationException
6568
{
6669
try
6770
{
68-
final Yaml yaml = new Yaml();
71+
final Yaml yaml = createYamlForReading(new LoaderOptions());
6972
final Map<String, Object> map = (Map) yaml.load(in);
7073
load(map);
7174
}
@@ -80,7 +83,7 @@ public void read(final Reader in, final LoaderOptions options)
8083
{
8184
try
8285
{
83-
final Yaml yaml = new Yaml(options);
86+
final Yaml yaml = createYamlForReading(options);
8487
final Map<String, Object> map = (Map) yaml.load(in);
8588
load(map);
8689
}
@@ -117,7 +120,7 @@ public void read(final InputStream in) throws ConfigurationException
117120
{
118121
try
119122
{
120-
final Yaml yaml = new Yaml();
123+
final Yaml yaml = createYamlForReading(new LoaderOptions());
121124
final Map<String, Object> map = (Map) yaml.load(in);
122125
load(map);
123126
}
@@ -132,7 +135,7 @@ public void read(final InputStream in, final LoaderOptions options)
132135
{
133136
try
134137
{
135-
final Yaml yaml = new Yaml(options);
138+
final Yaml yaml = createYamlForReading(options);
136139
final Map<String, Object> map = (Map) yaml.load(in);
137140
load(map);
138141
}
@@ -142,4 +145,34 @@ public void read(final InputStream in, final LoaderOptions options)
142145
}
143146
}
144147

148+
/**
149+
* Creates a {@code Yaml} object for reading a Yaml file. The object is
150+
* configured with some default settings.
151+
*
152+
* @param options options for loading the file
153+
* @return the {@code Yaml} instance for loading a file
154+
*/
155+
private static Yaml createYamlForReading(LoaderOptions options)
156+
{
157+
return new Yaml(createClassLoadingDisablingConstructor(), new Representer(), new DumperOptions(), options);
158+
}
159+
160+
/**
161+
* Returns a {@code Constructor} object for the YAML parser that prevents
162+
* all classes from being loaded. This effectively disables the dynamic
163+
* creation of Java objects that are declared in YAML files to be loaded.
164+
*
165+
* @return the {@code Constructor} preventing object creation
166+
*/
167+
private static Constructor createClassLoadingDisablingConstructor()
168+
{
169+
return new Constructor()
170+
{
171+
@Override
172+
protected Class<?> getClassForName(String name)
173+
{
174+
throw new ConfigurationRuntimeException("Class loading is disabled.");
175+
}
176+
};
177+
}
145178
}

src/test/java/org/apache/commons/configuration2/TestYAMLConfiguration.java

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,37 @@
1717

1818
package org.apache.commons.configuration2;
1919

20-
import static org.junit.Assert.assertEquals;
21-
import static org.junit.Assert.assertTrue;
22-
20+
import java.io.ByteArrayInputStream;
21+
import java.io.File;
2322
import java.io.FileReader;
2423
import java.io.IOException;
24+
import java.io.StringReader;
2525
import java.io.StringWriter;
26+
import java.nio.charset.StandardCharsets;
2627
import java.util.Arrays;
2728
import java.util.List;
2829
import java.util.Map;
2930

3031
import org.apache.commons.configuration2.ex.ConfigurationException;
3132
import org.junit.Before;
33+
import org.junit.Rule;
3234
import org.junit.Test;
35+
import org.junit.rules.TemporaryFolder;
3336
import org.yaml.snakeyaml.Yaml;
3437

38+
import static org.junit.Assert.assertEquals;
39+
import static org.junit.Assert.assertFalse;
40+
import static org.junit.Assert.assertTrue;
41+
import static org.junit.Assert.fail;
42+
3543
/**
3644
* Unit test for {@link YAMLConfiguration}
3745
*/
3846
public class TestYAMLConfiguration
3947
{
48+
@Rule
49+
public TemporaryFolder temporaryFolder = new TemporaryFolder();
50+
4051
/** The files that we test with. */
4152
private final String testYaml =
4253
ConfigurationAssert.getTestFile("test.yaml").getAbsolutePath();
@@ -134,4 +145,40 @@ public void testCopyConstructor()
134145
yamlConfiguration = new YAMLConfiguration(c);
135146
assertEquals("bar", yamlConfiguration.getString("foo"));
136147
}
148+
149+
@Test
150+
public void testObjectCreationFromReader()
151+
{
152+
final File createdFile = new File(temporaryFolder.getRoot(), "data.txt");
153+
final String yaml = "!!java.io.FileOutputStream [" + createdFile.getAbsolutePath() + "]";
154+
155+
try
156+
{
157+
yamlConfiguration.read(new StringReader(yaml));
158+
fail("Loading configuration did not cause an exception!");
159+
}
160+
catch (ConfigurationException e)
161+
{
162+
//expected
163+
}
164+
assertFalse("Java object was created", createdFile.exists());
165+
}
166+
167+
@Test
168+
public void testObjectCreationFromStream()
169+
{
170+
final File createdFile = new File(temporaryFolder.getRoot(), "data.txt");
171+
final String yaml = "!!java.io.FileOutputStream [" + createdFile.getAbsolutePath() + "]";
172+
173+
try
174+
{
175+
yamlConfiguration.read(new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)));
176+
fail("Loading configuration did not cause an exception!");
177+
}
178+
catch (ConfigurationException e)
179+
{
180+
//expected
181+
}
182+
assertFalse("Java object was created", createdFile.exists());
183+
}
137184
}

0 commit comments

Comments
 (0)