You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Tony Finch <do...@dotat.at> on 1999/02/04 20:14:34 UTC

[PATCH] mod_log_config: support for reliably parsable logs

This patch allows you to use C-style backslash escapes in
mod_log_config format strings. This allows the server administrator to
configure a log format (using \n between each datum to be logged) that
is reliably parsable even in the face of people sending garbage
requests to the server. There's also the option of using a tab
separated value format if you wish, but that isn't reliably parsable
because (e.g.) %r can contain tabs. It's easy to add more escapes.

Tony.
-- 
f.a.n.finch  dot@dotat.at  fanf@demon.net


Index: mod_log_config.c
===================================================================
RCS file: /a/cvsroot/src/www/apache_1-3_fanf/src/modules/standard/mod_log_config.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- mod_log_config.c	1999/01/25 16:03:41	1.5
+++ mod_log_config.c	1999/02/04 18:57:44	1.6
@@ -524,30 +524,61 @@
     return NULL;
 }
 
-static char *log_format_substring(pool *p, const char *start,
-                                  const char *end)
-{
-    char *res = ap_palloc(p, end - start + 1);
-
-    strncpy(res, start, end - start);
-    res[end - start] = '\0';
-    return res;
-}
-
 static char *parse_log_misc_string(pool *p, log_format_item *it,
                                    const char **sa)
 {
-    const char *s = *sa;
+    const char *s;
+    char *d;
 
     it->func = constant_item;
     it->conditions = NULL;
 
+    s = *sa;
     while (*s && *s != '%') {
-        ++s;
+	s++;
     }
-    it->arg = log_format_substring(p, *sa, s);
-    *sa = s;
+    /*
+     * This might allocate a few chars extra if there's a backslash
+     * escape in the format string.
+     */
+    it->arg = ap_palloc(p, s - *sa + 1);
 
+    d = it->arg;
+    s = *sa;
+    while (*s && *s != '%') {
+	if (*s != '\\') {
+	    *d++ = *s++;
+	}
+	else {
+	    s++;
+	    switch (*s) {
+	    case '\\':
+		*d++ = '\\';
+		s++;
+		break;
+	    case 'n':
+		*d++ = '\n';
+		s++;
+		break;
+	    case 't':	
+		*d++ = '\t';
+		s++;
+		break;
+	    default:
+		/* copy verbatim */
+		*d++ = '\\';
+		/*
+		 * Allow the loop to deal with this *s in the normal
+		 * fashion so that it handles end of string etc.
+		 * properly.
+		 */
+		break;
+	    }
+	}
+    }
+    *d = '\0';
+
+    *sa = s;
     return NULL;
 }