[jira] [Created] (WINK-439) @FormParam-annotated parameters may be URL decoded twice

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[jira] [Created] (WINK-439) @FormParam-annotated parameters may be URL decoded twice

JIRA jira@apache.org
Steven Soloff created WINK-439:
----------------------------------

             Summary: @FormParam-annotated parameters may be URL decoded twice
                 Key: WINK-439
                 URL: https://issues.apache.org/jira/browse/WINK-439
             Project: Wink
          Issue Type: Bug
          Components: Server
    Affects Versions: 1.4
         Environment: Jetty 9.2.9.v20150224
            Reporter: Steven Soloff
            Priority: Minor


I suspect there is a defect in the {{org.apache.wink.server.internal.registry.ServerInjectableFactory$FormParamBinding.getValue()}} method [\[1\]|http://svn.apache.org/viewvc/wink/tags/wink-1.4.0/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java?revision=1523533&view=markup#l342] that causes {{@FormParam}}-annotated parameters to be URL decoded twice under certain conditions.  This causes a problem when the unencoded parameter value contains a percent sign ({{%}}).  In that case, the second URL decode incorrectly transforms sequences of {{%<char><char>}} into a single character resulting in an incorrect parameter value on the service side.

The issue is manifested when the path through {{FormParamBinding.getValue()}} goes through the following code:

{code:java}
                    // see E011 at
                    // http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html
                    // Perhaps the message body was already consumed by a
                    // servlet filter. Let's try the servlet request parameters
                    // instead.
                    Map map =
                        RuntimeContextTLS.getRuntimeContext()
                            .getAttribute(HttpServletRequest.class).getParameterMap();
{code}

The {{javax.servlet.ServletRequest.getParameterMap()}} method will URL decode the parameter value if the content type is {{application/x-www-form-urlencoded}} (this is not specified in the Javadocs, but I confirmed that Jetty implements this behavior).  Then, regardless of how the parameter value was retrieved, the following code is executed later in the method:

{code:java}
            // decode all values
            decodeValues(values);
{code}

The {{decodeValues()}} method also URL decodes the parameter value.

Thus, the parameter value is URL decoded twice whenever Wink is forced to retrieve the parameter value from the request object instead of reading the request body directly.

A naive fix for the issue would be to bypass {{decodeValues()}} if the parameter value is obtained from the request object.

A confirmed workaround for the issue requires replacing the {{@FormParam}}-annotated parameter(s) of the service method with a {{@Context}}-annotated parameter referencing the {{HttpServletRequest}} and directly retrieving the form parameters from the request object.  A possible, but unconfirmed, workaround may be to annotate the service method with {{@Encoded}} to suppress one of the URL decodes [\[2\]|http://stackoverflow.com/a/11949673/3900879].

\[1\] http://svn.apache.org/viewvc/wink/tags/wink-1.4.0/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java?revision=1523533&view=markup#l342
\[2\] http://stackoverflow.com/a/11949673/3900879



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)