From 10e7063321838b6040d2d3337741f7894e045529 Mon Sep 17 00:00:00 2001 From: Stefan Fritsch Date: Sat, 3 Aug 2013 17:35:21 +0000 Subject: [PATCH] Merge r1485409: Be more clever when allocating memory for log item to be escaped. This should be faster and save about 70-100 bytes in the request pool with the default config. Reviewed by: minfrin, rjung, rpluem git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1510044 13f79535-47bb-0310-9956-ffa450edef68 --- STATUS | 13 ------------- server/util.c | 21 +++++++++++++++++++-- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/STATUS b/STATUS index c4296e1ce60..2c4491f7c87 100644 --- a/STATUS +++ b/STATUS @@ -97,19 +97,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * core: speed up (for common cases) and reduce memory usage of ap_escape_logitem - This should save 70-100 bytes in the request pool for a default config. - trunk patch: http://svn.apache.org/r1485409 - 2.4.x patch: http://svn.apache.org/r1485723 - 2.2.x patch: trunk works - +1: minfrin, rjung, rpluem - wrowe wonders why we copy and don't simply return the identity on no-change - rjung: From an API point of view the function - as well as the html escape functions - - takes a const char* and returns a plain char *. So a consumer would be free - to write to the returned string. There's no such place in httpd code I can - find but we can't rule it out for foreign modules. We could fix the signature - (returning const char *) in trunk but not for 2.2 ad 2.4. - * mod_dav; Teeny patch to fix #55304 trunk: http://svn.apache.org/r1506714 +1: gstein, wrowe, rpluem diff --git a/server/util.c b/server/util.c index f1fb2550f15..5dee87fd229 100644 --- a/server/util.c +++ b/server/util.c @@ -1845,16 +1845,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) { -- 2.47.2