1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Document what is meant by "non-printable" in the context of escnonprint.

This commit is contained in:
hniksic 2005-05-05 06:47:20 -07:00
parent ce06e4297f
commit 1230b724ca
2 changed files with 50 additions and 21 deletions

View File

@ -1,3 +1,9 @@
2005-05-05 Hrvoje Niksic <hniksic@xemacs.org>
* log.c (copy_and_escape): Replace the FOR_URI argument with a
slightly more general mechanism for specifying different kinds of
escape.
2005-05-05 Hrvoje Niksic <hniksic@xemacs.org> 2005-05-05 Hrvoje Niksic <hniksic@xemacs.org>
* ftp-basic.c (ftp_response): Fix printing FTP server response. * ftp-basic.c (ftp_response): Fix printing FTP server response.

View File

@ -635,46 +635,65 @@ count_nonprint (const char *source)
return cnt; return cnt;
} }
/* Copy SOURCE to DEST, escaping non-printable characters. If FOR_URI /* Copy SOURCE to DEST, escaping non-printable characters.
is 0, they are escaped as \ooo; otherwise, they are escaped as
%xx. Non-printable refers to anything outside the non-control ASCII
range (32-126) which means that, for example, CR, LF, and TAB are
considered non-printable along with ESC and other control chars.
This is by design: it makes sure that messages from remote servers
cannot be used to deceive the users by mimicking Wget's output.
Disallowing non-ASCII characters is another necessary security
measure, which makes sure that remote servers cannot garble the
screen or guess the local charset and perform homographic attacks.
Of course, the above means that escnonprint must only be used in
decidedly ASCII-only context, such as when printing host names,
responses from HTTP headers, messages coming from FTP servers, and
the like.
ESCAPE is the character used to introduce the escape sequence.
BASE should be the base of the escape sequence, and must be either
8 for octal or 16 for hex.
DEST must point to a location with sufficient room to store an DEST must point to a location with sufficient room to store an
encoded version of SOURCE. */ encoded version of SOURCE. */
static void static void
copy_and_escape (const char *source, char *dest, int for_uri) copy_and_escape (const char *source, char *dest, char escape, int base)
{ {
const char *from; const char *from;
char *to; char *to;
/* Copy the string, escaping non-printable chars. */ /* Copy the string from SOURCE to DEST, escaping non-printable chars. */
if (!for_uri) switch (base)
{ {
case 8:
for (from = source, to = dest; *from; from++) for (from = source, to = dest; *from; from++)
if (ISPRINT (*from)) if (ISPRINT (*from))
*to++ = *from; *to++ = *from;
else else
{ {
const unsigned char c = *from; const unsigned char c = *from;
*to++ = '\\'; *to++ = escape;
*to++ = '0' + (c >> 6); *to++ = '0' + (c >> 6);
*to++ = '0' + ((c >> 3) & 7); *to++ = '0' + ((c >> 3) & 7);
*to++ = '0' + (c & 7); *to++ = '0' + (c & 7);
} }
} break;
else case 16:
{
for (from = source, to = dest; *from; from++) for (from = source, to = dest; *from; from++)
if (ISPRINT (*from)) if (ISPRINT (*from))
*to++ = *from; *to++ = *from;
else else
{ {
const unsigned char c = *from; const unsigned char c = *from;
*to++ = '%'; *to++ = escape;
*to++ = XNUM_TO_DIGIT (c >> 4); *to++ = XNUM_TO_DIGIT (c >> 4);
*to++ = XNUM_TO_DIGIT (c & 0xf); *to++ = XNUM_TO_DIGIT (c & 0xf);
} }
break;
default:
abort ();
} }
*to = '\0'; *to = '\0';
} }
@ -687,10 +706,12 @@ struct ringel {
static struct ringel ring[RING_SIZE]; /* ring data */ static struct ringel ring[RING_SIZE]; /* ring data */
static const char * static const char *
escnonprint_internal (const char *str, int for_uri) escnonprint_internal (const char *str, char escape, int base)
{ {
static int ringpos; /* current ring position */ static int ringpos; /* current ring position */
assert (base == 8 || base == 16);
int nprcnt = count_nonprint (str); int nprcnt = count_nonprint (str);
if (nprcnt == 0) if (nprcnt == 0)
/* If there are no non-printable chars in STR, don't bother /* If there are no non-printable chars in STR, don't bother
@ -702,11 +723,11 @@ escnonprint_internal (const char *str, int for_uri)
simply r->X instead of ring[ringpos].X. */ simply r->X instead of ring[ringpos].X. */
struct ringel *r = ring + ringpos; struct ringel *r = ring + ringpos;
/* Every non-printable character is replaced with "\ooo", /* Every non-printable character is replaced with the escape char
i.e. with three *additional* chars (two in URI-mode). Size and three (or two, depending on BASE) *additional* chars. Size
must also include the length of the original string and an must also include the length of the original string and one
additional char for the terminating \0. */ additional char for the terminating \0. */
int needed_size = strlen (str) + 1 + (for_uri ? 2 * nprcnt : 3 * nprcnt); int needed_size = strlen (str) + 1 + (base == 8 ? 3 * nprcnt : 2 * nprcnt);
/* If the current buffer is uninitialized or too small, /* If the current buffer is uninitialized or too small,
(re)allocate it. */ (re)allocate it. */
@ -716,7 +737,7 @@ escnonprint_internal (const char *str, int for_uri)
r->size = needed_size; r->size = needed_size;
} }
copy_and_escape (str, r->buffer, for_uri); copy_and_escape (str, r->buffer, escape, base);
ringpos = (ringpos + 1) % RING_SIZE; ringpos = (ringpos + 1) % RING_SIZE;
return r->buffer; return r->buffer;
} }
@ -724,7 +745,8 @@ escnonprint_internal (const char *str, int for_uri)
/* Return a pointer to a static copy of STR with the non-printable /* Return a pointer to a static copy of STR with the non-printable
characters escaped as \ooo. If there are no non-printable characters escaped as \ooo. If there are no non-printable
characters in STR, STR is returned. characters in STR, STR is returned. See copy_and_escape for more
information on which characters are considered non-printable.
NOTE: since this function can return a pointer to static data, be NOTE: since this function can return a pointer to static data, be
careful to copy its result before calling it again. However, to be careful to copy its result before calling it again. However, to be
@ -736,12 +758,13 @@ escnonprint_internal (const char *str, int for_uri)
const char * const char *
escnonprint (const char *str) escnonprint (const char *str)
{ {
return escnonprint_internal (str, 0); return escnonprint_internal (str, '\\', 8);
} }
/* Return a pointer to a static copy of STR with the non-printable /* Return a pointer to a static copy of STR with the non-printable
characters escaped as %XX. If there are no non-printable characters escaped as %XX. If there are no non-printable
characters in STR, STR is returned. characters in STR, STR is returned. See copy_and_escape for more
information on which characters are considered non-printable.
This function returns a pointer to static data which will be This function returns a pointer to static data which will be
overwritten by subsequent calls -- see escnonprint for details. */ overwritten by subsequent calls -- see escnonprint for details. */
@ -749,7 +772,7 @@ escnonprint (const char *str)
const char * const char *
escnonprint_uri (const char *str) escnonprint_uri (const char *str)
{ {
return escnonprint_internal (str, 1); return escnonprint_internal (str, '%', 16);
} }
void void