simplified buffer-encoding functions into one function

- all of them do some kind of string-to-hex conversion
  (html, rel-uri, hex)
- add a rel-uri encoding next to the old rel-uri-part one
- fixes #266


git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-merge-1.4.x@822 152afb58-edef-0310-8abb-c4023f1b3aa9
This commit is contained in:
Jan Kneschke 2005-11-07 13:15:51 +00:00
parent 95132d93c8
commit 976f32182e
7 changed files with 170 additions and 153 deletions

View File

@ -251,7 +251,7 @@ int buffer_copy_memory(buffer *b, const char *s, size_t s_len) {
return buffer_append_memory(b, s, s_len);
}
int buffer_append_hex(buffer *b, unsigned long value) {
int buffer_append_long_hex(buffer *b, unsigned long value) {
char *buf;
int shift = 0;
unsigned long copy = value;
@ -281,7 +281,6 @@ int buffer_append_hex(buffer *b, unsigned long value) {
return 0;
}
int ltostr(char *buf, long val) {
char swap;
char *end;
@ -620,31 +619,99 @@ int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
return 0;
}
const char encoded_chars_rel_uri_part[] = {
/*
0 1 2 3 4 5 6 7 8 9 A B C D E F
*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, /* 20 - 2F space " # $ % & ' + , / */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 5F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 70 - 7F DEL */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
};
int buffer_append_string_hex(buffer *b, const char *in, size_t in_len) {
size_t i;
/* BO protection */
if (in_len * 2 < in_len) return -1;
if (b->used > 0 && b->ptr[b->used - 1] == '\0') {
b->used--;
}
buffer_prepare_append(b, in_len * 2 + 1);
for (i = 0; i < in_len; i++) {
b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
}
b->ptr[b->used++] = '\0';
return 0;
}
const char encoded_chars_rel_uri[] = {
/*
0 1 2 3 4 5 6 7 8 9 A B C D E F
*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, /* 20 - 2F space " # $ % & ' + , / */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 5F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 70 - 7F DEL */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
};
int buffer_append_string_url_encoded(buffer *b, const char *s, size_t s_len) {
const char encoded_chars_html[] = {
/*
0 1 2 3 4 5 6 7 8 9 A B C D E F
*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 5F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 70 - 7F DEL */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
};
const char encoded_chars_hex[] = {
/*
0 1 2 3 4 5 6 7 8 9 A B C D E F
*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70 - 7F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
};
int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding) {
unsigned char *ds, *d;
size_t d_len;
const char *map = NULL;
if (!s || !b) return -1;
@ -653,148 +720,89 @@ int buffer_append_string_url_encoded(buffer *b, const char *s, size_t s_len) {
}
if (s_len == 0) return 0;
switch(encoding) {
case ENCODING_REL_URI:
map = encoded_chars_rel_uri;
break;
case ENCODING_REL_URI_PART:
map = encoded_chars_rel_uri_part;
break;
case ENCODING_HTML:
map = encoded_chars_html;
break;
case ENCODING_HEX:
map = encoded_chars_hex;
break;
case ENCODING_UNSET:
break;
}
assert(map != NULL);
/* count to-be-encoded-characters */
for (ds = (unsigned char *)s, d_len = 0; *ds; ds++) {
if (*ds < 32 || *ds > 126) {
d_len += 3;
} else {
switch (*ds) {
case '$':
case '&':
case '+':
case ',':
case '/':
case ':':
case ';':
case '=':
case '?':
case '@':
case ' ':
case '#':
case '%':
case '<':
case '>':
case '"':
case '\'':
if (map[*ds]) {
switch(encoding) {
case ENCODING_REL_URI:
case ENCODING_REL_URI_PART:
d_len += 3;
break;
default:
d_len ++;
case ENCODING_HTML:
d_len += 6;
break;
case ENCODING_HEX:
d_len += 2;
break;
case ENCODING_UNSET:
break;
}
} else {
d_len ++;
}
}
buffer_prepare_append(b, d_len);
for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0; *ds; ds++) {
if (*ds < 32 || *ds > 126) {
d[d_len++] = '%';
d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F];
d[d_len++] = hex_chars[(*ds) & 0x0F];
} else {
switch (*ds) {
case '$':
case '&':
case '+':
case ',':
case '/':
case ':':
case ';':
case '=':
case '?':
case '@':
case ' ':
case '#':
case '%':
case '<':
case '>':
case '"':
case '\'':
if (map[*ds]) {
switch(encoding) {
case ENCODING_REL_URI:
case ENCODING_REL_URI_PART:
d[d_len++] = '%';
d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F];
d[d_len++] = hex_chars[(*ds) & 0x0F];
break;
default:
d[d_len++] = *ds;
case ENCODING_HTML:
d[d_len++] = '&';
d[d_len++] = '#';
d[d_len++] = 'x';
d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F];
d[d_len++] = hex_chars[(*ds) & 0x0F];
d[d_len++] = ';';
break;
case ENCODING_HEX:
d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F];
d[d_len++] = hex_chars[(*ds) & 0x0F];
break;
case ENCODING_UNSET:
break;
}
}
}
b->ptr[b->used + d_len - 1] = '\0';
b->used += d_len;
return 0;
}
int buffer_append_string_html_encoded(buffer *b, const char *s, size_t s_len) {
unsigned char *ds, *d;
size_t d_len, i;
if (!s || !b) return -1;
if (b->ptr[b->used - 1] != '\0') {
SEGFAULT();
}
/* nothing to append */
if (s_len == 0) return 0;
/* count to-be-encoded-characters */
for (ds = (unsigned char *)s, d_len = 0, i = 0; i < s_len && *ds; ds++, i++) {
d_len++;
if (*ds == '<' || *ds == '>') {
d_len += 4 - 1;
} else if (*ds == '&') {
d_len += 5 - 1;
}
}
buffer_prepare_append(b, d_len);
for (ds = (unsigned char *)s,
d = (unsigned char *)b->ptr + b->used - 1,
d_len = 0,
i = 0; i < s_len && *ds; ds++, i++) {
switch (*ds) {
case '>':
d[d_len++] = '&';
d[d_len++] = 'g';
d[d_len++] = 't';
d[d_len++] = ';';
break;
case '<':
d[d_len++] = '&';
d[d_len++] = 'l';
d[d_len++] = 't';
d[d_len++] = ';';
break;
case '&':
d[d_len++] = '&';
d[d_len++] = 'a';
d[d_len++] = 'm';
d[d_len++] = 'p';
d[d_len++] = ';';
break;
default:
} else {
d[d_len++] = *ds;
break;
}
}
/* terminate buffer and calculate new length */
b->ptr[b->used + d_len - 1] = '\0';
b->used += d_len;
return 0;
}
/* decodes url-special-chars inplace.
* replaces non-printable characters with '_'
*/

View File

@ -62,7 +62,7 @@ int buffer_append_string_buffer(buffer *b, const buffer *src);
int buffer_append_string_lfill(buffer *b, const char *s, size_t maxlen);
int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen);
int buffer_append_hex(buffer *b, unsigned long len);
int buffer_append_long_hex(buffer *b, unsigned long len);
int buffer_append_long(buffer *b, long val);
#if defined(SIZEOF_LONG) && (SIZEOF_LONG == SIZEOF_OFF_T)
@ -83,9 +83,15 @@ int buffer_is_equal_right_len(buffer *a, buffer *b, size_t len);
int buffer_is_equal_string(buffer *a, const char *s, size_t b_len);
int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len);
int buffer_append_string_hex(buffer *b, const char *in, size_t in_len);
int buffer_append_string_url_encoded(buffer *b, const char *s, size_t s_len);
int buffer_append_string_html_encoded(buffer *b, const char *s, size_t s_len);
typedef enum {
ENCODING_UNSET,
ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */
ENCODING_HTML, /* & becomes &amp; and so on */
ENCODING_HEX /* encode string as hex */
} buffer_encoding_t;
int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding);
int buffer_urldecode_path(buffer *url);
int buffer_urldecode_query(buffer *url);

