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

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new d42dd73a2e Fix BZ 69690 - getParameter is OK for multipart request and 
no config
d42dd73a2e is described below

commit d42dd73a2eeae52c1e7107316bc279f3f3f8ff8e
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed May 21 15:23:21 2025 +0100

    Fix BZ 69690 - getParameter is OK for multipart request and no config
    
    It is only if getPart() or getParts() is called for a multipart request
    and there is no multipart configuration that an exception should be
    thrown.
---
 java/org/apache/catalina/connector/Request.java    | 10 ++-
 .../org/apache/catalina/connector/TestRequest.java | 85 +++++++++++++++++++++-
 webapps/docs/changelog.xml                         |  9 +++
 3 files changed, 97 insertions(+), 7 deletions(-)

diff --git a/java/org/apache/catalina/connector/Request.java 
b/java/org/apache/catalina/connector/Request.java
index c26c2263e5..1e3e060e8a 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -2298,7 +2298,7 @@ public class Request implements HttpServletRequest {
     @Override
     public Collection<Part> getParts() throws IOException, 
IllegalStateException, ServletException {
 
-        parseParts();
+        parseParts(true);
 
         if (partsParseException != null) {
             switch (partsParseException) {
@@ -2314,7 +2314,7 @@ public class Request implements HttpServletRequest {
     }
 
 
-    private void parseParts() {
+    private void parseParts(boolean mustParse) {
 
         // Return immediately if the parts have already been parsed
         if (parts != null || partsParseException != null) {
@@ -2329,7 +2329,9 @@ public class Request implements HttpServletRequest {
                 mce = new MultipartConfigElement(null, 
connector.getMaxPostSize(), connector.getMaxPostSize(),
                         connector.getMaxPostSize());
             } else {
-                partsParseException = new 
IllegalStateException(sm.getString("coyoteRequest.noMultipartConfig"));
+                if (mustParse) {
+                    partsParseException = new 
IllegalStateException(sm.getString("coyoteRequest.noMultipartConfig"));
+                }
                 return;
             }
         }
@@ -2694,7 +2696,7 @@ public class Request implements HttpServletRequest {
         String mediaType = MediaType.parseMediaTypeOnly(getContentType());
 
         if ("multipart/form-data".equals(mediaType)) {
-            parseParts();
+            parseParts(false);
             if (partsParseException instanceof IllegalStateException) {
                 parametersParseException = (IllegalStateException) 
partsParseException;
             } else if (partsParseException != null) {
diff --git a/test/org/apache/catalina/connector/TestRequest.java 
b/test/org/apache/catalina/connector/TestRequest.java
index 5c9d95bfb6..05b05b51f4 100644
--- a/test/org/apache/catalina/connector/TestRequest.java
+++ b/test/org/apache/catalina/connector/TestRequest.java
@@ -443,7 +443,7 @@ public class TestRequest extends TomcatBaseTest {
         HttpURLConnection conn = getConnection("http://localhost:"; + getPort()
                 + "/parseParametersBeforeParseParts");
 
-        prepareRequestBug54984(conn);
+        prepareMultiPartRequest(conn);
 
         checkResponseBug54984(conn);
 
@@ -451,7 +451,7 @@ public class TestRequest extends TomcatBaseTest {
 
         conn = getConnection("http://localhost:"; + getPort() + "/");
 
-        prepareRequestBug54984(conn);
+        prepareMultiPartRequest(conn);
 
         checkResponseBug54984(conn);
 
@@ -617,7 +617,7 @@ public class TestRequest extends TomcatBaseTest {
         }
     }
 
-    private void prepareRequestBug54984(HttpURLConnection conn)
+    private void prepareMultiPartRequest(HttpURLConnection conn)
             throws Exception {
         String boundary = "-----" + System.currentTimeMillis();
         conn.setRequestProperty("Content-Type",
@@ -981,4 +981,83 @@ public class TestRequest extends TomcatBaseTest {
             }
         }
     }
+
+
+    /*
+     * getParameter should work with a multipart/form-data request if there is 
no multipart config.
+     */
+    @Test
+    public void testBug69690a() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        Context ctx = getProgrammaticRootContext();
+        Tomcat.addServlet(ctx, "Bug69690", new Bug69690Servlet());
+        ctx.addServletMappingDecoded("/", "Bug69690");
+        tomcat.start();
+
+        HttpURLConnection conn = getConnection("http://localhost:"; + getPort() 
+ "/parameter?a=b");
+
+        prepareMultiPartRequest(conn);
+
+        List<String> response = new ArrayList<>();
+        int status = conn.getResponseCode();
+        if (status == HttpURLConnection.HTTP_OK) {
+            try (InputStreamReader isr = new 
InputStreamReader(conn.getInputStream(), "UTF-8");
+                    BufferedReader reader = new BufferedReader(isr)) {
+                String line = null;
+                while ((line = reader.readLine()) != null) {
+                    response.add(line);
+                }
+                Assert.assertTrue(response.contains("OK"));
+            }
+        } else {
+            Assert.fail("OK status was expected: " + status);
+        }
+
+        conn.disconnect();
+    }
+
+
+    /*
+     * getPart should not work with a multipart/form-data request if there is 
no multipart config.
+     */
+    @Test
+    public void testBug69690b() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        Context ctx = getProgrammaticRootContext();
+        Tomcat.addServlet(ctx, "Bug69690", new Bug69690Servlet());
+        ctx.addServletMappingDecoded("/", "Bug69690");
+        tomcat.start();
+
+        HttpURLConnection conn = getConnection("http://localhost:"; + getPort() 
+ "/part?a=b");
+
+        prepareMultiPartRequest(conn);
+
+        Assert.assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
conn.getResponseCode());
+
+        conn.disconnect();
+    }
+
+
+    private class Bug69690Servlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doPost(HttpServletRequest req, HttpServletResponse 
resp) throws ServletException, IOException {
+            resp.setCharacterEncoding(StandardCharsets.UTF_8);
+            resp.setContentType("text/plain");
+            PrintWriter pw = resp.getWriter();
+
+            if (req.getRequestURI().endsWith("/parameter")) {
+                if ("b".equals(req.getParameter("a"))) {
+                    pw.print("OK");
+                } else {
+                    pw.print("FAIL - Parameter 'a' not set to 'b'");
+                }
+            } else {
+                // This should trigger an error since the servlet does not 
have a multi-part configuration.
+                req.getPart("any");
+            }
+        }
+    }
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 2c95245095..5296c30230 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -170,6 +170,15 @@
         Add support for the <code>java:module</code> namespace which mirrors
         the <code>java:comp</code> namespace. (markt)
       </fix>
+      <fix>
+        <bug>69690</bug>: Calling 
<code>HttpServletRequest.getParameter()</code>
+        and related methods for a request with content type
+        <code>multipart/form-data</code> when the mapped servlet does not have 
a
+        <code>@MultipartConfig</code> or equivalent should not trigger an
+        exception. Note that calling <code>getPart()</code> or
+        <code>getParts()</code> is these circumstances will trigger an
+        exception. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to