399703 made encoding error handling consistent

This commit is contained in:
Greg Wilkins 2013-02-01 15:31:18 +11:00
parent b679565178
commit 1610329d3e
5 changed files with 115 additions and 25 deletions

View File

@ -336,10 +336,20 @@ public class UrlEncoded extends MultiMap 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])));
else
{
buffer.getStringBuilder().append(Utf8Appendable.REPLACEMENT);
i=end;
}
}
else
buffer.append((byte)((convertHexDigit(raw[++i])<<4) + convertHexDigit(raw[++i])));
}
else
{
buffer.getStringBuilder().append(Utf8Appendable.REPLACEMENT);
i=end;
}
break;
default:
@ -356,13 +366,13 @@ public class UrlEncoded extends MultiMap implements Cloneable
if (key != null)
{
value = buffer.length()==0?"":buffer.toString();
value = buffer.length()==0?"":buffer.toReplacedString();
buffer.reset();
map.add(key,value);
}
else if (buffer.length()>0)
{
map.add(buffer.toString(),"");
map.add(buffer.toReplacedString(),"");
}
}
}
@ -763,7 +773,10 @@ public class UrlEncoded extends MultiMap implements Cloneable
buffer.getStringBuffer().append(unicode);
}
else
{
i=length;
buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT);
}
}
else
{
@ -773,13 +786,22 @@ public class UrlEncoded extends MultiMap implements Cloneable
buffer.append(b);
}
}
catch(NotUtf8Exception e)
{
LOG.warn(e.toString());
LOG.debug(e);
}
catch(NumberFormatException nfe)
{
LOG.debug(nfe);
buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT);
}
}
else
{
buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT);
i=length;
}
}
else if (buffer!=null)
buffer.getStringBuffer().append(c);
@ -792,7 +814,7 @@ public class UrlEncoded extends MultiMap implements Cloneable
return encoded.substring(offset,offset+length);
}
return buffer.toString();
return buffer.toReplacedString();
}
else
{
@ -843,12 +865,20 @@ public class UrlEncoded extends MultiMap implements Cloneable
{
if ('u'==encoded.charAt(offset+i+1))
{
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;
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
{
@ -866,8 +896,8 @@ public class UrlEncoded extends MultiMap implements Cloneable
}
else
{
ba[n++] = (byte)'%';
i++;
ba[n++] = (byte)'?';
i=length;
}
}
else if (c=='+')

View File

@ -20,6 +20,9 @@ package org.eclipse.jetty.util;
import java.io.IOException;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */
/**
* Utf8 Appendable abstract base class
@ -46,6 +49,7 @@ import java.io.IOException;
**/
public abstract class Utf8Appendable
{
protected static final Logger LOG = Log.getLogger(Utf8Appendable.class);
public static final char REPLACEMENT = '\ufffd';
private static final int UTF8_ACCEPT = 0;
private static final int UTF8_REJECT = 12;
@ -192,4 +196,43 @@ public abstract class Utf8Appendable
super("Not valid UTF8! "+reason);
}
}
protected void checkState()
{
if (!isUtf8SequenceComplete())
{
_codep=0;
_state = UTF8_ACCEPT;
try
{
_appendable.append(REPLACEMENT);
}
catch(IOException e)
{
throw new RuntimeException(e);
}
throw new NotUtf8Exception("incomplete UTF8 sequence");
}
}
public String toReplacedString()
{
if (!isUtf8SequenceComplete())
{
_codep=0;
_state = UTF8_ACCEPT;
try
{
_appendable.append(REPLACEMENT);
}
catch(IOException e)
{
throw new RuntimeException(e);
}
Throwable th= new NotUtf8Exception("incomplete UTF8 sequence");
LOG.warn(th.toString());
LOG.debug(th);
}
return _appendable.toString();
}
}

View File

@ -72,10 +72,4 @@ public class Utf8StringBuffer extends Utf8Appendable
checkState();
return _buffer.toString();
}
private void checkState()
{
if (!isUtf8SequenceComplete())
throw new IllegalArgumentException("Tried to read incomplete UTF8 decoded String");
}
}

View File

@ -74,9 +74,5 @@ public class Utf8StringBuilder extends Utf8Appendable
return _buffer.toString();
}
private void checkState()
{
if (!isUtf8SequenceComplete())
throw new IllegalArgumentException("Tried to read incomplete UTF8 decoded String");
}
}

View File

@ -159,11 +159,38 @@ public class URLEncodedTest
public void testBadEncoding() throws UnsupportedEncodingException
{
UrlEncoded url_encoded = new UrlEncoded();
url_encoded.decode("Name15=xx%zz", "UTF-8");
url_encoded.decode("Name15=xx%zzyy", "UTF-8");
assertEquals("encoded param size",1, url_encoded.size());
assertEquals("encoded get", "xx\ufffd", url_encoded.getString("Name15"));
assertEquals("encoded get", "xx\ufffdyy", url_encoded.getString("Name15"));
byte[] bad="Name=%FF%FF%FF".getBytes("UTF-8");
MultiMap<String> map = new MultiMap<String>();
UrlEncoded.decodeUtf8To(bad,0,bad.length,map);
assertEquals("encoded param size",1, map.size());
assertEquals("encoded get", "\ufffd\ufffd\ufffd", map.getString("Name"));
assertEquals("xxx",UrlEncoded.decodeString("xxx%u123",0,5,"UTF-8"));
url_encoded.clear();
url_encoded.decode("Name=%FF%FF%FF", "UTF-8");
assertEquals("encoded param size",1, url_encoded.size());
assertEquals("encoded get", "\ufffd\ufffd\ufffd", url_encoded.getString("Name"));
url_encoded.clear();
url_encoded.decode("Name=%EF%EF%EF", "UTF-8");
assertEquals("encoded param size",1, url_encoded.size());
assertEquals("encoded get", "\ufffd\ufffd", url_encoded.getString("Name"));
assertEquals("x",UrlEncoded.decodeString("x",0,1,"UTF-8"));
assertEquals("x\ufffd",UrlEncoded.decodeString("x%",0,2,"UTF-8"));
assertEquals("x\ufffd",UrlEncoded.decodeString("x%2",0,3,"UTF-8"));
assertEquals("x ",UrlEncoded.decodeString("x%20",0,4,"UTF-8"));
assertEquals("xxx",UrlEncoded.decodeString("xxx",0,3,"UTF-8"));
assertEquals("xxx\ufffd",UrlEncoded.decodeString("xxx%",0,4,"UTF-8"));
assertEquals("xxx\ufffd",UrlEncoded.decodeString("xxx%u",0,5,"UTF-8"));
assertEquals("xxx\ufffd",UrlEncoded.decodeString("xxx%u1",0,6,"UTF-8"));
assertEquals("xxx\ufffd",UrlEncoded.decodeString("xxx%u12",0,7,"UTF-8"));
assertEquals("xxx\ufffd",UrlEncoded.decodeString("xxx%u123",0,8,"UTF-8"));
assertEquals("xxx\u1234",UrlEncoded.decodeString("xxx%u1234",0,9,"UTF-8"));
}