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)