summaryrefslogtreecommitdiff
path: root/chromium/third_party/libxml/src/nanohttp.c
diff options
context:
space:
mode:
authorMichael BrĂ¼ning <michael.bruning@qt.io>2023-05-04 13:15:21 +0200
committerMichael BrĂ¼ning <michael.bruning@qt.io>2023-05-05 07:37:00 +0000
commitb3010ad699b05b928359e7bd27cc623f789b6f12 (patch)
tree8dd9dcde540eff80f4530037ec1ab7d2b7338ef6 /chromium/third_party/libxml/src/nanohttp.c
parent49fb5fe113f79575614e5dd183e05222c7749c75 (diff)
downloadqtwebengine-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.c114
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);