bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / tomcat-connectors-1.2.32-src / native / common / jk_url.c
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17
18 /***************************************************************************
19  * Description: URL manipulation subroutines. (ported from mod_proxy).     *
20  * Version:     $Revision: 531816 $                                        *
21  ***************************************************************************/
22
23 #include "jk_global.h"
24 #include "jk_url.h"
25
26 #ifdef HAVE_APR
27 #define JK_ISXDIGIT(x) apr_isxdigit((x))
28 #define JK_ISDIGIT(x)  apr_isdigit((x))
29 #define JK_ISUPPER(x)  apr_isupper((x))
30 #define JK_ISALNUM(x)  apr_isalnum((x))
31 #else
32 #define JK_ISXDIGIT(x) isxdigit((int)(unsigned char)((x)))
33 #define JK_ISDIGIT(x)  isdigit((int)(unsigned char)((x)))
34 #define JK_ISUPPER(x)  isupper((int)(unsigned char)((x)))
35 #define JK_ISALNUM(x)  isalnum((int)(unsigned char)((x)))
36 #endif
37
38 static void jk_c2hex(int ch, char *x)
39 {
40 #if !CHARSET_EBCDIC
41     int i;
42
43     x[0] = '%';
44     i = (ch & 0xF0) >> 4;
45     if (i >= 10) {
46         x[1] = ('A' - 10) + i;
47     }
48     else {
49         x[1] = '0' + i;
50     }
51
52     i = ch & 0x0F;
53     if (i >= 10) {
54         x[2] = ('A' - 10) + i;
55     }
56     else {
57         x[2] = '0' + i;
58     }
59 #else /*CHARSET_EBCDIC*/
60     static const char ntoa[] = { "0123456789ABCDEF" };
61     char buf[1];
62
63     ch &= 0xFF;
64
65     buf[0] = ch;
66     jk_xlate_to_ascii(buf, 1);
67
68     x[0] = '%';
69     x[1] = ntoa[(buf[0] >> 4) & 0x0F];
70     x[2] = ntoa[buf[0] & 0x0F];
71     x[3] = '\0';
72 #endif /*CHARSET_EBCDIC*/
73 }
74
75 /*
76  * Convert a URL-encoded string to canonical form.
77  * It encodes those which must be encoded, and does not touch
78  * those which must not be touched.
79  * String x must be '\0'-terminated.
80  * String y must be pre-allocated with len maxlen
81  * (including the terminating '\0').
82  */
83 int jk_canonenc(const char *x, char *y, int maxlen)
84 {
85     int i, j;
86     int ch = x[0];
87     char *allowed;  /* characters which should not be encoded */
88     char *reserved; /* characters which much not be en/de-coded */
89
90 /*
91  * N.B. in addition to :@&=, this allows ';' in an http path
92  * and '?' in an ftp path -- this may be revised
93  */
94     allowed = "~$-_.+!*'(),;:@&=";
95     reserved = "/";
96
97     for (i = 0, j = 0; ch != '\0' && j < maxlen; i++, j++, ch=x[i]) {
98 /* always handle '/' first */
99         if (strchr(reserved, ch)) {
100             y[j] = ch;
101             continue;
102         }
103 /* recode it, if necessary */
104         if (!JK_ISALNUM(ch) && !strchr(allowed, ch)) {
105             if (j+2<maxlen) {
106                 jk_c2hex(ch, &y[j]);
107                 j += 2;
108             }
109             else {
110                 return JK_FALSE;
111             }
112         }
113         else {
114             y[j] = ch;
115         }
116     }
117     if (j<maxlen) {
118         y[j] = '\0';
119         return JK_TRUE;
120     }
121     else {
122         return JK_FALSE;
123     }
124 }