summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstbuehler <stbuehler@152afb58-edef-0310-8abb-c4023f1b3aa9>2009-10-16 16:43:52 +0000
committerstbuehler <stbuehler@152afb58-edef-0310-8abb-c4023f1b3aa9>2009-10-16 16:43:52 +0000
commitd9b134f6d1f967e70cfc99827d20defc6cc7876c (patch)
tree4b558c1f3faa2c443f4fb0f64d5a94ab006f7a54
parentd2a5467fa478f950e99aa67e94db418f956371d5 (diff)
downloadlighttpd-d9b134f6d1f967e70cfc99827d20defc6cc7876c.tar.gz
mod_accesslog: escape special characters (fixes #1551, thx icy)
git-svn-id: svn://svn.lighttpd.net/lighttpd/trunk@2661 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r--NEWS1
-rw-r--r--src/mod_accesslog.c57
2 files changed, 52 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 3b5aea94..75a0fad0 100644
--- a/NEWS
+++ b/NEWS
@@ -145,6 +145,7 @@ NEWS
* Use linux-epoll by default if available (fixes #2021)
* Add TLS servername indication (SNI) support (fixes #386, thx Peter Colberg <peter@colberg.org>)
* Add SSL Client Certificate verification (#1288)
+ * mod_accesslog: escape special characters (fixes #1551, thx icy)
- 1.5.0-r19.. -
* -F option added for spawn-fcgi
diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
index d5a94bd5..276981cb 100644
--- a/src/mod_accesslog.c
+++ b/src/mod_accesslog.c
@@ -163,6 +163,51 @@ INIT_FUNC(mod_accesslog_init) {
return p;
}
+static void accesslog_append_escaped(buffer *dest, buffer *str) {
+ /* replaces non-printable chars with \xHH where HH is the hex representation of the byte */
+ /* exceptions: " => \", \ => \\, whitespace chars => \n \t etc. */
+ buffer_prepare_append(dest, str->used - 1);
+
+ for (unsigned int i = 0; i < str->used - 1; i++) {
+ if (str->ptr[i] >= ' ' && str->ptr[i] <= '~') {
+ /* printable chars */
+ buffer_append_string_len(dest, &str->ptr[i], 1);
+ } else switch (str->ptr[i]) {
+ case '"':
+ BUFFER_APPEND_STRING_CONST(dest, "\\\"");
+ break;
+ case '\\':
+ BUFFER_APPEND_STRING_CONST(dest, "\\\\");
+ break;
+ case '\b':
+ BUFFER_APPEND_STRING_CONST(dest, "\\b");
+ break;
+ case '\n':
+ BUFFER_APPEND_STRING_CONST(dest, "\\n");
+ break;
+ case '\r':
+ BUFFER_APPEND_STRING_CONST(dest, "\\r");
+ break;
+ case '\t':
+ BUFFER_APPEND_STRING_CONST(dest, "\\t");
+ break;
+ case '\v':
+ BUFFER_APPEND_STRING_CONST(dest, "\\v");
+ break;
+ default: {
+ /* non printable char => \xHH */
+ char hh[5] = {'\\','x',0,0,0};
+ char h = str->ptr[i] / 16;
+ hh[2] = (h > 9) ? (h - 10 + 'A') : (h + '0');
+ h = str->ptr[i] % 16;
+ hh[3] = (h > 9) ? (h - 10 + 'A') : (h + '0');
+ buffer_append_string_len(dest, &hh[0], 4);
+ }
+ break;
+ }
+ }
+}
+
static int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
size_t i, j, k = 0, start = 0;
@@ -710,7 +755,7 @@ REQUESTDONE_FUNC(log_access_write) {
case FORMAT_REQUEST_LINE:
buffer_append_string(b, get_http_method_name(con->request.http_method));
buffer_append_string_len(b, CONST_STR_LEN(" "));
- buffer_append_string_buffer(b, con->request.orig_uri);
+ accesslog_append_escaped(b, con->request.orig_uri);
buffer_append_string_len(b, CONST_STR_LEN(" "));
buffer_append_string(b, get_http_version_name(con->request.http_version));
@@ -729,14 +774,14 @@ REQUESTDONE_FUNC(log_access_write) {
break;
case FORMAT_HEADER:
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, CONST_BUF_LEN(p->conf.parsed_format->ptr[j]->string)))) {
- buffer_append_string_buffer(b, ds->value);
+ accesslog_append_escaped(b, ds->value);
} else {
buffer_append_string_len(b, CONST_STR_LEN("-"));
}
break;
case FORMAT_RESPONSE_HEADER:
if (NULL != (ds = (data_string *)array_get_element(con->response.headers, CONST_BUF_LEN(p->conf.parsed_format->ptr[j]->string)))) {
- buffer_append_string_buffer(b, ds->value);
+ accesslog_append_escaped(b, ds->value);
} else {
buffer_append_string_len(b, CONST_STR_LEN("-"));
}
@@ -774,7 +819,7 @@ REQUESTDONE_FUNC(log_access_write) {
break;
case FORMAT_HTTP_HOST:
if (con->uri.authority->used > 1) {
- buffer_append_string_buffer(b, con->uri.authority);
+ accesslog_append_escaped(b, con->uri.authority);
} else {
buffer_append_string_len(b, CONST_STR_LEN("-"));
}
@@ -790,10 +835,10 @@ REQUESTDONE_FUNC(log_access_write) {
buffer_append_long(b, srv->srvconf.port);
break;
case FORMAT_QUERY_STRING:
- buffer_append_string_buffer(b, con->uri.query);
+ accesslog_append_escaped(b, con->uri.query);
break;
case FORMAT_URL:
- buffer_append_string_buffer(b, con->uri.path_raw);
+ accesslog_append_escaped(b, con->uri.path_raw);
break;
case FORMAT_CONNECTION_STATUS:
switch(con->keep_alive) {