View File

@ -210,7 +210,7 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const
case 'x': /* int (hex) */
d = va_arg(ap, int);
BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "0x");
buffer_append_hex(srv->errorlog_buf, d);
buffer_append_long_hex(srv->errorlog_buf, d);
BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
break;
case 'S': /* string */

View File

@ -414,7 +414,7 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
"<head>\n"
"<title>Index of "
);
buffer_append_string_html_encoded(out, CONST_BUF_LEN(con->uri.path));
buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_HTML);
BUFFER_APPEND_STRING_CONST(out, "</title>\n");
if (p->conf.external_css->used > 1) {
@ -462,7 +462,7 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
}
BUFFER_APPEND_STRING_CONST(out, "</head>\n<body>\n<h2>Index of ");
buffer_append_string_html_encoded(out, CONST_BUF_LEN(con->uri.path));
buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_HTML);
BUFFER_APPEND_STRING_CONST(out,
"</h2>\n"
"<div class=\"list\">\n"
@ -504,7 +504,7 @@ static void http_list_directory_footer(server *srv, connection *con, plugin_data
if (-1 != stream_open(&s, p->tmp_buf)) {
BUFFER_APPEND_STRING_CONST(out, "<pre class=\"readme\">");
buffer_append_string_html_encoded(out, s.start, s.size);
buffer_append_string_encoded(out, s.start, s.size, ENCODING_HTML);
BUFFER_APPEND_STRING_CONST(out, "</pre>");
}
stream_close(&s);
@ -689,9 +689,9 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
#endif
BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\"");
buffer_append_string_url_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen);
buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
BUFFER_APPEND_STRING_CONST(out, "/\">");
buffer_append_string_html_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen);
buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_HTML);
BUFFER_APPEND_STRING_CONST(out, "</a>/</td><td class=\"m\">");
buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
BUFFER_APPEND_STRING_CONST(out, "</td><td class=\"s\">- &nbsp;</td><td class=\"t\">Directory</td></tr>\n");
@ -745,9 +745,9 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
http_list_directory_sizefmt(sizebuf, tmp->size);
BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\"");
buffer_append_string_url_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen);
buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
BUFFER_APPEND_STRING_CONST(out, "\">");
buffer_append_string_html_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen);
buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_HTML);
BUFFER_APPEND_STRING_CONST(out, "</a></td><td class=\"m\">");
buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
BUFFER_APPEND_STRING_CONST(out, "</td><td class=\"s\">");

