360836 Accept parameters with bad UTF-8. Use replacement character

This commit is contained in:
Greg Wilkins 2011-10-19 16:23:56 +11:00
parent acc1b19228
commit c93e1c297f
3 changed files with 76 additions and 39 deletions

View File

@ -92,12 +92,12 @@ public class RequestTest
{
//catch the error and check the param map is not null
map = request.getParameterMap();
System.err.println(map);
assertFalse(map == null);
assertTrue(map.isEmpty());
Enumeration names = request.getParameterNames();
assertFalse(names.hasMoreElements());
}
return true;
@ -111,7 +111,32 @@ public class RequestTest
"Content-Type: text/html;charset=utf8\n"+
"\n";
String response = _connector.getResponses(request);
String responses=_connector.getResponses(request);
assertTrue(responses.startsWith("HTTP/1.1 200"));
}
@Test
public void testBadUtf8ParamExtraction() throws Exception
{
_handler._checker = new RequestTester()
{
public boolean check(HttpServletRequest request,HttpServletResponse response)
{
String value=request.getParameter("param");
return value.startsWith("aaa") && value.endsWith("bb");
}
};
//Send a request with query string with illegal hex code to cause
//an exception parsing the params
String request="GET /?param=aaa%E7bbb HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: text/html;charset=utf8\n"+
"\n";
String responses=_connector.getResponses(request);
assertTrue(responses.startsWith("HTTP/1.1 200"));
}

View File

@ -20,6 +20,9 @@ import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */
/** Handles coding of MIME "x-www-form-urlencoded".
@ -42,7 +45,7 @@ import java.util.Map;
*/
public class UrlEncoded extends MultiMap
{
// private static final Logger LOG = Log.getLogger(UrlEncoded.class);
private static final Logger LOG = Log.getLogger(UrlEncoded.class);
public static final String ENCODING = System.getProperty("org.eclipse.jetty.util.UrlEncoding.charset",StringUtil.__UTF8);
@ -267,50 +270,58 @@ public class UrlEncoded extends MultiMap
{
String key = null;
String value = null;
// TODO cache of parameter names ???
int end=offset+length;
for (int i=offset;i<end;i++)
{
byte b=raw[i];
switch ((char)(0xff&b))
try
{
case '&':
value = buffer.length()==0?"":buffer.toString();
buffer.reset();
if (key != null)
{
map.add(key,value);
}
else if (value!=null&&value.length()>0)
{
map.add(value,"");
}
key = null;
value=null;
break;
case '=':
if (key!=null)
{
switch ((char)(0xff&b))
{
case '&':
value = buffer.length()==0?"":buffer.toString();
buffer.reset();
if (key != null)
{
map.add(key,value);
}
else if (value!=null&&value.length()>0)
{
map.add(value,"");
}
key = null;
value=null;
break;
case '=':
if (key!=null)
{
buffer.append(b);
break;
}
key = buffer.toString();
buffer.reset();
break;
case '+':
buffer.append((byte)' ');
break;
case '%':
if (i+2<end)
buffer.append((byte)((TypeUtil.convertHexDigit(raw[++i])<<4) + TypeUtil.convertHexDigit(raw[++i])));
break;
default:
buffer.append(b);
break;
}
key = buffer.toString();
buffer.reset();
break;
case '+':
buffer.append((byte)' ');
break;
case '%':
if (i+2<end)
buffer.append((byte)((TypeUtil.convertHexDigit(raw[++i])<<4) + TypeUtil.convertHexDigit(raw[++i])));
break;
default:
buffer.append(b);
break;
}
}
catch(NotUtf8Exception e)
{
LOG.warn(e.toString());
}
}

View File

@ -159,6 +159,7 @@ public abstract class Utf8Appendable
}
else if (_state == UTF8_REJECT)
{
_codep=0;
_state = UTF8_ACCEPT;
_appendable.append(REPLACEMENT);
throw new NotUtf8Exception();