]> granicus.if.org Git - apache/commitdiff
Be more clever when allocating memory for log item to be escaped.
authorChristophe Jaillet <jailletc36@apache.org>
Wed, 22 May 2013 20:38:35 +0000 (20:38 +0000)
committerChristophe Jaillet <jailletc36@apache.org>
Wed, 22 May 2013 20:38:35 +0000 (20:38 +0000)
This should be faster and save about 70-100 bytes in the request pool with the default config.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1485409 13f79535-47bb-0310-9956-ffa450edef68

server/util.c

index c696fb7350e5e905d8fd149770b6f243f3285da9..7a9e47cf467f70a1e36ab82735b1e053bed55d47 100644 (file)
@@ -1910,16 +1910,33 @@ AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str)
     char *ret;
     unsigned char *d;
     const unsigned char *s;
+    apr_size_t length, escapes = 0;
 
     if (!str) {
         return NULL;
     }
 
-    ret = apr_palloc(p, 4 * strlen(str) + 1); /* Be safe */
+    /* Compute how many characters need to be escaped */
+    s = (const unsigned char *)str;
+    for (; *s; ++s) {
+        if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
+            escapes++;
+        }
+    }
+    
+    /* Compute the length of the input string, including NULL */
+    length = s - (const unsigned char *)str + 1;
+    
+    /* Fast path: nothing to escape */
+    if (escapes == 0) {
+        return apr_pmemdup(p, str, length);
+    }
+    
+    /* Each escaped character needs up to 3 extra bytes (0 --> \x00) */
+    ret = apr_palloc(p, length + 3 * escapes);
     d = (unsigned char *)ret;
     s = (const unsigned char *)str;
     for (; *s; ++s) {
-
         if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
             *d++ = '\\';
             switch(*s) {