View File

@ -510,7 +510,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
buffer_append_string_html_encoded(b, CONST_BUF_LEN(c->uri.path));
buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
@ -539,7 +539,6 @@ static handler_t mod_status_handle_server_status_text(server *srv, connection *c
plugin_data *p = p_d;
buffer *b;
double avg;
size_t j;
time_t ts;
b = chunkqueue_get_append_buffer(con->write_queue);

View File

@ -235,7 +235,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
MD5_Final(h, &Md5Ctx);
buffer_append_string_hex(ds->value, (char *)h, 16);
buffer_append_string_encoded(ds->value, (char *)h, 16, ENCODING_HEX);
buffer_append_string(ds->value, "\"; Path=\"/\"");
buffer_append_string(ds->value, "; Version=\"1\"");

View File

@ -946,6 +946,8 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
c->offset += weHave;
cq->bytes_out += weHave;
break;
case UNUSED_CHUNK:
break;
}
chunkqueue_remove_finished_chunks(cq);
@ -1111,7 +1113,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
buffer_append_string_buffer(b, con->uri.scheme);
buffer_append_string(b,"://");
buffer_append_string_buffer(b, con->uri.authority);
buffer_append_string_buffer(b, con->uri.path);
buffer_append_string_encoded(b, CONST_BUF_LEN(con->uri.path), ENCODING_REL_URI);
buffer_append_string(b,"</D:href>\n");
if (!buffer_is_empty(prop_200)) {
@ -1176,7 +1178,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
buffer_append_string_buffer(b, con->uri.scheme);
buffer_append_string(b,"://");
buffer_append_string_buffer(b, con->uri.authority);
buffer_append_string_buffer(b, d.rel_path);
buffer_append_string_encoded(b, CONST_BUF_LEN(d.rel_path), ENCODING_REL_URI);
buffer_append_string(b,"</D:href>\n");
if (!buffer_is_empty(prop_200)) {
@ -1415,6 +1417,8 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
}
}
break;
case UNUSED_CHUNK:
break;
}
if (r > 0) {