~ubuntu-branches/ubuntu/oneiric/tomcat6/oneiric

« back to all changes in this revision

Viewing changes to java/org/apache/tomcat/util/buf/UDecoder.java

  • Committer: Bazaar Package Importer
  • Author(s): Thierry Carrez
  • Date: 2010-07-20 14:36:48 UTC
  • mfrom: (2.2.17 sid)
  • Revision ID: james.westby@ubuntu.com-20100720143648-23y81x6cq1kv1z00
Tags: 6.0.28-2
* Add debconf questions for user, group and Java options.
* Use ucf to install /etc/default/tomcat6 from a template
* Drop CATALINA_BASE and CATALINA_HOME from /etc/default/tomcat6 since we
  shouldn't encourage users to change those anyway

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 */
31
31
public final class UDecoder {
32
32
    
33
 
    private static org.apache.juli.logging.Log log=
34
 
        org.apache.juli.logging.LogFactory.getLog(UDecoder.class );
35
 
    
36
33
    protected static final boolean ALLOW_ENCODED_SLASH = 
37
34
        Boolean.valueOf(System.getProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "false")).booleanValue();
38
35
 
52
49
    /** URLDecode, will modify the source.
53
50
     */
54
51
    public void convert( ByteChunk mb, boolean query )
55
 
        throws IOException
 
52
        throws IOException
56
53
    {
57
 
        int start=mb.getOffset();
58
 
        byte buff[]=mb.getBytes();
59
 
        int end=mb.getEnd();
 
54
        int start=mb.getOffset();
 
55
        byte buff[]=mb.getBytes();
 
56
        int end=mb.getEnd();
60
57
 
61
 
        int idx= ByteChunk.indexOf( buff, start, end, '%' );
 
58
        int idx= ByteChunk.indexOf( buff, start, end, '%' );
62
59
        int idx2=-1;
63
60
        if( query )
64
61
            idx2= ByteChunk.indexOf( buff, start, end, '+' );
65
 
        if( idx<0 && idx2<0 ) {
66
 
            return;
67
 
        }
 
62
        if( idx<0 && idx2<0 ) {
 
63
            return;
 
64
        }
68
65
 
69
 
        // idx will be the smallest positive inxes ( first % or + )
70
 
        if( idx2 >= 0 && idx2 < idx ) idx=idx2;
71
 
        if( idx < 0 ) idx=idx2;
 
66
        // idx will be the smallest positive inxes ( first % or + )
 
67
        if( idx2 >= 0 && idx2 < idx ) idx=idx2;
 
68
        if( idx < 0 ) idx=idx2;
72
69
 
73
70
    boolean noSlash = !(ALLOW_ENCODED_SLASH || query);
74
71
    
75
 
        for( int j=idx; j<end; j++, idx++ ) {
76
 
            if( buff[ j ] == '+' && query) {
77
 
                buff[idx]= (byte)' ' ;
78
 
            } else if( buff[ j ] != '%' ) {
79
 
                buff[idx]= buff[j];
80
 
            } else {
81
 
                // read next 2 digits
82
 
                if( j+2 >= end ) {
83
 
                    throw new CharConversionException("EOF");
84
 
                }
85
 
                byte b1= buff[j+1];
86
 
                byte b2=buff[j+2];
87
 
                if( !isHexDigit( b1 ) || ! isHexDigit(b2 ))
88
 
                    throw new CharConversionException( "isHexDigit");
89
 
                
90
 
                j+=2;
91
 
                int res=x2c( b1, b2 );
 
72
        for( int j=idx; j<end; j++, idx++ ) {
 
73
            if( buff[ j ] == '+' && query) {
 
74
                buff[idx]= (byte)' ' ;
 
75
            } else if( buff[ j ] != '%' ) {
 
76
                buff[idx]= buff[j];
 
77
            } else {
 
78
                // read next 2 digits
 
79
                if( j+2 >= end ) {
 
80
                    throw new CharConversionException("EOF");
 
81
                }
 
82
                byte b1= buff[j+1];
 
83
                byte b2=buff[j+2];
 
84
                if( !isHexDigit( b1 ) || ! isHexDigit(b2 ))
 
85
                    throw new CharConversionException( "isHexDigit");
 
86
                
 
87
                j+=2;
 
88
                int res=x2c( b1, b2 );
92
89
        if (noSlash && (res == '/')) {
93
90
            throw new CharConversionException( "noSlash");
94
91
        }
95
 
                buff[idx]=(byte)res;
96
 
            }
97
 
        }
 
92
                buff[idx]=(byte)res;
 
93
            }
 
94
        }
98
95
 
99
 
        mb.setEnd( idx );
100
 
        
101
 
        return;
 
96
        mb.setEnd( idx );
 
97
        
 
98
        return;
102
99
    }
