bruno       2003/05/23 06:08:37

  Modified:    src/java/org/apache/cocoon/util NetUtils.java
  Log:
  Improved implementation of decodePath
  
  Revision  Changes    Path
  1.2       +46 -8     cocoon-2.1/src/java/org/apache/cocoon/util/NetUtils.java
  
  Index: NetUtils.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/util/NetUtils.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- NetUtils.java     9 Mar 2003 00:09:43 -0000       1.1
  +++ NetUtils.java     23 May 2003 13:08:35 -0000      1.2
  @@ -53,6 +53,7 @@
   import java.io.ByteArrayOutputStream;
   import java.io.IOException;
   import java.io.OutputStreamWriter;
  +import java.io.UnsupportedEncodingException;
   
   import java.util.BitSet;
   import java.util.Enumeration;
  @@ -122,19 +123,56 @@
       }
   
       /**
  -     * Decode a path
  +     * Decode a path.
  +     *
  +     * <p>Interprets %XX (where XX is hexadecimal number) as UTF-8 encoded 
bytes.
  +     * <p>The validity of the input path is not checked (i.e. characters 
that were not encoded will
  +     * not be reported as errors).
  +     * <p>This method differs from URLDecoder.decode in that it always uses 
UTF-8 (while URLDecoder
  +     * uses the platform default encoding, often ISO-8859-1), and doesn't 
translate + characters to spaces.
        *
        * @param path the path to decode
        * @return the decoded path
        */
       public static String decodePath(String path) {
  -        // VG: JDK1.2 MEthods throws an exception; JDK1.3 - not.
  -        // 
http://java.sun.com/products/jdk/1.2/docs/api/java/net/URLDecoder.html#decode(java.lang.String)
  -        try {
  -            return java.net.URLDecoder.decode( path );
  -        } catch (Exception e) {
  -            return path;
  +        StringBuffer translatedPath = new StringBuffer(path.length());
  +        byte[] encodedchars = new byte[path.length() / 3];
  +        int i = 0;
  +        int length = path.length();
  +        int encodedcharsLength = 0;
  +        while (i < length) {
  +            if (path.charAt(i) == '%') {
  +                // we must process all consecutive %-encoded characters in 
one go, because they represent
  +                // an UTF-8 encoded string, and in UTF-8 one character can 
be encoded as multiple bytes
  +                while (i < length && path.charAt(i) == '%') {
  +                    if (i + 2 < length) {
  +                        try {
  +                            byte x = (byte)Integer.parseInt(path.substring(i 
+ 1, i + 3), 16);
  +                            encodedchars[encodedcharsLength] = x;
  +                        } catch (NumberFormatException e) {
  +                            throw new 
IllegalArgumentException("NetUtils.decodePath: illegal hex characters in 
pattern %" + path.substring(i + 1, i + 3));
  +                        }
  +                        encodedcharsLength++;
  +                        i += 3;
  +                    } else {
  +                        throw new 
IllegalArgumentException("NetUtils.decodePath: % character should be followed 
by 2 hexadecimal characters.");
  +                    }
  +                }
  +                try {
  +                    String translatedPart = new String(encodedchars, 0, 
encodedcharsLength, "UTF-8");
  +                    translatedPath.append(translatedPart);
  +                } catch (UnsupportedEncodingException e) {
  +                    // the situation that UTF-8 is not supported is quite 
theoretical, so throw a runtime exception
  +                    throw new RuntimeException("Problem in decodePath: UTF-8 
encoding not supported.");
  +                }
  +                encodedcharsLength = 0;
  +            } else {
  +                // a normal character
  +                translatedPath.append(path.charAt(i));
  +                i++;
  +            }
           }
  +        return translatedPath.toString();
       }
   
       /**
  
  
  

Reply via email to