diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java index ed044c333fd..455d5339a3c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java @@ -482,28 +482,26 @@ public class ErrorHandler extends AbstractHandler writer.append(json.entrySet().stream() .map(e -> QuotedStringTokenizer.quote(e.getKey()) + ":" + - QuotedStringTokenizer.quote((e.getValue()))) + QuotedStringTokenizer.quote(StringUtil.sanitizeXmlString((e.getValue())))) .collect(Collectors.joining(",\n", "{\n", "\n}"))); - - } protected void writeErrorPageStacks(HttpServletRequest request, Writer writer) throws IOException { Throwable th = (Throwable)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); - while (th != null) + if (th != null) { writer.write("
"); // You have to pre-generate and then use #write(writer, String) - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - th.printStackTrace(pw); - pw.flush(); - write(writer, sw.getBuffer().toString()); // IMPORTANT STEP + try (StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw)) + { + th.printStackTrace(pw); + pw.flush(); + write(writer, sw.getBuffer().toString()); // sanitize + } writer.write("\n"); - - th = th.getCause(); } } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java index 97a7f736b40..87184c19e32 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java @@ -31,6 +31,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.ajax.JSON; +import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -38,6 +39,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; @@ -47,12 +49,14 @@ import static org.hamcrest.Matchers.nullValue; public class ErrorHandlerTest { + static StacklessLogging stacklessLogging; static Server server; static LocalConnector connector; @BeforeAll public static void before() throws Exception { + stacklessLogging = new StacklessLogging(HttpChannel.class); server = new Server(); connector = new LocalConnector(server); server.addConnector(connector); @@ -66,7 +70,7 @@ public class ErrorHandlerTest if (baseRequest.getDispatcherType() == DispatcherType.ERROR) { baseRequest.setHandled(true); - response.sendError(((Integer)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)).intValue()); + response.sendError((Integer)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)); return; } @@ -80,43 +84,40 @@ public class ErrorHandlerTest if (target.startsWith("/badmessage/")) { - int code = Integer.valueOf(target.substring(target.lastIndexOf('/') + 1)); + int code = Integer.parseInt(target.substring(target.lastIndexOf('/') + 1)); throw new ServletException(new BadMessageException(code)); } // produce an exception with an JSON formatted cause message if (target.startsWith("/jsonmessage/")) { - StringBuilder message = new StringBuilder(); - message.append("{\n \"glossary\": {\n \"title\": \"example\"\n }\n }"); - throw new ServletException(new RuntimeException(message.toString())); + String message = "{\n \"glossary\": {\n \"title\": \"example\"\n }\n }"; + throw new ServletException(new RuntimeException(message)); } // produce an exception with an XML cause message if (target.startsWith("/xmlmessage/")) { - StringBuilder message = new StringBuilder(); - message.append("\n"); - message.append("