diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java index 06741c0a130..87b2f2e4a28 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java @@ -462,52 +462,60 @@ public class UrlEncoded extends MultiMap implements Cloneable int totalLength=0; while ((b=in.read())>=0) { - switch ((char) 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; - if (maxKeys>0 && map.size()>maxKeys) - { - LOG.warn("maxFormKeys limit exceeded keys>{}",maxKeys); - return; - } - break; - - case '=': - if (key!=null) - { + switch ((char) 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; + if (maxKeys>0 && map.size()>maxKeys) + { + LOG.warn("maxFormKeys limit exceeded keys>{}",maxKeys); + return; + } + break; + + case '=': + if (key!=null) + { + buffer.append((byte)b); + break; + } + key = buffer.toString(); + buffer.reset(); + break; + + case '+': + buffer.append((byte)' '); + break; + + case '%': + int dh=in.read(); + int dl=in.read(); + if (dh<0||dl<0) + break; + buffer.append((byte)((TypeUtil.convertHexDigit((byte)dh)<<4) + TypeUtil.convertHexDigit((byte)dl))); + break; + default: buffer.append((byte)b); break; - } - key = buffer.toString(); - buffer.reset(); - break; - - case '+': - buffer.append((byte)' '); - break; - - case '%': - int dh=in.read(); - int dl=in.read(); - if (dh<0||dl<0) - break; - buffer.append((byte)((TypeUtil.convertHexDigit((byte)dh)<<4) + TypeUtil.convertHexDigit((byte)dl))); - break; - default: - buffer.append((byte)b); - break; + } + } + catch(NotUtf8Exception e) + { + LOG.warn(e.toString()); + LOG.debug(e); } if (maxLength>=0 && (++totalLength > maxLength)) throw new IllegalStateException("Form too large"); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java index 8fe840c1b88..de02cc4e3f4 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java @@ -40,7 +40,7 @@ import java.io.IOException; **/ public abstract class Utf8Appendable { - private final char REPLACEMENT = '\ufffd'; + public static final char REPLACEMENT = '\ufffd'; private static final int UTF8_ACCEPT = 0; private static final int UTF8_REJECT = 12; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java index 42bba2b05bc..1678338df77 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java @@ -220,7 +220,6 @@ public class URLEncodedTest */ } - /* -------------------------------------------------------------- */ @Test public void testUtf8() @@ -236,4 +235,21 @@ public class URLEncodedTest String expected = new String(TypeUtil.fromHexString(hex),"utf-8"); assertEquals(expected,url_encoded.get("text")); } + + /* -------------------------------------------------------------- */ + @Test + public void testNotUtf8() throws Exception + { + String query="name=X%c0%afZ"; + + MultiMap map = new MultiMap(); + + UrlEncoded.decodeUtf8To(query.getBytes(StringUtil.__ISO_8859_1),0,query.length(),map); + assertEquals("X"+Utf8Appendable.REPLACEMENT+Utf8Appendable.REPLACEMENT+"Z",map.getValue("name",0)); + + map.clear(); + + UrlEncoded.decodeUtf8To(new ByteArrayInputStream(query.getBytes(StringUtil.__ISO_8859_1)),map,100,2); + assertEquals("X"+Utf8Appendable.REPLACEMENT+Utf8Appendable.REPLACEMENT+"Z",map.getValue("name",0)); + } }