Disable ext entities in SourceHttpMessageConverter

This change disables the processing of external entities in
SourceHttpMessageConverter by default and provides an option to enable
it if required.
This commit is contained in:
Rossen Stoyanchev
2013-11-05 09:21:57 -05:00
parent c5fcf19535
commit 2ae6a6a341
3 changed files with 205 additions and 51 deletions

View File

@@ -17,21 +17,29 @@
package org.springframework.http.converter.xml;
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.junit.Assert.assertNotEquals;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.nio.charset.Charset;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.MockHttpInputMessage;
import org.springframework.http.MockHttpOutputMessage;
@@ -39,17 +47,29 @@ import org.springframework.util.FileCopyUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
/**
* @author Arjen Poutsma
*/
public class SourceHttpMessageConverterTests {
private static final String BODY = "<root>Hello World</root>";
private SourceHttpMessageConverter<Source> converter;
private String bodyExternal;
@Before
public void setUp() {
public void setUp() throws IOException {
converter = new SourceHttpMessageConverter<Source>();
Resource external = new ClassPathResource("external.txt", getClass());
bodyExternal = "<!DOCTYPE root [" +
" <!ELEMENT root ANY >\n" +
" <!ENTITY ext SYSTEM \"" + external.getURI() + "\" >]><root>&ext;</root>";
}
@Test
@@ -67,39 +87,94 @@ public class SourceHttpMessageConverterTests {
@Test
public void readDOMSource() throws Exception {
String body = "<root>Hello World</root>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
DOMSource result = (DOMSource) converter.read(DOMSource.class, inputMessage);
Document document = (Document) result.getNode();
assertEquals("Invalid result", "root", document.getDocumentElement().getLocalName());
}
@Test
public void readDOMSourceExternal() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(bodyExternal.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
DOMSource result = (DOMSource) converter.read(DOMSource.class, inputMessage);
Document document = (Document) result.getNode();
assertEquals("Invalid result", "root", document.getDocumentElement().getLocalName());
assertNotEquals("Invalid result", "Foo Bar", document.getDocumentElement().getTextContent());
}
@Test
public void readSAXSource() throws Exception {
String body = "<root>Hello World</root>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
SAXSource result = (SAXSource) converter.read(SAXSource.class, inputMessage);
InputSource inputSource = result.getInputSource();
String s = FileCopyUtils.copyToString(new InputStreamReader(inputSource.getByteStream()));
assertXMLEqual("Invalid result", body, s);
assertXMLEqual("Invalid result", BODY, s);
}
@Test
public void readSAXSourceExternal() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(bodyExternal.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
SAXSource result = (SAXSource) converter.read(SAXSource.class, inputMessage);
InputSource inputSource = result.getInputSource();
XMLReader reader = result.getXMLReader();
reader.setContentHandler(new DefaultHandler() {
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String s = new String(ch, start, length);
assertNotEquals("Invalid result", "Foo Bar", s);
}
});
reader.parse(inputSource);
}
@Test
public void readStAXSource() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
StAXSource result = (StAXSource) converter.read(StAXSource.class, inputMessage);
XMLStreamReader streamReader = result.getXMLStreamReader();
assertTrue(streamReader.hasNext());
streamReader.nextTag();
String s = streamReader.getLocalName();
assertEquals("root", s);
s = streamReader.getElementText();
assertEquals("Hello World", s);
streamReader.close();
}
@Test
public void readStAXSourceExternal() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(bodyExternal.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
StAXSource result = (StAXSource) converter.read(StAXSource.class, inputMessage);
XMLStreamReader streamReader = result.getXMLStreamReader();
assertTrue(streamReader.hasNext());
streamReader.next();
streamReader.next();
String s = streamReader.getLocalName();
assertEquals("root", s);
s = streamReader.getElementText();
assertNotEquals("Foo Bar", s);
streamReader.close();
}
@Test
public void readStreamSource() throws Exception {
String body = "<root>Hello World</root>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
StreamSource result = (StreamSource) converter.read(StreamSource.class, inputMessage);
String s = FileCopyUtils.copyToString(new InputStreamReader(result.getInputStream()));
assertXMLEqual("Invalid result", body, s);
assertXMLEqual("Invalid result", BODY, s);
}
@Test
public void readSource() throws Exception {
String body = "<root>Hello World</root>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
MockHttpInputMessage inputMessage = new MockHttpInputMessage(BODY.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
converter.read(Source.class, inputMessage);
}