From a4766238acbe1be841bca67346ca1611b73cdf96 Mon Sep 17 00:00:00 2001 From: Chenjp Date: Thu, 16 Jan 2025 08:46:38 +0800 Subject: [PATCH] webdav testcase for special path cases for allowSpecialPaths=true --- .../catalina/servlets/TestWebdavServlet.java | 87 ++++++++++++++----- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/test/org/apache/catalina/servlets/TestWebdavServlet.java b/test/org/apache/catalina/servlets/TestWebdavServlet.java index 007f3ead9559..ee27a93535da 100644 --- a/test/org/apache/catalina/servlets/TestWebdavServlet.java +++ b/test/org/apache/catalina/servlets/TestWebdavServlet.java @@ -18,11 +18,13 @@ import java.io.File; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.UUID; import javax.xml.parsers.SAXParserFactory; @@ -46,46 +48,85 @@ public class TestWebdavServlet extends TomcatBaseTest { - /* - * Test attempting to access special paths (WEB-INF/META-INF) using WebdavServlet - */ @Test - public void testGetSpecials() throws Exception { + public void testGetSpecial_allowSpecialPaths_rootdavcontext() throws Exception { + testGetSpecials(true, false); + } + + @Test + public void testGetSpecial_allowSpecialPaths_nonrootdavcontext() throws Exception { + testGetSpecials(true, true); + } + + @Test + public void testGetSpecial_disallowSpecialPaths_rootdavcontext() throws Exception { + testGetSpecials(false, false); + } + + @Test + public void testGetSpecial_disallowSpecialPaths_nonrootdavcontext() throws Exception { + testGetSpecials(false, true); + } + + /* Test attempting to access special paths (WEB-INF/META-INF) using WebdavServlet */ + private void testGetSpecials(boolean allowSpecialPaths, boolean useSubpathWebdav) throws Exception { Tomcat tomcat = getTomcatInstance(); - String contextPath = "/examples"; + // Create a temp webapp that can be safely written to + File tempWebapp = new File(getTemporaryDirectory(), "webdav-specialpath"+UUID.randomUUID()); + Assert.assertTrue("Failed to mkdirs on "+tempWebapp.getCanonicalPath(),tempWebapp.mkdirs()); + Assert.assertTrue(new File(tempWebapp,"WEB-INF").mkdir()); + Assert.assertTrue(new File(tempWebapp,"META-INF").mkdir()); + try (FileWriter fw = new FileWriter(new File(tempWebapp, "WEB-INF-desc.xml"))) { + fw.write("This is not a special file"); + } + try (FileWriter fw = new FileWriter(new File(tempWebapp, "WEB-INF/web.xml"))) { + fw.write("..."); + } + try (FileWriter fw = new FileWriter(new File(tempWebapp, "META-INF/context.xml"))) { + fw.write("..."); + } - File appDir = new File(getBuildDirectory(), "webapps" + contextPath); - // app dir is relative to server home - Context ctx = tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); + Context ctx = tomcat.addContext("", tempWebapp.getAbsolutePath()); + Wrapper webdavServlet = Tomcat.addServlet(ctx, "webdav", new WebdavServlet()); - Tomcat.addServlet(ctx, "webdav", new WebdavServlet()); - ctx.addServletMappingDecoded("/*", "webdav"); + webdavServlet.addInitParameter("listings", "true"); + webdavServlet.addInitParameter("allowSpecialPaths", allowSpecialPaths ? "true" : "false"); + + String contextPath=""; + if (useSubpathWebdav) { + ctx.addServletMappingDecoded("/webdav/*", "webdav"); + contextPath = "/webdav"; + } else { + ctx.addServletMappingDecoded("/*", "webdav"); + } tomcat.start(); final ByteChunk res = new ByteChunk(); - int rc =getUrl("http://localhost:" + getPort() + contextPath + - "/WEB-INF/web.xml", res, null); - Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, rc); + int rc = 0; - rc =getUrl("http://localhost:" + getPort() + contextPath + - "/WEB-INF/doesntexistanywhere", res, null); - Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, rc); + // Notice: Special paths /WEB-INF and /META-INF are protected by StandardContextValve. + // allowSpecialPaths works only when webdav re-mount to a non-root path. + rc = getUrl("http://localhost:" + getPort() + contextPath + "/WEB-INF/web.xml", res, null); + Assert.assertEquals( + useSubpathWebdav && allowSpecialPaths ? HttpServletResponse.SC_OK : HttpServletResponse.SC_NOT_FOUND, + rc); - rc =getUrl("http://localhost:" + getPort() + contextPath + - "/WEB-INF/", res, null); + rc = getUrl("http://localhost:" + getPort() + contextPath + "/WEB-INF/doesntexistanywhere", res, null); Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, rc); - rc =getUrl("http://localhost:" + getPort() + contextPath + - "/META-INF/MANIFEST.MF", res, null); - Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, rc); + rc = getUrl("http://localhost:" + getPort() + contextPath + "/META-INF/context.xml", res, null); + Assert.assertEquals( + useSubpathWebdav && allowSpecialPaths ? HttpServletResponse.SC_OK : HttpServletResponse.SC_NOT_FOUND, + rc); - rc =getUrl("http://localhost:" + getPort() + contextPath + - "/META-INF/doesntexistanywhere", res, null); + rc = getUrl("http://localhost:" + getPort() + contextPath + "/META-INF/doesntexistanywhere", res, null); Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, rc); + rc = getUrl("http://localhost:" + getPort() + contextPath + "/WEB-INF-desc.xml", res, null); + Assert.assertEquals(HttpServletResponse.SC_OK, rc); } /*