103
100
 
104
101
    // -------------------- Additional methods --------------------
108
105
     *  Includes converting  '+' to ' '.
109
106
     */
110
107
    public void convert( CharChunk mb )
111
 
        throws IOException
 
108
        throws IOException
112
109
    {
113
110
        convert(mb, true);
114
111
    }
116
113
    /** In-buffer processing - the buffer will be modified
117
114
     */
118
115
    public void convert( CharChunk mb, boolean query )
119
 
        throws IOException
 
116
        throws IOException
120
117
    {
121
 
        //      log( "Converting a char chunk ");
122
 
        int start=mb.getOffset();
123
 
        char buff[]=mb.getBuffer();
124
 
        int cend=mb.getEnd();
 
118
        //        log( "Converting a char chunk ");
 
119
        int start=mb.getOffset();
 
120
        char buff[]=mb.getBuffer();
 
121
        int cend=mb.getEnd();
125
122
 
126
 
        int idx= CharChunk.indexOf( buff, start, cend, '%' );
 
123
        int idx= CharChunk.indexOf( buff, start, cend, '%' );
127
124
        int idx2=-1;
128
125
        if( query )
129
126
            idx2= CharChunk.indexOf( buff, start, cend, '+' );
130
 
        if( idx<0 && idx2<0 ) {
131
 
            return;
132
 
        }
133
 
        
134
 
        if( idx2 >= 0 && idx2 < idx ) idx=idx2; 
135
 
        if( idx < 0 ) idx=idx2;
 
127
        if( idx<0 && idx2<0 ) {
 
128
            return;
 
129
        }
 
130
        
 
131
        if( idx2 >= 0 && idx2 < idx ) idx=idx2; 
 
132
        if( idx < 0 ) idx=idx2;
136
133
 
137
 
        for( int j=idx; j<cend; j++, idx++ ) {
138
 
            if( buff[ j ] == '+' && query ) {
139
 
                buff[idx]=( ' ' );
140
 
            } else if( buff[ j ] != '%' ) {
141
 
                buff[idx]=buff[j];
142
 
            } else {
143
 
                // read next 2 digits
144
 
                if( j+2 >= cend ) {
145
 
                    // invalid
146
 
                    throw new CharConversionException("EOF");
147
 
                }
148
 
                char b1= buff[j+1];
149
 
                char b2=buff[j+2];
150
 
                if( !isHexDigit( b1 ) || ! isHexDigit(b2 ))
151
 
                    throw new CharConversionException("isHexDigit");
152
 
                
153
 
                j+=2;
154
 
                int res=x2c( b1, b2 );
155
 
                buff[idx]=(char)res;
156
 
            }
157
 
        }
158
 
        mb.setEnd( idx );
 
134
        for( int j=idx; j<cend; j++, idx++ ) {
 
135
            if( buff[ j ] == '+' && query ) {
 
136
                buff[idx]=( ' ' );
 
137
            } else if( buff[ j ] != '%' ) {
 
138
                buff[idx]=buff[j];
 
139
            } else {
 
140
                // read next 2 digits
 
141
                if( j+2 >= cend ) {
 
142
                    // invalid
 
143
                    throw new CharConversionException("EOF");
 
144
                }
 
145
                char b1= buff[j+1];
 
146
                char b2=buff[j+2];
 
147
                if( !isHexDigit( b1 ) || ! isHexDigit(b2 ))
 
148
                    throw new CharConversionException("isHexDigit");
 
149
                
 
150
                j+=2;
 
151
                int res=x2c( b1, b2 );
 
152
                buff[idx]=(char)res;
 
153
            }
 
154
        }
 
155
        mb.setEnd( idx );
159
156
    }
160
157
 
161
158
    /** URLDecode, will modify the source
162
159
     *  Includes converting  '+' to ' '.
163
160
     */
164
161
    public void convert(MessageBytes mb)
165
 
        throws IOException
 
162
        throws IOException
166
163
    {
167
164
        convert(mb, true);
168
165
    }
170
167
    /** URLDecode, will modify the source
171
168
     */
172
169
    public void convert(MessageBytes mb, boolean query)
173
 
        throws IOException
 
170
        throws IOException
