Attached you'll find a more or less straightforward port of 
ap_escape_logitem, introduced in 1.3.25.

Two questions:
- is this a minor mmn bump? (I'd say: yes, because new api)
- should we make it configurable (via LogFormat?), I'm not sure ...

TIA, nd

*mumbling something about outdated docs, I've just discovered this feature 
accidentally ;-)*
-- 
package Hacker::Perl::Another::Just;print
[EMAIL PROTECTED] split/::/ =>__PACKAGE__]}~;

#  André Malo  #  http://pub.perlig.de  #
diff -Nur httpd-2.1\include\httpd.h httpd-2.1.escape\include\httpd.h
--- httpd-2.1\include\httpd.h   Mon Feb 03 18:52:53 2003
+++ httpd-2.1.escape\include\httpd.h    Wed Mar 05 01:08:12 2003
@@ -1360,6 +1360,14 @@
 AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s);
 
 /**
+ * Escape a string for logging
+ * @param p The pool to allocate from
+ * @param s The string to escape
+ * @return The escaped string
+ */
+AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str);
+
+/**
  * Construct a full hostname
  * @param p The pool to allocate from
  * @param hostname The hostname of the server
diff -Nur httpd-2.1\modules\loggers\mod_log_config.c 
httpd-2.1.escape\modules\loggers\mod_log_config.c
--- httpd-2.1\modules\loggers\mod_log_config.c  Fri Feb 14 15:25:44 2003
+++ httpd-2.1.escape\modules\loggers\mod_log_config.c   Wed Mar 05 01:55:29 2003
@@ -333,8 +333,9 @@
 
 static const char *log_remote_host(request_rec *r, char *a)
 {
-    return ap_get_remote_host(r->connection, r->per_dir_config,
-                                    REMOTE_NAME, NULL);
+    return ap_escape_logitem(r->pool, ap_get_remote_host(r->connection,
+                                                         r->per_dir_config,
+                                                         REMOTE_NAME, NULL));
 }
 
 static const char *log_remote_address(request_rec *r, char *a)
@@ -349,7 +350,7 @@
 
 static const char *log_remote_logname(request_rec *r, char *a)
 {
-    return ap_get_remote_logname(r);
+    return ap_escape_logitem(r->pool, ap_get_remote_logname(r));
 }
 
 static const char *log_remote_user(request_rec *r, char *a)
@@ -362,6 +363,10 @@
     else if (strlen(rvalue) == 0) {
         rvalue = "\"\"";
     }
+    else {
+        rvalue = ap_escape_logitem(r->pool, rvalue);
+    }
+
     return rvalue;
 }
 
@@ -372,33 +377,37 @@
      * (note the truncation before the protocol string for HTTP/0.9 requests)
      * (note also that r->the_request contains the unmodified request)
      */
-    return (r->parsed_uri.password) 
-                ? apr_pstrcat(r->pool, r->method, " ",
-                              apr_uri_unparse(r->pool, &r->parsed_uri, 0),
-                              r->assbackwards ? NULL : " ", r->protocol, NULL)
-                : r->the_request;
+    return ap_escape_logitem(r->pool,
+                             (r->parsed_uri.password)
+                               ? apr_pstrcat(r->pool, r->method, " ",
+                                             apr_uri_unparse(r->pool,
+                                                             &r->parsed_uri, 0),
+                                             r->assbackwards ? NULL : " ",
+                                             r->protocol, NULL)
+                               : r->the_request);
 }
 
 static const char *log_request_file(request_rec *r, char *a)
 {
-    return r->filename;
+    return ap_escape_logitem(r->pool, r->filename);
 }
 static const char *log_request_uri(request_rec *r, char *a)
 {
-    return r->uri;
+    return ap_escape_logitem(r->pool, r->uri);
 }
 static const char *log_request_method(request_rec *r, char *a)
 {
-    return r->method;
+    return ap_escape_logitem(r->pool, r->method);
 }
 static const char *log_request_protocol(request_rec *r, char *a)
 {
-    return r->protocol;
+    return ap_escape_logitem(r->pool, r->protocol);
 }
 static const char *log_request_query(request_rec *r, char *a)
 {
-    return (r->args != NULL) ? apr_pstrcat(r->pool, "?", r->args, NULL)
-                             : "";
+    return (r->args) ? apr_pstrcat(r->pool, "?",
+                                   ap_escape_logitem(r->pool, r->args), NULL)
+                     : "";
 }
 static const char *log_status(request_rec *r, char *a)
 {
@@ -428,7 +437,7 @@
 
 static const char *log_header_in(request_rec *r, char *a)
 {
-    return apr_table_get(r->headers_in, a);
+    return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a));
 }
 
 static const char *log_header_out(request_rec *r, char *a)
@@ -438,18 +447,18 @@
         cp = ap_field_noparam(r->pool, r->content_type);
     }
     if (cp) {
-        return cp;
+        return ap_escape_logitem(r->pool, cp);
     }
