Add processExternalEntities support to OXM

Update OXM AbstractMarshaller to support processing of external
XML entities. By default external entities will not be processed.

Issue: SPR-11376
This commit is contained in:
Rossen Stoyanchev
2014-02-18 16:01:20 -08:00
committed by Phillip Webb
parent 09c57203bb
commit fb0683c066
12 changed files with 327 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@@ -19,6 +19,8 @@ package org.springframework.oxm.castor;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.concurrent.atomic.AtomicReference;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import org.junit.Ignore;
@@ -28,6 +30,8 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.oxm.AbstractUnmarshallerTests;
import org.springframework.oxm.MarshallingException;
import org.springframework.oxm.Unmarshaller;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
@@ -203,4 +207,59 @@ public class CastorUnmarshallerTests extends AbstractUnmarshallerTests {
StreamSource source = new StreamSource(new StringReader(xml));
return unmarshaller.unmarshal(source);
}
@Test
public void unmarshalStreamSourceExternalEntities() throws Exception {
final AtomicReference<XMLReader> result = new AtomicReference<XMLReader>();
CastorMarshaller marshaller = new CastorMarshaller() {
@Override
protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource) {
result.set(xmlReader);
return null;
}
};
// 1. external-general-entities disabled (default)
marshaller.unmarshal(new StreamSource("1"));
assertNotNull(result.get());
assertEquals(false, result.get().getFeature("http://xml.org/sax/features/external-general-entities"));
// 2. external-general-entities disabled (default)
result.set(null);
marshaller.setProcessExternalEntities(true);
marshaller.unmarshal(new StreamSource("1"));
assertNotNull(result.get());
assertEquals(true, result.get().getFeature("http://xml.org/sax/features/external-general-entities"));
}
@Test
public void unmarshalSaxSourceExternalEntities() throws Exception {
final AtomicReference<XMLReader> result = new AtomicReference<XMLReader>();
CastorMarshaller marshaller = new CastorMarshaller() {
@Override
protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource) {
result.set(xmlReader);
return null;
}
};
// 1. external-general-entities disabled (default)
marshaller.unmarshal(new SAXSource(new InputSource("1")));
assertNotNull(result.get());
assertEquals(false, result.get().getFeature("http://xml.org/sax/features/external-general-entities"));
// 2. external-general-entities disabled (default)
result.set(null);
marshaller.setProcessExternalEntities(true);
marshaller.unmarshal(new SAXSource(new InputSource("1")));
assertNotNull(result.get());
assertEquals(true, result.get().getFeature("http://xml.org/sax/features/external-general-entities"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@@ -31,9 +31,12 @@ import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
@@ -49,6 +52,7 @@ import org.springframework.util.FileCopyUtils;
import org.springframework.util.ReflectionUtils;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
@@ -301,6 +305,75 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
writer.toString(), "<airplane><name>test</name></airplane>");
}
// SPR-10806
@Test
public void unmarshalStreamSourceExternalEntities() throws Exception {
final javax.xml.bind.Unmarshaller unmarshaller = mock(javax.xml.bind.Unmarshaller.class);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller() {
@Override
protected javax.xml.bind.Unmarshaller createUnmarshaller() {
return unmarshaller;
}
};
// 1. external-general-entities disabled (default)
marshaller.unmarshal(new StreamSource("1"));
ArgumentCaptor<SAXSource> sourceCaptor = ArgumentCaptor.forClass(SAXSource.class);
verify(unmarshaller).unmarshal(sourceCaptor.capture());
SAXSource result = sourceCaptor.getValue();
assertEquals(false, result.getXMLReader().getFeature("http://xml.org/sax/features/external-general-entities"));
// 2. external-general-entities enabled
reset(unmarshaller);
marshaller.setProcessExternalEntities(true);
marshaller.unmarshal(new StreamSource("1"));
verify(unmarshaller).unmarshal(sourceCaptor.capture());
result = sourceCaptor.getValue();
assertEquals(true, result.getXMLReader().getFeature("http://xml.org/sax/features/external-general-entities"));
}
// SPR-10806
@Test
public void unmarshalSaxSourceExternalEntities() throws Exception {
final javax.xml.bind.Unmarshaller unmarshaller = mock(javax.xml.bind.Unmarshaller.class);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller() {
@Override
protected javax.xml.bind.Unmarshaller createUnmarshaller() {
return unmarshaller;
}
};
// 1. external-general-entities disabled (default)
marshaller.unmarshal(new SAXSource(new InputSource("1")));
ArgumentCaptor<SAXSource> sourceCaptor = ArgumentCaptor.forClass(SAXSource.class);
verify(unmarshaller).unmarshal(sourceCaptor.capture());
SAXSource result = sourceCaptor.getValue();
assertEquals(false, result.getXMLReader().getFeature("http://xml.org/sax/features/external-general-entities"));
// 2. external-general-entities enabled
reset(unmarshaller);
marshaller.setProcessExternalEntities(true);
marshaller.unmarshal(new SAXSource(new InputSource("1")));
verify(unmarshaller).unmarshal(sourceCaptor.capture());
result = sourceCaptor.getValue();
assertEquals(true, result.getXMLReader().getFeature("http://xml.org/sax/features/external-general-entities"));
}
@XmlRootElement
@SuppressWarnings("unused")
public static class DummyRootElement {

View File

@@ -25,7 +25,9 @@ import org.junit.Test;
import org.springframework.oxm.AbstractUnmarshallerTests;
import org.springframework.oxm.Unmarshaller;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* @author Arjen Poutsma