From 4df7df27ad5207ef4bf8f4874701c353ce94467e Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Fri, 16 Oct 2026 14:09:15 +0200 Subject: [PATCH] WW-3655 test(freemarker): guard against resolving the result location from the request URI The behaviour was changed by WW-4169 (2.3.17): a relative location is resolved against the action namespace. The test fails when the old request-URI based resolution is restored. Co-Authored-By: Claude Opus 5.5 --- .../freemarker/FreeMarkerResultTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java b/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java index f8a4bc4dab..e4b42e076c 100644 --- a/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java +++ b/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java @@ -28,9 +28,14 @@ import org.apache.struts2.views.jsp.StrutsMockServletContext; import org.springframework.mock.web.MockHttpServletRequest; +import freemarker.cache.StringTemplateLoader; +import freemarker.template.Configuration; + import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; /** * Test case for FreeMarkerResult. @@ -113,6 +118,42 @@ public void testContentTypeFromTemplate() throws Exception { assertEquals("text/xml", response.getContentType()); } + public void testEmptyLocationDoesNotLoadRequestUriAsTemplate() throws Exception { + request.setRequestURI("/com/acme/actions/Action.class/"); + request.setServletPath("/com/acme/actions/Action.class/"); + + List requestedTemplates = new ArrayList<>(); + StringTemplateLoader loader = new StringTemplateLoader() { + @Override + public Object findTemplateSource(String name) { + requestedTemplates.add(name); + return super.findTemplateSource(name); + } + }; + loader.putTemplate("com/acme/actions/Action.class/", "CLASS-FILE-BYTES"); + Configuration recordingConfiguration = new Configuration(Configuration.VERSION_2_3_34); + recordingConfiguration.setLocalizedLookup(false); + recordingConfiguration.setTemplateLoader(loader); + + FreemarkerResult result = new FreemarkerResult() { + @Override + protected Configuration getConfiguration() { + return recordingConfiguration; + } + }; + result.setLocation(""); + result.setFreemarkerManager(mgr); + + try { + result.execute(invocation); + } catch (Exception expected) { + // a missing template is acceptable, serving the request URI is not + } + + assertFalse(stringWriter.toString().contains("CLASS-FILE-BYTES")); + assertTrue(requestedTemplates.toString(), requestedTemplates.stream().noneMatch(name -> name.contains("Action.class"))); + } + protected void setUp() throws Exception { super.setUp(); mgr = new FreemarkerManager();