]>
git.ipfire.org Git - thirdparty/squid.git/blob - lib/rfc1738.c
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
17 * RFC 1738 defines that these characters should be escaped, as well
18 * any non-US-ASCII character or anything between 0x00 - 0x1F.
20 static char rfc1738_unsafe_chars
[] = {
25 #if 0 /* done in code */
26 (char) 0x20, /* space */
41 static char rfc1738_reserved_chars
[] = {
52 * rfc1738_escape - Returns a static buffer contains the RFC 1738
53 * compliant, escaped version of the given url.
56 rfc1738_do_escape(const char *url
, int flags
)
59 static size_t bufsize
= 0;
62 unsigned int i
, do_escape
;
64 if (buf
== NULL
|| strlen(url
) * 3 > bufsize
) {
66 bufsize
= strlen(url
) * 3 + 1;
67 buf
= (char*)xcalloc(bufsize
, 1);
69 for (src
= url
, dst
= buf
; *src
!= '\0' && dst
< (buf
+ bufsize
- 1); src
++, dst
++) {
71 /* a-z, A-Z and 0-9 are SAFE. */
72 if ((*src
>= 'a' && *src
<= 'z') || (*src
>= 'A' && *src
<= 'Z') || (*src
>= '0' && *src
<= '9')) {
79 /* RFC 1738 defines these chars as unsafe */
80 if ((flags
& RFC1738_ESCAPE_UNSAFE
)) {
81 for (i
= 0; i
< sizeof(rfc1738_unsafe_chars
); i
++) {
82 if (*src
== rfc1738_unsafe_chars
[i
]) {
87 /* Handle % separately */
88 if (!(flags
& RFC1738_ESCAPE_NOPERCENT
) && *src
== '%')
90 /* Handle space separately */
91 else if (!(flags
& RFC1738_ESCAPE_NOSPACE
) && *src
<= ' ')
94 /* RFC 1738 defines these chars as reserved */
95 if ((flags
& RFC1738_ESCAPE_RESERVED
) && do_escape
== 0) {
96 for (i
= 0; i
< sizeof(rfc1738_reserved_chars
); i
++) {
97 if (*src
== rfc1738_reserved_chars
[i
]) {
103 if ((flags
& RFC1738_ESCAPE_CTRLS
) && do_escape
== 0) {
104 /* RFC 1738 says any control chars (0x00-0x1F) are encoded */
105 if ((unsigned char) *src
<= (unsigned char) 0x1F)
107 /* RFC 1738 says 0x7f is encoded */
108 else if (*src
== (char) 0x7F)
110 /* RFC 1738 says any non-US-ASCII are encoded */
111 else if (((unsigned char) *src
>= (unsigned char) 0x80))
114 /* Do the triplet encoding, or just copy the char */
115 if (do_escape
== 1) {
116 (void) snprintf(dst
, (bufsize
-(dst
-buf
)), "%%%02X", (unsigned char) *src
);
117 dst
+= sizeof(char) * 2;
127 * Converts a ascii hex code into a binary character.
132 if (ch
>= '0' && ch
<= '9')
134 if (ch
>= 'a' && ch
<= 'f')
135 return ch
- 'a' + 10;
136 if (ch
>= 'A' && ch
<= 'F')
137 return ch
- 'A' + 10;
142 * rfc1738_unescape() - Converts escaped characters (%xy numbers) in
143 * given the string. %% is a %. %ab is the 8-bit hexadecimal number "ab"
146 rfc1738_unescape(char *s
)
148 int i
, j
; /* i is write, j is read */
149 for (i
= j
= 0; s
[j
]; i
++, j
++) {
152 /* normal case, nothing more to do */
153 } else if (s
[j
+ 1] == '%') { /* %% case */
158 v1
= fromhex(s
[j
+ 1]);
160 continue; /* non-hex or \0 */
161 v2
= fromhex(s
[j
+ 2]);
163 continue; /* non-hex or \0 */
165 if (x
> 0 && x
<= 255) {