]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
PR#64443: watch whether mod_proxy_html i18n might risk messing up FORM
authorNick Kew <niq@apache.org>
Sat, 6 Jun 2020 22:54:32 +0000 (22:54 +0000)
committerNick Kew <niq@apache.org>
Sat, 6 Jun 2020 22:54:32 +0000 (22:54 +0000)
submission, and insert accept-charset attribute if necessary.

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

modules/filters/mod_proxy_html.c

index 66b56a367cd3c4372e618ebdd7eef247d90c5bf4..685cb8be5740d19cdac4c254414c47aa6cbe7103 100644 (file)
@@ -417,6 +417,9 @@ static void pstartElement(void *ctxt, const xmlChar *uname,
     const char** attrs = (const char**) uattrs;
     const htmlElemDesc* desc = htmlTagLookup(uname);
     urlmap *themap = ctx->map;
+    const char *accept_charset = NULL;
+
+
 #ifdef HAVE_STACK
     const void** descp;
 #endif
@@ -446,6 +449,21 @@ static void pstartElement(void *ctxt, const xmlChar *uname,
     /* TODO - implement HTML "allowed here" */
 #endif
 
+    /* PR#64443: for <FORM>, insert accept-charset attribute if necessary
+     * It's necessary if we've changed the charset (i.e. input not UTF-8)
+     *  UNLESS someone has taken charge.
+     * If there's already an accept-charset, then the backend is in charge.
+     * If ProxyHTMLCharsetOut is set, the sysop has taken charge.
+     */
+    if ((xml2enc_charset != NULL) && (ctx->cfg->charset_out == NULL)
+        && !strcasecmp(name, "FORM")) {
+        xmlCharEncoding enc;
+        if ((xml2enc_charset(ctx->f->r, &enc, &accept_charset) != APR_SUCCESS)
+            || (enc == XML_CHAR_ENCODING_UTF8)) {
+            accept_charset = NULL;  /* Now pay attention if not NULL */
+        }
+    }
+
     ap_fputc(ctx->f->next, ctx->bb, '<');
     ap_fputs(ctx->f->next, ctx->bb, name);
 
@@ -672,8 +690,17 @@ static void pstartElement(void *ctxt, const xmlChar *uname,
                 pcharacters(ctx, (const xmlChar*)ctx->buf, strlen(ctx->buf));
                 ap_fputc(ctx->f->next, ctx->bb, '"');
             }
+            /* PR#64443: watch for accept-charset from backend */
+            if (accept_charset && !strcasecmp(a[0], "accept-charset")) {
+                accept_charset = NULL;
+            }
         }
     }
+    /* PR#64443: we've seen all we need, so add accept-charset if necessary */
+    if (accept_charset != NULL) {
+        ap_fprintf(ctx->f->next, ctx->bb, " accept-charset=\"%s\"",
+                   accept_charset);
+    }
     ctx->offset = 0;
     if (desc && desc->empty)
         ap_fputs(ctx->f->next, ctx->bb, ctx->etag);