This is an automated email from the ASF dual-hosted git repository.

reiern70 pushed a commit to branch reiern70/WICKET-7074-master
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit 5cefb6b86b73d445b25277c8b92d3e0f054f7fcc
Author: reiern70 <reier...@gmail.com>
AuthorDate: Tue Sep 19 11:30:07 2023 -0500

    [WICKET-7074] write AJAX responses to a temporary buffer so that is AJAX 
fails in rendering phase response is not polluted with an invalid XML
---
 .../org/apache/wicket/ajax/AjaxRequestHandler.java |  8 +-
 .../apache/wicket/ajax/AjaxRequestHandlerTest.java | 94 ++++++++++++++++++++++
 2 files changed, 99 insertions(+), 3 deletions(-)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java 
b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
index 5e52cfa678..2f69f22b60 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
@@ -273,14 +273,16 @@ public class AjaxRequestHandler extends 
AbstractPartialPageRequestHandler implem
                final List<IResponseFilter> filters = Application.get()
                        .getRequestCycleSettings()
                        .getResponseFilters();
+               // KP-7074 we need to write to a temporary buffer, otherwise, 
if an exception is produced,
+               // and a redirect is done we will end up with a malformed XML
+               final StringResponse bodyResponse = new StringResponse();
+               update.writeTo(bodyResponse, encoding);
                if (filters == null || filters.isEmpty())
                {
-                       update.writeTo(response, encoding);
+                       response.write(bodyResponse.getBuffer());
                }
                else
                {
-                       final StringResponse bodyResponse = new 
StringResponse();
-                       update.writeTo(bodyResponse, encoding);
                        CharSequence filteredResponse = 
invokeResponseFilters(bodyResponse, filters);
                        response.write(filteredResponse);
                }
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxRequestHandlerTest.java 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxRequestHandlerTest.java
index f2c12362e9..61542ef102 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxRequestHandlerTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxRequestHandlerTest.java
@@ -34,11 +34,15 @@ import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.MockPageWithLink;
 import org.apache.wicket.MockPageWithLinkAndComponent;
+import org.apache.wicket.Page;
+import org.apache.wicket.RuntimeConfigurationType;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.event.IEvent;
 import org.apache.wicket.markup.IMarkupResourceStreamProvider;
 import org.apache.wicket.markup.html.WebComponent;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.mock.MockApplication;
 import org.apache.wicket.request.IRequestHandler;
 import org.apache.wicket.request.cycle.IRequestCycleListener;
 import org.apache.wicket.request.cycle.RequestCycle;
@@ -47,7 +51,9 @@ import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.StringResourceStream;
 import org.apache.wicket.util.tester.DiffUtil;
 import org.apache.wicket.util.tester.WicketTestCase;
+import org.apache.wicket.util.tester.WicketTester;
 import org.apache.wicket.util.time.Instants;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -306,6 +312,94 @@ class AjaxRequestHandlerTest extends WicketTestCase
                assertEquals("no-cache, no-store", 
tester.getLastResponse().getHeader("Cache-Control"));
        }
 
+       private static class Wicket7074Application extends MockApplication
+       {
+
+               @Override
+               public Class<? extends Page> getHomePage()
+               {
+                       return Wicket7074.class;
+               }
+
+
+               @Override
+               public RuntimeConfigurationType getConfigurationType() {
+                       // this ise needed so that no filters are added
+                       return RuntimeConfigurationType.DEPLOYMENT;
+               }
+       }
+
+       private static class WeirdException extends IllegalStateException {
+
+       }
+
+       private static class Wicket7074 extends WebPage implements 
IMarkupResourceStreamProvider
+       {
+               private static final long serialVersionUID = 1L;
+
+               private boolean generateError = false;
+
+               private final Component label;
+               /**
+                * Construct.
+                */
+               private Wicket7074()
+               {
+                       setOutputMarkupId(true);
+
+                       add(new AjaxLink<Void>("action")
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               @Override
+                               public void onClick(AjaxRequestTarget target)
+                               {
+                                       // we simulate producing an exception 
in rendering phase
+                                       generateError = true;
+                                       target.add(label);
+                               }
+                       });
+
+                       add(label = new Label("label", "error")
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               @Override
+                               protected void onBeforeRender()
+                               {
+                                       super.onBeforeRender();
+                                       // we simulate producing an exception 
in rendering phase
+                                       if (generateError)
+                                       {
+                                               throw new WeirdException();
+                                       }
+                               }
+                       }.setOutputMarkupId(true));
+               }
+
+               @Override
+               public IResourceStream getMarkupResourceStream(MarkupContainer 
container,
+                                                                               
                           Class<?> containerClass)
+               {
+                       return new StringResourceStream(
+                                       "<html><body><a 
wicket:id='action'>link1</a><br/><br/><br/><span 
wicket:id='label'>Link2</span></body></html>");
+               }
+       }
+
+       @Test
+       void 
ajaxResposeIsEmptyIfExceptionIsProducedDuringRenderingAndNoFiltersAreSet() {
+               Wicket7074Application application = new Wicket7074Application();
+               WicketTester tester = newWicketTester(application);
+               // page renders normally first time
+               tester.startPage(new Wicket7074());
+               // click on action to produce render phase error
+               assertThrows(WeirdException.class, () -> {
+                       tester.clickLink("action");
+               });
+               // AJAX response is written now into a buffer => response 
should empty
+               assertTrue(tester.getLastResponseAsString().isEmpty());
+       }
+
        /**
         * https://issues.apache.org/jira/browse/WICKET-6808
         */

Reply via email to