]>
Commit | Line | Data |
---|---|---|
30a4f2a8 | 1 | /* |
262a0e14 | 2 | * $Id$ |
30a4f2a8 | 3 | * |
26ac0430 | 4 | * DEBUG: |
30a4f2a8 | 5 | * AUTHOR: Harvest Derived |
6 | * | |
2b6662ba | 7 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
e25c139f | 8 | * ---------------------------------------------------------- |
30a4f2a8 | 9 | * |
2b6662ba | 10 | * Squid is the result of efforts by numerous individuals from |
11 | * the Internet community; see the CONTRIBUTORS file for full | |
12 | * details. Many organizations have provided support for Squid's | |
13 | * development; see the SPONSORS file for full details. Squid is | |
14 | * Copyrighted (C) 2001 by the Regents of the University of | |
15 | * California; see the COPYRIGHT file for full details. Squid | |
16 | * incorporates software developed and/or copyrighted by other | |
17 | * sources; see the CREDITS file for full details. | |
30a4f2a8 | 18 | * |
19 | * This program is free software; you can redistribute it and/or modify | |
20 | * it under the terms of the GNU General Public License as published by | |
21 | * the Free Software Foundation; either version 2 of the License, or | |
22 | * (at your option) any later version. | |
26ac0430 | 23 | * |
30a4f2a8 | 24 | * This program is distributed in the hope that it will be useful, |
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27 | * GNU General Public License for more details. | |
26ac0430 | 28 | * |
30a4f2a8 | 29 | * You should have received a copy of the GNU General Public License |
30 | * along with this program; if not, write to the Free Software | |
cbdec147 | 31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
e25c139f | 32 | * |
30a4f2a8 | 33 | */ |
34 | ||
35 | #include "config.h" | |
1fa9b1a7 | 36 | #include "rfc1738.h" |
25f98340 | 37 | //#include "util.h" |
0d94e9fe | 38 | |
30a4f2a8 | 39 | #if HAVE_STDIO_H |
090089c4 | 40 | #include <stdio.h> |
30a4f2a8 | 41 | #endif |
42 | #if HAVE_STRING_H | |
090089c4 | 43 | #include <string.h> |
30a4f2a8 | 44 | #endif |
45 | ||
26ac0430 | 46 | /* |
090089c4 | 47 | * RFC 1738 defines that these characters should be escaped, as well |
48 | * any non-US-ASCII character or anything between 0x00 - 0x1F. | |
49 | */ | |
26ac0430 | 50 | static char rfc1738_unsafe_chars[] = { |
090089c4 | 51 | (char) 0x3C, /* < */ |
52 | (char) 0x3E, /* > */ | |
53 | (char) 0x22, /* " */ | |
54 | (char) 0x23, /* # */ | |
9bc73deb | 55 | #if 0 /* done in code */ |
090089c4 | 56 | (char) 0x25, /* % */ |
9bc73deb | 57 | #endif |
090089c4 | 58 | (char) 0x7B, /* { */ |
59 | (char) 0x7D, /* } */ | |
60 | (char) 0x7C, /* | */ | |
61 | (char) 0x5C, /* \ */ | |
62 | (char) 0x5E, /* ^ */ | |
63 | (char) 0x7E, /* ~ */ | |
64 | (char) 0x5B, /* [ */ | |
65 | (char) 0x5D, /* ] */ | |
66 | (char) 0x60, /* ` */ | |
67 | (char) 0x27, /* ' */ | |
68 | (char) 0x20 /* space */ | |
69 | }; | |
70 | ||
26ac0430 | 71 | static char rfc1738_reserved_chars[] = { |
9bc73deb | 72 | (char) 0x3b, /* ; */ |
73 | (char) 0x2f, /* / */ | |
74 | (char) 0x3f, /* ? */ | |
75 | (char) 0x3a, /* : */ | |
76 | (char) 0x40, /* @ */ | |
77 | (char) 0x3d, /* = */ | |
78 | (char) 0x26 /* & */ | |
79 | }; | |
80 | ||
090089c4 | 81 | /* |
26ac0430 | 82 | * rfc1738_escape - Returns a static buffer contains the RFC 1738 |
090089c4 | 83 | * compliant, escaped version of the given url. |
84 | */ | |
1fa9b1a7 AJ |
85 | char * |
86 | rfc1738_do_escape(const char *url, int flags) | |
090089c4 | 87 | { |
3fdadc70 | 88 | static char *buf; |
89 | static size_t bufsize = 0; | |
0ee4272b | 90 | const char *p; |
91 | char *q; | |
2d72d4fd | 92 | unsigned int i, do_escape; |
090089c4 | 93 | |
3fdadc70 | 94 | if (buf == NULL || strlen(url) * 3 > bufsize) { |
26ac0430 AJ |
95 | xfree(buf); |
96 | bufsize = strlen(url) * 3 + 1; | |
1fa9b1a7 | 97 | buf = (char*)xcalloc(bufsize, 1); |
3fdadc70 | 98 | } |
6512a760 | 99 | for (p = url, q = buf; *p != '\0' && q < (buf + bufsize - 1); p++, q++) { |
26ac0430 | 100 | do_escape = 0; |
090089c4 | 101 | |
26ac0430 AJ |
102 | /* RFC 1738 defines these chars as unsafe */ |
103 | for (i = 0; i < sizeof(rfc1738_unsafe_chars); i++) { | |
104 | if (*p == rfc1738_unsafe_chars[i]) { | |
105 | do_escape = 1; | |
106 | break; | |
107 | } | |
108 | } | |
109 | /* Handle % separately */ | |
1fa9b1a7 | 110 | if (flags != RFC1738_ESCAPE_UNESCAPED && *p == '%') |
26ac0430 AJ |
111 | do_escape = 1; |
112 | /* RFC 1738 defines these chars as reserved */ | |
1fa9b1a7 | 113 | for (i = 0; i < sizeof(rfc1738_reserved_chars) && flags == RFC1738_ESCAPE_RESERVED; i++) { |
26ac0430 AJ |
114 | if (*p == rfc1738_reserved_chars[i]) { |
115 | do_escape = 1; | |
116 | break; | |
117 | } | |
118 | } | |
119 | /* RFC 1738 says any control chars (0x00-0x1F) are encoded */ | |
120 | if ((unsigned char) *p <= (unsigned char) 0x1F) { | |
121 | do_escape = 1; | |
122 | } | |
123 | /* RFC 1738 says 0x7f is encoded */ | |
124 | if (*p == (char) 0x7F) { | |
125 | do_escape = 1; | |
126 | } | |
127 | /* RFC 1738 says any non-US-ASCII are encoded */ | |
128 | if (((unsigned char) *p >= (unsigned char) 0x80)) { | |
129 | do_escape = 1; | |
130 | } | |
131 | /* Do the triplet encoding, or just copy the char */ | |
132 | /* note: we do not need snprintf here as q is appropriately | |
133 | * allocated - KA */ | |
93fc29fe | 134 | |
26ac0430 | 135 | if (do_escape == 1) { |
cc630482 | 136 | (void) snprintf(q, (bufsize-(p-buf)), "%%%02X", (unsigned char) *p); |
26ac0430 AJ |
137 | q += sizeof(char) * 2; |
138 | } else { | |
139 | *q = *p; | |
140 | } | |
090089c4 | 141 | } |
142 | *q = '\0'; | |
143 | return (buf); | |
144 | } | |
145 | ||
146 | /* | |
e4d5e365 | 147 | * Converts a ascii hex code into a binary character. |
090089c4 | 148 | */ |
c6f72b94 | 149 | static int |
e0d6837c HN |
150 | fromhex(char ch) |
151 | { | |
152 | if (ch >= '0' && ch <= '9') | |
153 | return ch - '0'; | |
154 | if (ch >= 'a' && ch <= 'f') | |
155 | return ch - 'a' + 10; | |
156 | if (ch >= 'A' && ch <= 'F') | |
157 | return ch - 'A' + 10; | |
158 | return -1; | |
159 | } | |
160 | ||
e4d5e365 AJ |
161 | /* |
162 | * rfc1738_unescape() - Converts escaped characters (%xy numbers) in | |
163 | * given the string. %% is a %. %ab is the 8-bit hexadecimal number "ab" | |
164 | */ | |
b8d8561b | 165 | void |
8d917594 | 166 | rfc1738_unescape(char *s) |
090089c4 | 167 | { |
090089c4 | 168 | int i, j; /* i is write, j is read */ |
090089c4 | 169 | for (i = j = 0; s[j]; i++, j++) { |
26ac0430 | 170 | s[i] = s[j]; |
e0d6837c HN |
171 | if (s[j] != '%') { |
172 | /* normal case, nothing more to do */ | |
173 | } else if (s[j + 1] == '%') { /* %% case */ | |
174 | j++; /* Skip % */ | |
175 | } else { | |
176 | /* decode */ | |
0a9e98f6 | 177 | int v1, v2, x; |
e0d6837c | 178 | v1 = fromhex(s[j + 1]); |
79c8a298 A |
179 | if (v1 < 0) |
180 | continue; /* non-hex or \0 */ | |
e0d6837c | 181 | v2 = fromhex(s[j + 2]); |
79c8a298 A |
182 | if (v2 < 0) |
183 | continue; /* non-hex or \0 */ | |
55b5914b HN |
184 | x = v1 << 4 | v2; |
185 | if (x > 0 && x <= 255) { | |
186 | s[i] = x; | |
187 | j += 2; | |
188 | } | |
26ac0430 | 189 | } |
090089c4 | 190 | } |
191 | s[i] = '\0'; | |
192 | } |