diff options
author | stbuehler <stbuehler@152afb58-edef-0310-8abb-c4023f1b3aa9> | 2009-10-16 16:43:52 +0000 |
---|---|---|
committer | stbuehler <stbuehler@152afb58-edef-0310-8abb-c4023f1b3aa9> | 2009-10-16 16:43:52 +0000 |
commit | d9b134f6d1f967e70cfc99827d20defc6cc7876c (patch) | |
tree | 4b558c1f3faa2c443f4fb0f64d5a94ab006f7a54 | |
parent | d2a5467fa478f950e99aa67e94db418f956371d5 (diff) | |
download | lighttpd-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-- | NEWS | 1 | ||||
-rw-r--r-- | src/mod_accesslog.c | 57 |
2 files changed, 52 insertions, 6 deletions
@@ -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) { |