411538 Use Replacement character for bad parameter % encodings

This commit is contained in:
Greg Wilkins 2013-06-27 10:19:51 +10:00
parent d857562059
commit 32ec8255db
5 changed files with 62 additions and 62 deletions

View File

@ -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));
}

View File

@ -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"+

View File

@ -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;
}

View File

@ -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)'?';
}
}

View File

@ -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;