2828import javax .xml .bind .annotation .XmlElement ;
2929import javax .xml .bind .annotation .XmlRootElement ;
3030import javax .xml .bind .annotation .XmlType ;
31+ import javax .xml .stream .XMLInputFactory ;
3132
3233import org .junit .Before ;
3334import org .junit .Test ;
3435import org .springframework .core .ParameterizedTypeReference ;
36+ import org .springframework .core .io .ClassPathResource ;
37+ import org .springframework .core .io .Resource ;
3538import org .springframework .http .MockHttpInputMessage ;
39+ import org .springframework .http .converter .HttpMessageConverter ;
3640
3741/**
3842 * Test fixture for {@link Jaxb2CollectionHttpMessageConverter}.
@@ -120,6 +124,48 @@ public void readXmlTypeSet() throws Exception {
120124 assertTrue ("Invalid result" , result .contains (new TestType ("2" )));
121125 }
122126
127+ @ Test
128+ @ SuppressWarnings ("unchecked" )
129+ public void readXmlRootElementWithExternalEntity () throws Exception {
130+
131+ Resource external = new ClassPathResource ("external.txt" , getClass ());
132+ String content = "<!DOCTYPE root [" +
133+ " <!ELEMENT external ANY >\n " +
134+ " <!ENTITY ext SYSTEM \" " + external .getURI () + "\" >]>" +
135+ " <list><rootElement><type s=\" 1\" /><external>&ext;</external></rootElement></list>" ;
136+ MockHttpInputMessage inputMessage = new MockHttpInputMessage (content .getBytes ("UTF-8" ));
137+
138+ Collection <RootElement > result = converter .read (rootElementListType , null , inputMessage );
139+ assertEquals (1 , result .size ());
140+ assertEquals ("" , result .iterator ().next ().external );
141+ }
142+
143+ @ Test
144+ @ SuppressWarnings ("unchecked" )
145+ public void readXmlRootElementExternalEntityEnabled () throws Exception {
146+
147+ Resource external = new ClassPathResource ("external.txt" , getClass ());
148+ String content = "<!DOCTYPE root [" +
149+ " <!ELEMENT external ANY >\n " +
150+ " <!ENTITY ext SYSTEM \" " + external .getURI () + "\" >]>" +
151+ " <list><rootElement><type s=\" 1\" /><external>&ext;</external></rootElement></list>" ;
152+ MockHttpInputMessage inputMessage = new MockHttpInputMessage (content .getBytes ("UTF-8" ));
153+
154+ // Now read with
155+ Jaxb2CollectionHttpMessageConverter <?> c = new Jaxb2CollectionHttpMessageConverter <Collection <Object >>() {
156+ @ Override
157+ protected XMLInputFactory createXmlInputFactory () {
158+ XMLInputFactory inputFactory = XMLInputFactory .newInstance ();
159+ inputFactory .setProperty (XMLInputFactory .IS_REPLACING_ENTITY_REFERENCES , true );
160+ return inputFactory ;
161+ }
162+ };
163+
164+ Collection <RootElement > result = c .read (rootElementListType , null , inputMessage );
165+ assertEquals (1 , result .size ());
166+ assertEquals ("Foo Bar" , result .iterator ().next ().external );
167+ }
168+
123169
124170 @ XmlRootElement
125171 public static class RootElement {
@@ -134,6 +180,9 @@ public RootElement(String s) {
134180 @ XmlElement
135181 public TestType type = new TestType ();
136182
183+ @ XmlElement (required =false )
184+ public String external ;
185+
137186 @ Override
138187 public boolean equals (Object o ) {
139188 if (this == o ) {
@@ -181,9 +230,6 @@ public boolean equals(Object o) {
181230 public int hashCode () {
182231 return s .hashCode ();
183232 }
184-
185-
186-
187233 }
188234
189235}
0 commit comments