-    return apr_table_get(r->err_headers_out, a);
+    return ap_escape_logitem(r->pool, apr_table_get(r->err_headers_out, a));
 }
 
 static const char *log_note(request_rec *r, char *a)
 {
-    return apr_table_get(r->notes, a);
+    return ap_escape_logitem(r->pool, apr_table_get(r->notes, a));
 }
 static const char *log_env_var(request_rec *r, char *a)
 {
-    return apr_table_get(r->subprocess_env, a);
+    return ap_escape_logitem(r->pool, apr_table_get(r->subprocess_env, a));
 }
 
 static const char *log_cookie(request_rec *r, char *a)
@@ -467,7 +476,7 @@
             if (end_cookie) {
                 *end_cookie = '\0';
             }
-            return cookie;
+            return ap_escape_logitem(r->pool, cookie);
         }
     }
     return NULL;
@@ -585,7 +594,7 @@
  */
 static const char *log_virtual_host(request_rec *r, char *a)
 {
-    return r->server->server_hostname;
+    return ap_escape_logitem(r->pool, r->server->server_hostname);
 }
 
 static const char *log_server_port(request_rec *r, char *a)
@@ -599,7 +608,7 @@
  */
 static const char *log_server_name(request_rec *r, char *a)
 {
-    return ap_get_server_name(r);
+    return ap_escape_logitem(r->pool, ap_get_server_name(r));
 }
 
 static const char *log_child_pid(request_rec *r, char *a)
diff -Nur httpd-2.1\server\gen_test_char.c httpd-2.1.escape\server\gen_test_char.c
--- httpd-2.1\server\gen_test_char.c    Mon Feb 03 18:53:18 2003
+++ httpd-2.1.escape\server\gen_test_char.c     Wed Mar 05 01:11:22 2003
@@ -73,6 +73,7 @@
 #define T_ESCAPE_PATH_SEGMENT (0x02)
 #define T_OS_ESCAPE_PATH      (0x04)
 #define T_HTTP_TOKEN_STOP     (0x08)
+#define T_ESCAPE_LOGITEM      (0x10)
 
 int main(int argc, char *argv[])
 {
@@ -85,13 +86,15 @@
            "#define T_ESCAPE_PATH_SEGMENT  (%u)\n"
            "#define T_OS_ESCAPE_PATH       (%u)\n"
            "#define T_HTTP_TOKEN_STOP      (%u)\n"
+           "#define T_ESCAPE_LOGITEM       (%u)\n"
            "\n"
            "static const unsigned char test_char_table[256] = {\n"
            "    0,",
            T_ESCAPE_SHELL_CMD,
            T_ESCAPE_PATH_SEGMENT,
            T_OS_ESCAPE_PATH,
-           T_HTTP_TOKEN_STOP);
+           T_HTTP_TOKEN_STOP,
+           T_ESCAPE_LOGITEM);
 
     /* we explicitly dealt with NUL above
      * in case some strchr() do bogosity with it */
@@ -135,8 +138,16 @@
             flags |= T_HTTP_TOKEN_STOP;
         }
 
-        printf("%u%c", flags, (c < 255) ? ',' : ' ');
+        /* For logging, escape all control characters,
+         * double quotes (because they delimit the request in the log file)
+         * backslashes (because we use backslash for escaping)
+         * and 8-bit chars with the high bit set
+         */
+        if (!apr_isprint(c) || c == '"' || c == '\\' || apr_iscntrl(c)) {
+            flags |= T_ESCAPE_LOGITEM;
+        }
 
+        printf("%u%c", flags, (c < 255) ? ',' : ' ');
     }
 
     printf("\n};\n");
diff -Nur httpd-2.1\server\util.c httpd-2.1.escape\server\util.c
--- httpd-2.1\server\util.c     Thu Feb 13 03:42:51 2003
+++ httpd-2.1.escape\server\util.c      Wed Mar 05 00:16:31 2003
@@ -1784,6 +1784,58 @@
     return x;
 }
 
+AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str)
+{
+    char *ret;
+    unsigned char *d;
+    const unsigned char *s;
+
+    if (!str) {
+        return NULL;
+    }
+
+    ret = apr_palloc(p, 4 * strlen(str) + 1); /* Be safe */
+    d = (unsigned char *)ret;
+    s = (const unsigned char *)str;
+    for (; *s; ++s) {
+
+        if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
+            *d++ = '\\';
+            switch(*s) {
+            case '\b':
+                *d++ = 'b';
+                break;
+            case '\n':
+                *d++ = 'n';
+                break;
+            case '\r':
+                *d++ = 'r';
+                break;
+            case '\t':
+                *d++ = 't';
+                break;
+            case '\v':
+                *d++ = 'v';
+                break;
+            case '\\':
+            case '"':
+                *d++ = *s;
+                break;
+            default:
+                c2x(*s, d);
+                *d = 'x';
+                d += 3;
+            }
+        }
+        else {
+            *d++ = *s;
+        }
+    }
+    *d = '\0';
+
+    return ret;
+}
+
 AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path)
 {
     apr_finfo_t finfo;

Reply via email to