diff options
author | Michael BrĂ¼ning <michael.bruning@qt.io> | 2023-05-04 13:15:21 +0200 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2023-05-05 07:37:00 +0000 |
commit | b3010ad699b05b928359e7bd27cc623f789b6f12 (patch) | |
tree | 8dd9dcde540eff80f4530037ec1ab7d2b7338ef6 /chromium/third_party/libxml/src/nanohttp.c | |
parent | 49fb5fe113f79575614e5dd183e05222c7749c75 (diff) | |
download | qtwebengine-chromium-b3010ad699b05b928359e7bd27cc623f789b6f12.tar.gz |
[Backport] CVE-2023-29469 / Security bug 1433328
Manual roll of libxml to include cherry-picked security fix.
Originally reviewed on:
https://chromium-review.googlesource.com/c/chromium/src/+/4457227
Change-Id: If4241792fd07d82d57ecd4b82b928f070a1c43e0
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/475993
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/third_party/libxml/src/nanohttp.c')
-rw-r--r-- | chromium/third_party/libxml/src/nanohttp.c | 114 |
1 files changed, 110 insertions, 4 deletions
diff --git a/chromium/third_party/libxml/src/nanohttp.c b/chromium/third_party/libxml/src/nanohttp.c index 0678b730eed..e014fe48862 100644 --- a/chromium/third_party/libxml/src/nanohttp.c +++ b/chromium/third_party/libxml/src/nanohttp.c @@ -16,11 +16,14 @@ #ifdef LIBXML_HTTP_ENABLED #include <string.h> +#include <ctype.h> #include <stdlib.h> #include <errno.h> #ifdef HAVE_UNISTD_H #include <unistd.h> +#elif defined (_WIN32) +#include <io.h> #endif #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> @@ -1259,6 +1262,107 @@ xmlNanoHTTPClose(void *ctx) { xmlNanoHTTPFreeCtxt(ctxt); } + +/** + * xmlNanoHTTPHostnameMatch: + * @pattern: The pattern as it appears in no_proxy environment variable + * @hostname: The hostname to test as it appears in the URL + * + * This function tests whether a given hostname matches a pattern. The pattern + * usually is a token from the no_proxy environment variable. Wildcards in the + * pattern are not supported. + * + * Returns true, iff hostname matches the pattern. + */ + +static int +xmlNanoHTTPHostnameMatch(const char *pattern, const char *hostname) { + int idx_pattern, idx_hostname; + const char * pattern_start; + + if (!pattern || *pattern == '\0' || !hostname) + return 0; + + /* Ignore trailing '.' */ + if (*pattern == '.') { + idx_pattern = strlen(pattern) -1; + pattern_start = pattern + 1; + } + else { + idx_pattern = strlen(pattern); + pattern_start = pattern; + } + idx_hostname = strlen(hostname); + + for (; idx_pattern >= 0 && idx_hostname >= 0; + --idx_pattern, --idx_hostname) { + if (tolower(pattern_start[idx_pattern]) != tolower(hostname[idx_hostname])) + break; + } + + return idx_pattern == -1 && (idx_hostname == -1|| hostname[idx_hostname] == '.'); +} + + +/** + * xmlNanoHTTPBypassProxy: + * @hostname: The hostname as it appears in the URL + * + * This function evaluates the no_proxy environment variable and returns + * whether the proxy server should be bypassed for a given host. + * + * Returns true, iff a proxy server should be bypassed for the given hostname. + */ + +static int +xmlNanoHTTPBypassProxy(const char *hostname) { + size_t envlen; + char *env = getenv("no_proxy"), *cpy=NULL, *p=NULL; + if (!env) + return 0; + + /* (Avoid strdup because it's not portable.) */ + envlen = strlen(env) + 1; + cpy = xmlMalloc(envlen); + memcpy(cpy, env, envlen); + env = cpy; + + /* The remainder of the function is basically a tokenizing: */ + while (isspace(*env)) + ++env; + if (*env == '\0') { + xmlFree(cpy); + return 0; + } + + p = env; + while (*env) { + + if (*env != ',') { + ++env; + continue; + } + + *(env++) = '\0'; + if (xmlNanoHTTPHostnameMatch(p, hostname)) { + xmlFree(cpy); + return 1; + } + + while (isspace(*env)) + ++env; + p = env; + } + if (xmlNanoHTTPHostnameMatch(p, hostname)) { + xmlFree(cpy); + return 1; + } + + xmlFree(cpy); + return 0; +} + + /** * xmlNanoHTTPMethodRedir: * @URL: The URL to load @@ -1286,6 +1390,7 @@ xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input, int blen; SOCKET ret; int nbRedirects = 0; + int use_proxy; char *redirURL = NULL; #ifdef DEBUG_HTTP int xmt_bytes; @@ -1320,7 +1425,8 @@ retry: if (redirURL != NULL) xmlFree(redirURL); return(NULL); } - if (proxy) { + use_proxy = proxy && !xmlNanoHTTPBypassProxy(ctxt->hostname); + if (use_proxy) { blen = strlen(ctxt->hostname) * 2 + 16; ret = xmlNanoHTTPConnectHost(proxy, proxyPort); } @@ -1355,7 +1461,7 @@ retry: #endif if (ctxt->port != 80) { /* reserve space for ':xxxxx', incl. potential proxy */ - if (proxy) + if (use_proxy) blen += 17; else blen += 11; @@ -1369,7 +1475,7 @@ retry: p = bp; - if (proxy) { + if (use_proxy) { if (ctxt->port != 80) { p += snprintf( p, blen - (p - bp), "%s http://%s:%d%s", method, ctxt->hostname, @@ -1410,7 +1516,7 @@ retry: #ifdef DEBUG_HTTP xmlGenericError(xmlGenericErrorContext, - "-> %s%s", proxy? "(Proxy) " : "", bp); + "-> %s%s", use_proxy ? "(Proxy) " : "", bp); if ((blen -= strlen(bp)+1) < 0) xmlGenericError(xmlGenericErrorContext, "ERROR: overflowed buffer by %d bytes\n", -blen); |