1 17 18 package org.apache.tomcat.util.buf; 19 20 import java.io.CharConversionException ; 21 import java.io.IOException ; 22 23 31 public final class UDecoder { 32 33 private static org.apache.commons.logging.Log log= 34 org.apache.commons.logging.LogFactory.getLog(UDecoder.class ); 35 36 public UDecoder() 37 { 38 } 39 40 43 public void convert( ByteChunk mb ) 44 throws IOException 45 { 46 convert(mb, true); 47 } 48 49 51 public void convert( ByteChunk mb, boolean query ) 52 throws IOException 53 { 54 int start=mb.getOffset(); 55 byte buff[]=mb.getBytes(); 56 int end=mb.getEnd(); 57 58 int idx= ByteChunk.indexOf( buff, start, end, '%' ); 59 int idx2=-1; 60 if( query ) 61 idx2= ByteChunk.indexOf( buff, start, end, '+' ); 62 if( idx<0 && idx2<0 ) { 63 return; 64 } 65 66 if( idx2 >= 0 && idx2 < idx ) idx=idx2; 68 if( idx < 0 ) idx=idx2; 69 70 for( int j=idx; j<end; j++, idx++ ) { 71 if( buff[ j ] == '+' && query) { 72 buff[idx]= (byte)' ' ; 73 } else if( buff[ j ] != '%' ) { 74 buff[idx]= buff[j]; 75 } else { 76 if( j+2 >= end ) { 78 throw new CharConversionException ("EOF"); 79 } 80 byte b1= buff[j+1]; 81 byte b2=buff[j+2]; 82 if( !isHexDigit( b1 ) || ! isHexDigit(b2 )) 83 throw new CharConversionException ( "isHexDigit"); 84 85 j+=2; 86 int res=x2c( b1, b2 ); 87 buff[idx]=(byte)res; 88 } 89 } 90 91 mb.setEnd( idx ); 92 93 return; 94 } 95 96 99 102 public void convert( CharChunk mb ) 103 throws IOException 104 { 105 convert(mb, true); 106 } 107 108 110 public void convert( CharChunk mb, boolean query ) 111 throws IOException 112 { 113 int start=mb.getOffset(); 115 char buff[]=mb.getBuffer(); 116 int cend=mb.getEnd(); 117 118 int idx= CharChunk.indexOf( buff, start, cend, '%' ); 119 int idx2=-1; 120 if( query ) 121 idx2= CharChunk.indexOf( buff, start, cend, '+' ); 122 if( idx<0 && idx2<0 ) { 123 return; 124 } 125 126 if( idx2 >= 0 && idx2 < idx ) idx=idx2; 127 if( idx < 0 ) idx=idx2; 128 129 for( int j=idx; j<cend; j++, idx++ ) { 130 if( buff[ j ] == '+' && query ) { 131 buff[idx]=( ' ' ); 132 } else if( buff[ j ] != '%' ) { 133 buff[idx]=buff[j]; 134 } else { 135 if( j+2 >= cend ) { 137 throw new CharConversionException ("EOF"); 139 } 140 char b1= buff[j+1]; 141 char b2=buff[j+2]; 142 if( !isHexDigit( b1 ) || ! isHexDigit(b2 )) 143 throw new CharConversionException ("isHexDigit"); 144 145 j+=2; 146 int res=x2c( b1, b2 ); 147 buff[idx]=(char)res; 148 } 149 } 150 mb.setEnd( idx ); 151 } 152 153 156 public void convert(MessageBytes mb) 157 throws IOException 158 { 159 convert(mb, true); 160 } 161 162 164 public void convert(MessageBytes mb, boolean query) 165 throws IOException 166 { 167 168 switch (mb.getType()) { 169 case MessageBytes.T_STR: 170 String strValue=mb.toString(); 171 if( strValue==null ) return; 172 mb.setString( convert( strValue, query )); 173 break; 174 case MessageBytes.T_CHARS: 175 CharChunk charC=mb.getCharChunk(); 176 convert( charC, query ); 177 break; 178 case MessageBytes.T_BYTES: 179 ByteChunk bytesC=mb.getByteChunk(); 180 convert( bytesC, query ); 181 break; 182 } 183 } 184 185 public final String convert(String str) 188 { 189 return convert(str, true); 190 } 191 192 public final String convert(String str, boolean query) 193 { 194 if (str == null) return null; 195 196 if( (!query || str.indexOf( '+' ) < 0) && str.indexOf( '%' ) < 0 ) 197 return str; 198 199 StringBuffer dec = new StringBuffer (); int strPos = 0; 201 int strLen = str.length(); 202 203 dec.ensureCapacity(str.length()); 204 while (strPos < strLen) { 205 int laPos; 207 for (laPos = strPos; laPos < strLen; laPos++) { 209 char laChar = str.charAt(laPos); 210 if ((laChar == '+' && query) || (laChar == '%')) { 211 break; 212 } 213 } 214 215 if (laPos > strPos) { 217 dec.append(str.substring(strPos,laPos)); 218 strPos = laPos; 219 } 220 221 if (strPos >= strLen) { 223 break; 224 } 225 226 char metaChar = str.charAt(strPos); 228 if (metaChar == '+') { 229 dec.append(' '); 230 strPos++; 231 continue; 232 } else if (metaChar == '%') { 233 dec.append((char)Integer. 237 parseInt(str.substring(strPos + 1, strPos + 3),16)); 238 strPos += 3; 239 } 240 } 241 242 return dec.toString(); 243 } 244 245 246 247 private static boolean isHexDigit( int c ) { 248 return ( ( c>='0' && c<='9' ) || 249 ( c>='a' && c<='f' ) || 250 ( c>='A' && c<='F' )); 251 } 252 253 private static int x2c( byte b1, byte b2 ) { 254 int digit= (b1>='A') ? ( (b1 & 0xDF)-'A') + 10 : 255 (b1 -'0'); 256 digit*=16; 257 digit +=(b2>='A') ? ( (b2 & 0xDF)-'A') + 10 : 258 (b2 -'0'); 259 return digit; 260 } 261 262 private static int x2c( char b1, char b2 ) { 263 int digit= (b1>='A') ? ( (b1 & 0xDF)-'A') + 10 : 264 (b1 -'0'); 265 digit*=16; 266 digit +=(b2>='A') ? ( (b2 & 0xDF)-'A') + 10 : 267 (b2 -'0'); 268 return digit; 269 } 270 271 private final static int debug=0; 272 private static void log( String s ) { 273 if (log.isDebugEnabled()) 274 log.debug("URLDecoder: " + s ); 275 } 276 277 } 278 | Popular Tags |