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)

Reply via email to