3131import java .io .IOException ;
3232import java .io .InputStream ;
3333import java .io .InputStreamReader ;
34+ import java .io .StringReader ;
3435import java .lang .reflect .Type ;
3536import java .net .HttpURLConnection ;
3637import java .net .InetSocketAddress ;
@@ -222,8 +223,8 @@ void requestWithXML() throws IOException {
222223
223224 try {
224225 server .start ();
225- final ResponseXml client = newDefaultFactory ().create (ResponseXml .class , null );
226- client . base ( "http://localhost:" + server .getAddress ().getPort () + "/api" );
226+ final ResponseXml client = newDefaultFactory ().create (ResponseXml .class ,
227+ "http://localhost:" + server .getAddress ().getPort () + "/api" );
227228
228229 final Response <XmlRecord > result = client .main ("application/xml" , new XmlRecord ("xml content" ));
229230 assertEquals ("xml content" , result .body ().getValue ());
@@ -234,6 +235,63 @@ void requestWithXML() throws IOException {
234235 }
235236 }
236237
238+ @ Test
239+ void requestWithXMLXXE () throws IOException {
240+ final HttpServer server = HttpServer .create (new InetSocketAddress (0 ), 0 );
241+ server .createContext ("/" ).setHandler (httpExchange -> {
242+ final Headers headers = httpExchange .getResponseHeaders ();
243+ headers .set ("content-type" , "application/xml;charset=UTF-8" );
244+ final byte [] bytes ;
245+ String xmlContent = "<!DOCTYPE foo [ <!ENTITY xxe SYSTEM \" file:///etc/passwd\" > ]><foo>&xxe;</foo>" ;
246+ try (final BufferedReader in =
247+ new BufferedReader (new StringReader (xmlContent ))) {
248+ bytes = in .lines ().collect (joining ("\n " )).getBytes (StandardCharsets .UTF_8 );
249+ }
250+ httpExchange .sendResponseHeaders (HttpURLConnection .HTTP_OK , bytes .length );
251+ httpExchange .getResponseBody ().write (bytes );
252+ httpExchange .close ();
253+ });
254+
255+ try {
256+ server .start ();
257+ final ResponseXml client = newDefaultFactory ().create (ResponseXml .class ,
258+ "http://localhost:" + server .getAddress ().getPort () + "/api" );
259+ final Response <XmlRecord > result = client .main ("application/xml" , new XmlRecord ("xml content" ));
260+ assertThrows (java .lang .IllegalArgumentException .class , result ::body ,
261+ "lineNumber: 1; columnNumber: 10; DOCTYPE is disallowed when the feature \" http://apache.org/xml/features/disallow-doctype-decl\" set to true." );
262+ } finally {
263+ server .stop (0 );
264+ }
265+ }
266+
267+ @ Test
268+ void requestWithInvalidXML () throws IOException {
269+ final HttpServer server = HttpServer .create (new InetSocketAddress (0 ), 0 );
270+ server .createContext ("/" ).setHandler (httpExchange -> {
271+ final Headers headers = httpExchange .getResponseHeaders ();
272+ headers .set ("content-type" , "application/xml;charset=UTF-8" );
273+ final byte [] bytes ;
274+ String xmlContent = "<!ENTITY xxe SYSTEM \" file:///etc/passwd\" ><foo>invalid;" ;
275+ try (final BufferedReader in =
276+ new BufferedReader (new StringReader (xmlContent ))) {
277+ bytes = in .lines ().collect (joining ("\n " )).getBytes (StandardCharsets .UTF_8 );
278+ }
279+ httpExchange .sendResponseHeaders (HttpURLConnection .HTTP_OK , bytes .length );
280+ httpExchange .getResponseBody ().write (bytes );
281+ httpExchange .close ();
282+ });
283+
284+ try {
285+ server .start ();
286+ final ResponseXml client = newDefaultFactory ().create (ResponseXml .class ,
287+ "http://localhost:" + server .getAddress ().getPort () + "/api" );
288+ final Response <XmlRecord > result = client .main ("application/xml" , new XmlRecord ("xml content" ));
289+ assertThrows (java .lang .IllegalArgumentException .class , result ::body );
290+ } finally {
291+ server .stop (0 );
292+ }
293+ }
294+
237295 @ Test
238296 void requestWithJSON () throws IOException {
239297 final HttpServer server = HttpServer .create (new InetSocketAddress (0 ), 0 );
0 commit comments