From: Joe Orton Date: Thu, 4 Jun 2026 09:03:50 +0000 (+0000) Subject: mod_proxy_html: Simplify to use the ap_varbuf API. X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=9dc00bf22922b805d780f403132d2e35a99ced93;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy_html: Simplify to use the ap_varbuf API. * modules/filters/mod_proxy_html.c: Include util_varbuf.h. (saxctxt): Replace buf/offset/avail members with struct ap_varbuf vb. (DEFAULT_BUFSZ): New macro. (normalise): Take struct ap_varbuf * parameter instead of char *. (preserve, pappend): Remove functions, replaced by ap_varbuf_grow and ap_varbuf_strmemcat respectively. (dump_content): Use ap_varbuf for regex substitutions via ap_varbuf_regsub, avoiding manual buffer resizing with preserve/memmove/memcpy. Use a temporary ap_varbuf for building regex replacement results. (pcharacters, pcomment): Use ap_varbuf_strmemcat and ap_varbuf_strcat in place of pappend. (pendElement): Check vb.strlen instead of offset. (pstartElement): Use ap_varbuf for attribute URL rewriting with the same ap_varbuf_regsub approach. Use a temporary ap_varbuf for regex replacements. (proxy_html_filter): Initialize the ap_varbuf with a clamped bufsz. (proxy_html_merge): Use DEFAULT_BUFSZ macro. Assisted-by: Claude Opus 4.6 (claude-opus-4-6) git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1934975 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/filters/mod_proxy_html.c b/modules/filters/mod_proxy_html.c index f64bafceb2..6e33eac46e 100644 --- a/modules/filters/mod_proxy_html.c +++ b/modules/filters/mod_proxy_html.c @@ -63,6 +63,7 @@ #include "mod_xml2enc.h" #include "http_request.h" #include "ap_expr.h" +#include "util_varbuf.h" /* globals set once at startup */ static ap_rxplus_t *old_expr; @@ -122,9 +123,7 @@ typedef struct { proxy_html_conf *cfg; htmlParserCtxtPtr parser; apr_bucket_brigade *bb; - char *buf; - size_t offset; - size_t avail; + struct ap_varbuf vb; const char *encoding; urlmap *map; const char *etag; @@ -133,6 +132,7 @@ typedef struct { apr_size_t rmin; } saxctxt; +#define DEFAULT_BUFSZ (8192) #define NORM_LC 0x1 #define NORM_MSSLASH 0x2 @@ -156,17 +156,17 @@ static const char *const xhtml_etag = " />"; static const char *const DEFAULT_DOCTYPE = ""; #define DEFAULT_ETAG html_etag -static void normalise(unsigned int flags, char *str) +static void normalise(unsigned int flags, struct ap_varbuf *vb) { - char *p; + apr_size_t n; if (flags & NORM_LC) - for (p = str; *p; ++p) - if (isupper(*p)) - *p = tolower(*p); + for (n = 0; n < vb->strlen; ++n) + vb->buf[n] = apr_tolower(vb->buf[n]); if (flags & NORM_MSSLASH) - for (p = ap_strchr(str, '\\'); p; p = ap_strchr(p+1, '\\')) - *p = '/'; + for (n = 0; n < vb->strlen; ++n) + if (vb->buf[n] == '\\') + vb->buf[n] = '/'; } #define consume_buffer(ctx,inbuf,bytes,flag) \ @@ -195,113 +195,90 @@ static void pcharacters(void *ctxt, const xmlChar *uchars, int length) FLUSH; } -static void preserve(saxctxt *ctx, const size_t len) -{ - char *newbuf; - if (len <= (ctx->avail - ctx->offset)) - return; - else while (len > (ctx->avail - ctx->offset)) - ctx->avail += ctx->cfg->bufsz; - - newbuf = ap_realloc(ctx->buf, ctx->avail); - if (newbuf != ctx->buf) { - if (ctx->buf) - apr_pool_cleanup_kill(ctx->f->r->pool, ctx->buf, - (int(*)(void*))free); - apr_pool_cleanup_register(ctx->f->r->pool, newbuf, - (int(*)(void*))free, apr_pool_cleanup_null); - ctx->buf = newbuf; - } -} - -static void pappend(saxctxt *ctx, const char *buf, const size_t len) -{ - preserve(ctx, len); - memcpy(ctx->buf+ctx->offset, buf, len); - ctx->offset += len; -} - static void dump_content(saxctxt *ctx) { urlmap *m; char *found; size_t s_from, s_to; size_t match; - char c = 0; int nmatch; ap_regmatch_t pmatch[10]; - char *subs; size_t len, offs; urlmap *themap = ctx->map; + struct ap_varbuf temp; #ifndef GO_FASTER int verbose = APLOGrtrace1(ctx->f->r); #endif - pappend(ctx, &c, 1); /* append null byte */ - /* parse the text for URLs */ + /* Ensure buffer is null-terminated and strlen is set */ + if (ctx->vb.strlen == AP_VARBUF_UNKNOWN) { + ctx->vb.strlen = strlen(ctx->vb.buf); + } + + ap_varbuf_init(ctx->f->r->pool, &temp, 0); + + /* parse the text for URLs */ for (m = themap; m; m = m->next) { if (!(m->flags & M_CDATA)) continue; if (m->flags & M_REGEX) { + temp.strlen = 0; nmatch = 10; offs = 0; - while (!ap_regexec(m->from.r, ctx->buf+offs, nmatch, pmatch, 0)) { + while (!ap_regexec(m->from.r, ctx->vb.buf+offs, nmatch, pmatch, 0)) { match = pmatch[0].rm_so; s_from = pmatch[0].rm_eo - match; - subs = ap_pregsub(ctx->f->r->pool, m->to, ctx->buf+offs, - nmatch, pmatch); - s_to = strlen(subs); - len = strlen(ctx->buf); - offs += match; VERBOSEB( const char *f = apr_pstrndup(ctx->f->r->pool, - ctx->buf + offs, s_from); + ctx->vb.buf + offs + match, s_from); ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, ctx->f->r, - "C/RX: match at %s, substituting %s", f, subs); + "C/RX: match at %s, substituting with pattern %s", + f, m->to); ) - if (s_to > s_from) { - preserve(ctx, s_to - s_from); - memmove(ctx->buf+offs+s_to, ctx->buf+offs+s_from, - len + 1 - s_from - offs); - memcpy(ctx->buf+offs, subs, s_to); - } - else { - memcpy(ctx->buf + offs, subs, s_to); - memmove(ctx->buf+offs+s_to, ctx->buf+offs+s_from, - len + 1 - s_from - offs); - } - offs += s_to; + /* Copy text before the match */ + ap_varbuf_strmemcat(&temp, ctx->vb.buf+offs, match); + /* Append the substitution */ + ap_varbuf_regsub(&temp, m->to, ctx->vb.buf+offs, nmatch, pmatch, 0); + /* Continue past the match */ + offs += pmatch[0].rm_eo; } + /* Copy any remaining text */ + ap_varbuf_strcat(&temp, ctx->vb.buf+offs); + /* Replace the original buffer with the result */ + ctx->vb.strlen = 0; + ap_varbuf_strmemcat(&ctx->vb, temp.buf, temp.strlen); } else { s_from = strlen(m->from.c); s_to = strlen(m->to); - for (found = strstr(ctx->buf, m->from.c); found; - found = strstr(ctx->buf+match+s_to, m->from.c)) { - match = found - ctx->buf; + for (found = strstr(ctx->vb.buf, m->from.c); found; + found = strstr(ctx->vb.buf+match+s_to, m->from.c)) { + match = found - ctx->vb.buf; if ((m->flags & M_ATSTART) && (match != 0)) break; - len = strlen(ctx->buf); + len = ctx->vb.strlen; if ((m->flags & M_ATEND) && (match < (len - s_from))) continue; VERBOSE(ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, ctx->f->r, "C: matched %s, substituting %s", m->from.c, m->to)); if (s_to > s_from) { - preserve(ctx, s_to - s_from); - memmove(ctx->buf+match+s_to, ctx->buf+match+s_from, + ap_varbuf_grow(&ctx->vb, len + s_to - s_from); + memmove(ctx->vb.buf+match+s_to, ctx->vb.buf+match+s_from, len + 1 - s_from - match); - memcpy(ctx->buf+match, m->to, s_to); + memcpy(ctx->vb.buf+match, m->to, s_to); } else { - memcpy(ctx->buf+match, m->to, s_to); - memmove(ctx->buf+match+s_to, ctx->buf+match+s_from, + memcpy(ctx->vb.buf+match, m->to, s_to); + memmove(ctx->vb.buf+match+s_to, ctx->vb.buf+match+s_from, len + 1 - s_from - match); } + ctx->vb.strlen = len - s_from + s_to; } } } - AP_fwrite(ctx, ctx->buf, strlen(ctx->buf), 1); + AP_fwrite(ctx, ctx->vb.buf, ctx->vb.strlen, 1); + ap_varbuf_free(&temp); } static void pinternalSubset(void* ctxt, const xmlChar *name, const xmlChar *externalID, const xmlChar *sysID) @@ -335,7 +312,7 @@ static void pcdata(void *ctxt, const xmlChar *uchars, int length) const char *chars = (const char*) uchars; saxctxt *ctx = (saxctxt*) ctxt; if (ctx->cfg->extfix) { - pappend(ctx, chars, length); + ap_varbuf_strmemcat(&ctx->vb, chars, length); } else { /* not sure if this should force-flush @@ -352,9 +329,9 @@ static void pcomment(void *ctxt, const xmlChar *uchars) return; if (ctx->cfg->extfix) { - pappend(ctx, "", 3); + ap_varbuf_strcat(&ctx->vb, ""); } else { ap_fputs(ctx->f->next, ctx->bb, "