Hi folks,

I might have found a bug and looking for someone to confirm. (Tested in Tomcat 8.5.32).

Consider the following servlet:
@WebServlet("/request-dispatcher")
public class TestServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;

        protected void doGet(HttpServletRequest request, HttpServletResponse 
response)
                        throws ServletException, IOException {
                String jsp = request.getParameter("jsp");
                if (jsp == null || jsp.isEmpty())
                        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                else {
                        System.out.println("Requested JSP: " + jsp);
                        RequestDispatcher dispatcher = 
request.getRequestDispatcher("/" + jsp);
                        dispatcher.forward(request, response);
                }
        }
}

Now this call:
$ curl --verbose http://localhost:8080/test/request-dispatcher?jsp=1380%2B0.jsp
* STATE: INIT => CONNECT handle 0x25de150; line 1392 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* STATE: CONNECT => WAITRESOLVE handle 0x25de150; line 1428 (connection #0)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* 
  Trying ::1...
* TCP_NODELAY set
* STATE: WAITRESOLVE => WAITCONNECT handle 0x25de150; line 1509 (connection #0)
* Connected to localhost (::1) port 8080 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x25de150; line 1561 
(connection #0)
* Marked for [keep alive]: HTTP default
* STATE: SENDPROTOCONNECT => DO handle 0x25de150; line 1579 (connection #0)
GET /test/request-dispatcher?jsp=1380%2B0.jsp HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.58.0
Accept: */*

* STATE: DO => DO_DONE handle 0x25de150; line 1658 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x25de150; line 1783 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x25de150; line 1799 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 404
< Content-Type: text/html;charset=utf-8
< Content-Language: en
< Content-Length: 1093
< Date: Wed, 25 Jul 2018 19:44:30 GMT

Now this one:
$ curl -I http://localhost:8080/test/1380+0.jsp --verbose                       * 
STATE: INIT => CONNECT handle 0x66e150; line 1392 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* STATE: CONNECT => WAITRESOLVE handle 0x66e150; line 1428 (connection #0)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* 
  Trying ::1...
* TCP_NODELAY set
* STATE: WAITRESOLVE => WAITCONNECT handle 0x66e150; line 1509 (connection #0)
* Connected to localhost (::1) port 8080 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x66e150; line 1561 (connection 
#0)
* Marked for [keep alive]: HTTP default
* STATE: SENDPROTOCONNECT => DO handle 0x66e150; line 1579 (connection #0)
HEAD /test/1380+0.jsp HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.58.0
Accept: */*

* STATE: DO => DO_DONE handle 0x66e150; line 1658 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x66e150; line 1783 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x66e150; line 1799 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200
< Set-Cookie: JSESSIONID=FC911829DB08950A03808483C61DFBDF; Path=/test; HttpOnly
< Content-Type: text/html;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 25 Jul 2018 19:45:12 GMT

I know that #getRequestDispatcher() requires a RFC 3986 compliant URI which this one is according to JS' encodeURI().

The root cause, imho, is ApplicationContext.java:432:
decodedPath = URLDecoder.decode(normalizedPath, "UTF-8");

This is deemed to fail because URLDecoder has not been designed for URIs, but for "This class contains static methods for decoding a String from the application/x-www-form-urlencoded MIME format."

It is used in
ApplicationContext.java
WebappLoader.java
CGIServlet.java
JspRuntimeContext.java

I consider this to be a bug, I know that Tomcat has its own URLEncoder, but it seems that we need a compliant URLDecoder or use UDecoder?.

Can someone confirm?

Michael

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

Reply via email to