174
171
    {
175
 
        
176
 
        switch (mb.getType()) {
177
 
        case MessageBytes.T_STR:
178
 
            String strValue=mb.toString();
179
 
            if( strValue==null ) return;
180
 
            mb.setString( convert( strValue, query ));
181
 
            break;
182
 
        case MessageBytes.T_CHARS:
183
 
            CharChunk charC=mb.getCharChunk();
184
 
            convert( charC, query );
185
 
            break;
186
 
        case MessageBytes.T_BYTES:
187
 
            ByteChunk bytesC=mb.getByteChunk();
188
 
            convert( bytesC, query );
189
 
            break;
190
 
        }
 
172
        
 
173
        switch (mb.getType()) {
 
174
        case MessageBytes.T_STR:
 
175
            String strValue=mb.toString();
 
176
            if( strValue==null ) return;
 
177
            mb.setString( convert( strValue, query ));
 
178
            break;
 
179
        case MessageBytes.T_CHARS:
 
180
            CharChunk charC=mb.getCharChunk();
 
181
            convert( charC, query );
 
182
            break;
 
183
        case MessageBytes.T_BYTES:
 
184
            ByteChunk bytesC=mb.getByteChunk();
 
185
            convert( bytesC, query );
 
186
            break;
 
187
        }
191
188
    }
192
189
 
193
190
    // XXX Old code, needs to be replaced !!!!
200
197
    public final String convert(String str, boolean query)
201
198
    {
202
199
        if (str == null)  return  null;
203
 
        
204
 
        if( (!query || str.indexOf( '+' ) < 0) && str.indexOf( '%' ) < 0 )
205
 
            return str;
206
 
        
 
200
        
 
201
        if( (!query || str.indexOf( '+' ) < 0) && str.indexOf( '%' ) < 0 )
 
202
            return str;
 
203
        
207
204
        StringBuffer dec = new StringBuffer();    // decoded string output
208
205
        int strPos = 0;
209
206
        int strLen = str.length();
238
235
                strPos++;
239
236
                continue;
240
237
            } else if (metaChar == '%') {
241
 
                // We throw the original exception - the super will deal with
242
 
                // it
243
 
                //                try {
244
 
                dec.append((char)Integer.
245
 
                           parseInt(str.substring(strPos + 1, strPos + 3),16));
 
238
                // We throw the original exception - the super will deal with
 
239
                // it
 
240
                //                try {
 
241
                dec.append((char)Integer.
 
242
                           parseInt(str.substring(strPos + 1, strPos + 3),16));
246
243
                strPos += 3;
247
244
            }
248
245
        }
253
250
 
254
251
 
255
252
    private static boolean isHexDigit( int c ) {
256
 
        return ( ( c>='0' && c<='9' ) ||
257
 
                 ( c>='a' && c<='f' ) ||
258
 
                 ( c>='A' && c<='F' ));
 
253
        return ( ( c>='0' && c<='9' ) ||
 
254
                 ( c>='a' && c<='f' ) ||
 
255
                 ( c>='A' && c<='F' ));
259
256
    }
260
257
    
261
258
    private static int x2c( byte b1, byte b2 ) {
262
 
        int digit= (b1>='A') ? ( (b1 & 0xDF)-'A') + 10 :
263
 
            (b1 -'0');
264
 
        digit*=16;
265
 
        digit +=(b2>='A') ? ( (b2 & 0xDF)-'A') + 10 :
266
 
            (b2 -'0');
267
 
        return digit;
 
259
        int digit= (b1>='A') ? ( (b1 & 0xDF)-'A') + 10 :
 
260
            (b1 -'0');
 
261
        digit*=16;
 
262
        digit +=(b2>='A') ? ( (b2 & 0xDF)-'A') + 10 :
 
263
            (b2 -'0');
 
264
        return digit;
268
265
    }
269
266
 
270
267
    private static int x2c( char b1, char b2 ) {
271
 
        int digit= (b1>='A') ? ( (b1 & 0xDF)-'A') + 10 :
272
 
            (b1 -'0');
273
 
        digit*=16;
274
 
        digit +=(b2>='A') ? ( (b2 & 0xDF)-'A') + 10 :
275
 
            (b2 -'0');
276
 
        return digit;
277
 
    }
278
 
 
279
 
    private final static int debug=0;
280
 
    private static void log( String s ) {
281
 
        if (log.isDebugEnabled())
282
 
            log.debug("URLDecoder: " + s );
 
268
        int digit= (b1>='A') ? ( (b1 & 0xDF)-'A') + 10 :
 
269
            (b1 -'0');
 
270
        digit*=16;
 
271
        digit +=(b2>='A') ? ( (b2 & 0xDF)-'A') + 10 :
 
272
            (b2 -'0');
 
273
        return digit;
283
274
    }
284
275
 
285
276
}