388675 Non utf8 encoded query strings not decoded to parameter map using queryEncoding
This commit is contained in:
parent
e7f1743dd4
commit
0035343af3
|
@ -94,7 +94,15 @@ public class HttpURI
|
|||
public HttpURI(String raw)
|
||||
{
|
||||
_rawString=raw;
|
||||
byte[] b = raw.getBytes();
|
||||
byte[] b;
|
||||
try
|
||||
{
|
||||
b = raw.getBytes(StringUtil.__UTF8);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
parse(b,0,b.length);
|
||||
}
|
||||
|
||||
|
@ -700,7 +708,7 @@ public class HttpURI
|
|||
if (encoding==null || StringUtil.isUTF8(encoding))
|
||||
UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters);
|
||||
else
|
||||
UrlEncoded.decodeTo(toUtf8String(_query+1,_fragment-_query-1),parameters,encoding);
|
||||
UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding),parameters,encoding);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
|
|
|
@ -1739,6 +1739,7 @@ public class Request implements HttpServletRequest
|
|||
public void setQueryString(String queryString)
|
||||
{
|
||||
_queryString = queryString;
|
||||
_queryEncoding = null; //assume utf-8
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1922,7 +1923,7 @@ public class Request implements HttpServletRequest
|
|||
{
|
||||
// extract parameters from dispatch query
|
||||
MultiMap<String> parameters = new MultiMap<String>();
|
||||
UrlEncoded.decodeTo(query,parameters,getCharacterEncoding());
|
||||
UrlEncoded.decodeTo(query,parameters, StringUtil.__UTF8); //have to assume UTF-8 because we can't know otherwise
|
||||
|
||||
boolean merge_old_query = false;
|
||||
|
||||
|
@ -1957,10 +1958,11 @@ public class Request implements HttpServletRequest
|
|||
{
|
||||
StringBuilder overridden_query_string = new StringBuilder();
|
||||
MultiMap<String> overridden_old_query = new MultiMap<String>();
|
||||
UrlEncoded.decodeTo(_queryString,overridden_old_query,getCharacterEncoding());
|
||||
|
||||
UrlEncoded.decodeTo(_queryString,overridden_old_query,getQueryEncoding());//decode using any queryencoding set for the request
|
||||
|
||||
|
||||
MultiMap<String> overridden_new_query = new MultiMap<String>();
|
||||
UrlEncoded.decodeTo(query,overridden_new_query,getCharacterEncoding());
|
||||
UrlEncoded.decodeTo(query,overridden_new_query,StringUtil.__UTF8); //have to assume utf8 as we cannot know otherwise
|
||||
|
||||
Iterator<Entry<String, Object>> iter = overridden_old_query.entrySet().iterator();
|
||||
while (iter.hasNext())
|
||||
|
|
|
@ -386,7 +386,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
baseRequest.setRequestURI(null);
|
||||
baseRequest.setPathInfo(baseRequest.getRequestURI());
|
||||
if (uri.getQuery()!=null)
|
||||
baseRequest.mergeQueryString(uri.getQuery());
|
||||
baseRequest.mergeQueryString(uri.getQuery()); //we have to assume dispatch path and query are UTF8
|
||||
}
|
||||
|
||||
final String target=baseRequest.getPathInfo();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
@ -26,12 +27,16 @@ import static org.junit.Assert.fail;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.http.EncodedHttpURI;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.io.ByteArrayBuffer;
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
public class HttpURITest
|
||||
|
@ -205,6 +210,106 @@ public class HttpURITest
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoPercentEncodingOfQueryUsingNonUTF8() throws Exception
|
||||
{
|
||||
|
||||
byte[] utf8_bytes = "/%D0%A1%D1%82%D1%80%D0%BE%D0%BD%D0%B3-%D1%84%D0%B8%D0%BB%D1%8C%D1%82%D1%80/%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3?".getBytes("UTF-8");
|
||||
byte[] cp1251_bytes = TypeUtil.fromHexString("e2fbe1f0e0edee3dd2e5ecefe5f0e0f2f3f0e0");
|
||||
String expectedCP1251String = new String(cp1251_bytes, "cp1251");
|
||||
String expectedCP1251Key = new String(cp1251_bytes, 0, 7, "cp1251");
|
||||
String expectedCP1251Value = new String(cp1251_bytes, 8, cp1251_bytes.length-8, "cp1251");
|
||||
|
||||
//paste both byte arrays together to form the uri
|
||||
byte[] allbytes = new byte[utf8_bytes.length+cp1251_bytes.length];
|
||||
int i=0;
|
||||
for (;i<utf8_bytes.length;i++) {
|
||||
allbytes[i] = utf8_bytes[i];
|
||||
}
|
||||
for (int j=0; j< cp1251_bytes.length;j++)
|
||||
allbytes[i+j] = cp1251_bytes[j];
|
||||
|
||||
//Test using a HttpUri that expects a particular charset encoding. See URIUtil.__CHARSET
|
||||
EncodedHttpURI uri = new EncodedHttpURI("cp1251");
|
||||
uri.parse(allbytes, 0, allbytes.length);
|
||||
assertEquals(expectedCP1251String, uri.getQuery("cp1251"));
|
||||
|
||||
//Test params decoded correctly
|
||||
MultiMap params = new MultiMap();
|
||||
uri.decodeQueryTo(params);
|
||||
String val = params.getString(expectedCP1251Key);
|
||||
assertNotNull(val);
|
||||
assertEquals(expectedCP1251Value, val);
|
||||
|
||||
//Test using HttpURI where you pass in the charset encoding.
|
||||
HttpURI httpuri = new HttpURI();
|
||||
httpuri.parse(allbytes,0,allbytes.length);
|
||||
assertNotNull(httpuri.getQuery("UTF-8")); //still get back a query string, just incorrectly encoded
|
||||
assertEquals(expectedCP1251String, httpuri.getQuery("cp1251"));
|
||||
|
||||
//Test params decoded correctly
|
||||
params.clear();
|
||||
httpuri.decodeQueryTo(params, "cp1251");
|
||||
val = params.getString(expectedCP1251Key);
|
||||
assertNotNull(val);
|
||||
assertEquals(expectedCP1251Value, val);
|
||||
|
||||
//test able to set the query encoding and call getQueryString multiple times
|
||||
Request request = new Request();
|
||||
request.setUri(httpuri);
|
||||
request.setAttribute("org.eclipse.jetty.server.Request.queryEncoding", "ISO-8859-1");
|
||||
assertNotNull (request.getQueryString()); //will be incorrect encoding but not null
|
||||
request.setAttribute("org.eclipse.jetty.server.Request.queryEncoding", "cp1251");
|
||||
assertEquals(expectedCP1251String, request.getQueryString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPercentEncodingOfQueryStringUsingNonUTF8() throws UnsupportedEncodingException
|
||||
{
|
||||
|
||||
byte[] utf8_bytes = "/%D0%A1%D1%82%D1%80%D0%BE%D0%BD%D0%B3-%D1%84%D0%B8%D0%BB%D1%8C%D1%82%D1%80/%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3?".getBytes("UTF-8");
|
||||
byte[] cp1251_bytes = "%e2%fb%e1%f0%e0%ed%ee=%d2%e5%ec%ef%e5%f0%e0%f2%f3%f0%e0".getBytes("cp1251");
|
||||
|
||||
byte[] key_bytes = TypeUtil.fromHexString("e2fbe1f0e0edee");
|
||||
byte[] val_bytes = TypeUtil.fromHexString("d2e5ecefe5f0e0f2f3f0e0");
|
||||
String expectedCP1251String = new String(cp1251_bytes, "cp1251");
|
||||
String expectedCP1251Key = new String(key_bytes, "cp1251");
|
||||
String expectedCP1251Value = new String(val_bytes, "cp1251");
|
||||
|
||||
byte[] allbytes = new byte[utf8_bytes.length+cp1251_bytes.length];
|
||||
|
||||
//stick both arrays together to form uri
|
||||
int i=0;
|
||||
for (;i<utf8_bytes.length;i++) {
|
||||
allbytes[i] = utf8_bytes[i];
|
||||
}
|
||||
for (int j=0; j< cp1251_bytes.length;j++)
|
||||
allbytes[i+j] = cp1251_bytes[j];
|
||||
|
||||
|
||||
HttpURI httpuri = new HttpURI();
|
||||
httpuri.parse(allbytes,0,allbytes.length);
|
||||
assertNotNull(httpuri.getQuery("UTF-8")); //will be incorrectly encoded, but no errors
|
||||
assertEquals(expectedCP1251String, httpuri.getQuery("cp1251"));
|
||||
|
||||
//test params decoded correctly
|
||||
MultiMap params = new MultiMap();
|
||||
httpuri.decodeQueryTo(params, "cp1251");
|
||||
String val = params.getString(expectedCP1251Key);
|
||||
assertNotNull(val);
|
||||
assertEquals(expectedCP1251Value, val);
|
||||
|
||||
//test able to set the query encoding and call getQueryString multiple times
|
||||
Request request = new Request();
|
||||
request.setUri(httpuri);
|
||||
request.setAttribute("org.eclipse.jetty.server.Request.queryEncoding", "ISO-8859-1");
|
||||
assertNotNull (request.getQueryString()); //will be incorrect encoding but not null
|
||||
request.setAttribute("org.eclipse.jetty.server.Request.queryEncoding", "cp1251");
|
||||
assertEquals(expectedCP1251String, request.getQueryString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnicodeErrors() throws UnsupportedEncodingException
|
||||
|
|
|
@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
|
|||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
@ -53,6 +54,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
|
|||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -111,6 +113,23 @@ public class DispatcherTest
|
|||
assertEquals(expected, responses);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test public void testForwardNonUTF8() throws Exception
|
||||
{
|
||||
_contextHandler.addServlet(ForwardNonUTF8Servlet.class, "/ForwardServlet/*");
|
||||
_contextHandler.addServlet(AssertNonUTF8ForwardServlet.class, "/AssertForwardServlet/*");
|
||||
|
||||
String expected=
|
||||
"HTTP/1.1 200 OK\r\n"+
|
||||
"Content-Type: text/html\r\n"+
|
||||
"Content-Length: 0\r\n"+
|
||||
"\r\n";
|
||||
String responses = _connector.getResponses("GET /context/ForwardServlet?do=assertforward&foreign=%d2%e5%ec%ef%e5%f0%e0%f2%f3%f0%e0&test=1 HTTP/1.1\n" + "Host: localhost\n\n");
|
||||
|
||||
assertEquals(expected, responses);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForwardWithParam() throws Exception
|
||||
{
|
||||
|
@ -303,6 +322,7 @@ public class DispatcherTest
|
|||
dispatcher = getServletContext().getRequestDispatcher("/IncludeServlet/includepath?do=assertforwardinclude");
|
||||
else if(request.getParameter("do").equals("assertincludeforward"))
|
||||
dispatcher = getServletContext().getRequestDispatcher("/AssertIncludeForwardServlet/assertpath?do=end");
|
||||
|
||||
else if(request.getParameter("do").equals("assertforward"))
|
||||
dispatcher = getServletContext().getRequestDispatcher("/AssertForwardServlet?do=end&do=the");
|
||||
else if(request.getParameter("do").equals("ctx.echo"))
|
||||
|
@ -313,6 +333,18 @@ public class DispatcherTest
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ForwardNonUTF8Servlet extends HttpServlet implements Servlet
|
||||
{
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
RequestDispatcher dispatcher = null;
|
||||
request.setAttribute("org.eclipse.jetty.server.Request.queryEncoding", "cp1251");
|
||||
dispatcher = getServletContext().getRequestDispatcher("/AssertForwardServlet?do=end&else=%D0%B2%D1%8B%D0%B1%D1%80%D0%B0%D0%BD%D0%BE%3D%D0%A2%D0%B5%D0%BC%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D1%83%D1%80%D0%B0");
|
||||
dispatcher.forward(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Forward filter works with roger, echo and reverse echo servlets to test various
|
||||
* forwarding bits using filters.
|
||||
|
@ -531,6 +563,45 @@ public class DispatcherTest
|
|||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class AssertNonUTF8ForwardServlet extends HttpServlet implements Servlet
|
||||
{
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
byte[] cp1251_bytes = TypeUtil.fromHexString("d2e5ecefe5f0e0f2f3f0e0");
|
||||
String expectedCP1251String = new String(cp1251_bytes, "cp1251");
|
||||
|
||||
assertEquals( "/context/ForwardServlet", request.getAttribute(Dispatcher.FORWARD_REQUEST_URI));
|
||||
assertEquals( "/context", request.getAttribute(Dispatcher.FORWARD_CONTEXT_PATH) );
|
||||
assertEquals( "/ForwardServlet", request.getAttribute(Dispatcher.FORWARD_SERVLET_PATH));
|
||||
assertEquals( null, request.getAttribute(Dispatcher.FORWARD_PATH_INFO));
|
||||
assertEquals( "do=assertforward&foreign=%d2%e5%ec%ef%e5%f0%e0%f2%f3%f0%e0&test=1", request.getAttribute(Dispatcher.FORWARD_QUERY_STRING) );
|
||||
|
||||
List<String> expectedAttributeNames = Arrays.asList(Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH,
|
||||
Dispatcher.FORWARD_SERVLET_PATH, Dispatcher.FORWARD_QUERY_STRING);
|
||||
List<String> requestAttributeNames = Collections.list(request.getAttributeNames());
|
||||
assertTrue(requestAttributeNames.containsAll(expectedAttributeNames));
|
||||
|
||||
assertEquals(null, request.getPathInfo());
|
||||
assertEquals(null, request.getPathTranslated());
|
||||
assertTrue(request.getQueryString().startsWith("do=end&else=%D0%B2%D1%8B%D0%B1%D1%80%D0%B0%D0%BD%D0%BE%3D%D0%A2%D0%B5%D0%BC%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D1%83%D1%80%D0%B0&test=1&foreign="));
|
||||
|
||||
String[] vals = request.getParameterValues("foreign");
|
||||
assertTrue(vals!=null);
|
||||
assertEquals(1, vals.length);
|
||||
assertEquals(expectedCP1251String, vals[0]);
|
||||
|
||||
assertEquals("/context/AssertForwardServlet", request.getRequestURI());
|
||||
assertEquals("/context", request.getContextPath());
|
||||
assertEquals("/AssertForwardServlet", request.getServletPath());
|
||||
|
||||
response.setContentType("text/html");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class AssertIncludeServlet extends HttpServlet implements Servlet
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue