Index: src/main/java/org/mortbay/util/UrlEncoded.java
===================================================================
--- src/main/java/org/mortbay/util/UrlEncoded.java	(revision 4189)
+++ src/main/java/org/mortbay/util/UrlEncoded.java	(working copy)
@@ -641,9 +641,19 @@
 
                     while(c=='%' && (i+2)<length)
                     {
-                        byte b=(byte)TypeUtil.parseInt(encoded,offset+i+1,2,16);
-                        buffer.append(b);
-                        i+=3;
+                        try
+                        {
+                            byte b=(byte)TypeUtil.parseInt(encoded,offset+i+1,2,16);
+                            buffer.append(b);
+                            i+=3;
+                        }
+                        catch(NumberFormatException nfe)
+                        {
+                            buffer.getStringBuffer().append('%');
+                            for(char next; ((next=encoded.charAt(++i+offset))!='%');)
+                                buffer.getStringBuffer().append((next=='+' ? ' ' : next));
+                        }
+
                         if (i<length)
                             c = encoded.charAt(offset+i);
                     }
@@ -704,8 +714,26 @@
                         while(c>=0 && c<=0xff)
                         {
                             if (c=='%')
-                            {    ba[n++]=(byte)TypeUtil.parseInt(encoded,offset+i+1,2,16);
-                                i+=3;
+                            {   
+                                if(i+2<length)
+                                {
+                                    try
+                                    {
+                                        ba[n++]=(byte)TypeUtil.parseInt(encoded,offset+i+1,2,16);
+                                        i+=3;
+                                    }
+                                    catch(NumberFormatException nfe)
+                                    {                                        
+                                        ba[n-1] = (byte)'%';                                    
+                                        for(char next; ((next=encoded.charAt(++i+offset))!='%');)
+                                            ba[n++] = (byte)(next=='+' ? ' ' : next);
+                                    }
+                                }
+                                else
+                                {
+                                    ba[n++] = (byte)'%';
+                                    i++;
+                                }
                             }
                             else if (c=='+')
                             {
Index: src/test/java/org/mortbay/util/URLEncodedTest.java
===================================================================
--- src/test/java/org/mortbay/util/URLEncodedTest.java	(revision 4189)
+++ src/test/java/org/mortbay/util/URLEncodedTest.java	(working copy)
@@ -122,6 +122,16 @@
         url_encoded.decode("Name12=xxVerdi+%2F+og+2zz", "UTF-8");
         assertEquals("encoded param size",1, url_encoded.size());
         assertEquals("encoded get", url_encoded.getString("Name12"),"xxVerdi / og 2zz");
+        
+        url_encoded.clear();
+        url_encoded.decode("Name14=%GG%+%%+%", "ISO-8859-1");
+        assertEquals("encoded param size",1, url_encoded.size());
+        assertEquals("encoded get", url_encoded.getString("Name14"),"%GG% %% %");
+        
+        url_encoded.clear();
+        url_encoded.decode("Name14=%GG%+%%+%", "UTF-8");
+        assertEquals("encoded param size",1, url_encoded.size());
+        assertEquals("encoded get", url_encoded.getString("Name14"),"%GG% %% %");
 
         /* Not every jvm supports this encoding */
         

