version 1.205, 2021/08/31 09:51:25 |
version 1.206, 2021/11/06 14:27:45 |
|
|
static int retried; |
static int retried; |
|
|
/* |
/* |
* Determine whether the character needs encoding, per RFC1738: |
* Determine whether the character needs encoding, per RFC2396. |
* - No corresponding graphic US-ASCII. |
|
* - Unsafe characters. |
|
*/ |
*/ |
static int |
static int |
unsafe_char(const char *c0) |
to_encode(const char *c0) |
{ |
{ |
const char *unsafe_chars = " <>\"#{}|\\^~[]`"; |
/* 2.4.3. Excluded US-ASCII Characters */ |
|
const char *excluded_chars = |
|
" " /* space */ |
|
"<>#\"" /* delims (modulo "%", see below) */ |
|
"{}|\\^[]`" /* unwise */ |
|
; |
const unsigned char *c = (const unsigned char *)c0; |
const unsigned char *c = (const unsigned char *)c0; |
|
|
/* |
/* |
|
|
return (iscntrl(*c) || !isascii(*c) || |
return (iscntrl(*c) || !isascii(*c) || |
|
|
/* |
/* |
* Unsafe characters. |
* '%' is also reserved, if is not followed by two |
* '%' is also unsafe, if is not followed by two |
|
* hexadecimal digits. |
* hexadecimal digits. |
*/ |
*/ |
strchr(unsafe_chars, *c) != NULL || |
strchr(excluded_chars, *c) != NULL || |
(*c == '%' && (!isxdigit(c[1]) || !isxdigit(c[2])))); |
(*c == '%' && (!isxdigit(c[1]) || !isxdigit(c[2])))); |
} |
} |
|
|
/* |
/* |
* Encode given URL, per RFC1738. |
* Encode given URL, per RFC2396. |
* Allocate and return string to the caller. |
* Allocate and return string to the caller. |
*/ |
*/ |
static char * |
static char * |
|
|
|
|
/* |
/* |
* First pass: |
* First pass: |
* Count unsafe characters, and determine length of the |
* Count characters to encode and determine length of the final URL. |
* final URL. |
|
*/ |
*/ |
for (i = 0; i < length; i++) |
for (i = 0; i < length; i++) |
if (unsafe_char(path + i)) |
if (to_encode(path + i)) |
new_length += 2; |
new_length += 2; |
|
|
epath = epathp = malloc(new_length + 1); /* One more for '\0'. */ |
epath = epathp = malloc(new_length + 1); /* One more for '\0'. */ |
|
|
* Encode, and copy final URL. |
* Encode, and copy final URL. |
*/ |
*/ |
for (i = 0; i < length; i++) |
for (i = 0; i < length; i++) |
if (unsafe_char(path + i)) { |
if (to_encode(path + i)) { |
snprintf(epathp, 4, "%%" "%02x", |
snprintf(epathp, 4, "%%" "%02x", |
(unsigned char)path[i]); |
(unsigned char)path[i]); |
epathp += 3; |
epathp += 3; |