411538 Use Replacement character for bad parameter % encodings
This commit is contained in:
parent
d857562059
commit
32ec8255db
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.http.HttpURI;
|
|||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.Utf8Appendable;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -322,29 +323,15 @@ public class HttpURITest
|
|||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
HttpURI huri=new HttpURI(uri);
|
||||
MultiMap<String> params = new MultiMap<>();
|
||||
huri.decodeQueryTo(params);
|
||||
System.err.println(params);
|
||||
Assert.assertTrue(false);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
}
|
||||
HttpURI huri=new HttpURI(uri);
|
||||
MultiMap<String> params = new MultiMap<>();
|
||||
huri.decodeQueryTo(params);
|
||||
assertEquals("data"+Utf8Appendable.REPLACEMENT+"here"+Utf8Appendable.REPLACEMENT,params.getValue("invalid",0));
|
||||
|
||||
try
|
||||
{
|
||||
HttpURI huri=new HttpURI(uri);
|
||||
MultiMap<String> params = new MultiMap<>();
|
||||
huri.decodeQueryTo(params,"UTF-8");
|
||||
System.err.println(params);
|
||||
Assert.assertTrue(false);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
}
|
||||
huri=new HttpURI(uri);
|
||||
params = new MultiMap<>();
|
||||
huri.decodeQueryTo(params,"UTF-8");
|
||||
assertEquals("data"+Utf8Appendable.REPLACEMENT+"here"+Utf8Appendable.REPLACEMENT,params.getValue("invalid",0));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.MultiPartInputStreamParser;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.Utf8Appendable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
|
@ -100,24 +101,11 @@ public class RequestTest
|
|||
@Override
|
||||
public boolean check(HttpServletRequest request,HttpServletResponse response)
|
||||
{
|
||||
Map map = null;
|
||||
try
|
||||
{
|
||||
//do the parse
|
||||
request.getParameterMap();
|
||||
Assert.fail("Expected parsing failure");
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//catch the error and check the param map is not null
|
||||
map = request.getParameterMap();
|
||||
assertFalse(map == null);
|
||||
assertTrue(map.isEmpty());
|
||||
|
||||
Enumeration names = request.getParameterNames();
|
||||
assertFalse(names.hasMoreElements());
|
||||
}
|
||||
Map<String,String[]> map = null;
|
||||
//do the parse
|
||||
map = request.getParameterMap();
|
||||
assertEquals("aaa"+Utf8Appendable.REPLACEMENT+"bbb",map.get("param")[0]);
|
||||
assertEquals("value",map.get("other")[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -125,7 +113,7 @@ public class RequestTest
|
|||
|
||||
//Send a request with query string with illegal hex code to cause
|
||||
//an exception parsing the params
|
||||
String request="GET /?param=%ZZaaa HTTP/1.1\r\n"+
|
||||
String request="GET /?param=aaa%ZZbbb&other=value HTTP/1.1\r\n"+
|
||||
"Host: whatever\r\n"+
|
||||
"Content-Type: text/html;charset=utf8\n"+
|
||||
"Connection: close\n"+
|
||||
|
|
|
@ -353,7 +353,7 @@ public class TypeUtil
|
|||
{
|
||||
byte b = (byte)((c & 0x1f) + ((c >> 6) * 0x19) - 0x10);
|
||||
if (b<0 || b>15)
|
||||
throw new IllegalArgumentException("!hex "+c);
|
||||
throw new NumberFormatException("!hex "+c);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
|
|
@ -323,7 +323,13 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
{
|
||||
i++;
|
||||
if (i+4<end)
|
||||
buffer.getStringBuilder().append(Character.toChars((convertHexDigit(raw[++i])<<12) +(convertHexDigit(raw[++i])<<8) + (convertHexDigit(raw[++i])<<4) +convertHexDigit(raw[++i])));
|
||||
{
|
||||
byte top=raw[++i];
|
||||
byte hi=raw[++i];
|
||||
byte lo=raw[++i];
|
||||
byte bot=raw[++i];
|
||||
buffer.getStringBuilder().append(Character.toChars((convertHexDigit(top)<<12) +(convertHexDigit(hi)<<8) + (convertHexDigit(lo)<<4) +convertHexDigit(bot)));
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.getStringBuilder().append(Utf8Appendable.REPLACEMENT);
|
||||
|
@ -331,7 +337,11 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
}
|
||||
}
|
||||
else
|
||||
buffer.append((byte)((convertHexDigit(raw[++i])<<4) + convertHexDigit(raw[++i])));
|
||||
{
|
||||
byte hi=raw[++i];
|
||||
byte lo=raw[++i];
|
||||
buffer.append((byte)((convertHexDigit(hi)<<4) + convertHexDigit(lo)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -350,6 +360,12 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
}
|
||||
catch(NumberFormatException e)
|
||||
{
|
||||
buffer.append(Utf8Appendable.REPLACEMENT_UTF8,0,3);
|
||||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (key != null)
|
||||
|
@ -552,6 +568,12 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
}
|
||||
catch(NumberFormatException e)
|
||||
{
|
||||
buffer.append(Utf8Appendable.REPLACEMENT_UTF8,0,3);
|
||||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
}
|
||||
if (maxLength>=0 && (++totalLength > maxLength))
|
||||
throw new IllegalStateException("Form too large");
|
||||
}
|
||||
|
@ -798,9 +820,10 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
}
|
||||
catch(NumberFormatException nfe)
|
||||
catch(NumberFormatException e)
|
||||
{
|
||||
LOG.debug(nfe);
|
||||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT);
|
||||
}
|
||||
}
|
||||
|
@ -870,32 +893,33 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
|
|||
{
|
||||
if ('u'==encoded.charAt(offset+i+1))
|
||||
{
|
||||
if (i+6<length)
|
||||
{
|
||||
int o=offset+i+2;
|
||||
i+=6;
|
||||
String unicode = new String(Character.toChars(TypeUtil.parseInt(encoded,o,4,16)));
|
||||
byte[] reencoded = unicode.getBytes(charset);
|
||||
System.arraycopy(reencoded,0,ba,n,reencoded.length);
|
||||
n+=reencoded.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
ba[n++] = (byte)'?';
|
||||
i=length;
|
||||
}
|
||||
if (i+6<length)
|
||||
{
|
||||
int o=offset+i+2;
|
||||
i+=6;
|
||||
String unicode = new String(Character.toChars(TypeUtil.parseInt(encoded,o,4,16)));
|
||||
byte[] reencoded = unicode.getBytes(charset);
|
||||
System.arraycopy(reencoded,0,ba,n,reencoded.length);
|
||||
n+=reencoded.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
ba[n++] = (byte)'?';
|
||||
i=length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int o=offset+i+1;
|
||||
i+=3;
|
||||
ba[n]=(byte)TypeUtil.parseInt(encoded,o,2,16);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
catch(NumberFormatException nfe)
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.ignore(nfe);
|
||||
LOG.warn(e.toString());
|
||||
LOG.debug(e);
|
||||
ba[n++] = (byte)'?';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ public abstract class Utf8Appendable
|
|||
{
|
||||
protected static final Logger LOG = Log.getLogger(Utf8Appendable.class);
|
||||
public static final char REPLACEMENT = '\ufffd';
|
||||
public static final byte[] REPLACEMENT_UTF8 = new byte[] {(byte)0xEF,(byte)0xBF,(byte)0xBD };
|
||||
private static final int UTF8_ACCEPT = 0;
|
||||
private static final int UTF8_REJECT = 12;
|
||||
|
||||
|
|
Loading…
Reference in New Issue