wininet: Don't assume maximal URL length in HTTP_ShouldBypassProxy.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2016-05-17 19:18:05 +02:00 committed by Alexandre Julliard
parent 1d5670c7c4
commit bd1f39ea27
1 changed files with 43 additions and 59 deletions

View File

@ -1714,55 +1714,47 @@ static WCHAR *build_proxy_path_url(http_request_t *req)
return url; return url;
} }
static BOOL HTTP_DomainMatches(LPCWSTR server, LPCWSTR domain) static BOOL HTTP_DomainMatches(LPCWSTR server, substr_t domain)
{ {
static const WCHAR localW[] = { '<','l','o','c','a','l','>',0 }; static const WCHAR localW[] = { '<','l','o','c','a','l','>',0 };
BOOL ret = FALSE; const WCHAR *dot, *ptr;
int len;
if (!strcmpiW( domain, localW ) && !strchrW( server, '.' )) if(domain.len == sizeof(localW)/sizeof(WCHAR)-1 && !strncmpiW(domain.str, localW, domain.len) && !strchrW(server, '.' ))
ret = TRUE; return TRUE;
else if (*domain == '*')
{
if (domain[1] == '.')
{
LPCWSTR dot;
/* For a hostname to match a wildcard, the last domain must match if(domain.len && *domain.str != '*')
* the wildcard exactly. E.g. if the wildcard is *.a.b, and the return domain.len == strlenW(server) && !strncmpiW(server, domain.str, domain.len);
* hostname is www.foo.a.b, it matches, but a.b does not.
*/
dot = strchrW( server, '.' );
if (dot)
{
int len = strlenW( dot + 1 );
if (len > strlenW( domain + 2 )) if(domain.len < 2 || domain.str[1] != '.')
{ return FALSE;
LPCWSTR ptr;
/* The server's domain is longer than the wildcard, so it /* For a hostname to match a wildcard, the last domain must match
* could be a subdomain. Compare the last portion of the * the wildcard exactly. E.g. if the wildcard is *.a.b, and the
* server's domain. * hostname is www.foo.a.b, it matches, but a.b does not.
*/ */
ptr = dot + len + 1 - strlenW( domain + 2 ); dot = strchrW(server, '.');
if (!strcmpiW( ptr, domain + 2 )) if(!dot)
{ return FALSE;
/* This is only a match if the preceding character is
* a '.', i.e. that it is a matching domain. E.g. len = strlenW(dot + 1);
* if domain is '*.b.c' and server is 'www.ab.c' they if(len <= domain.len - 2)
* do not match. return FALSE;
*/
ret = *(ptr - 1) == '.'; /* The server's domain is longer than the wildcard, so it
} * could be a subdomain. Compare the last portion of the
} * server's domain.
else */
ret = !strcmpiW( dot + 1, domain + 2 ); ptr = dot + 1 + len - domain.len + 2;
} if(!strncmpiW(ptr, domain.str+2, domain.len-2))
} /* This is only a match if the preceding character is
} * a '.', i.e. that it is a matching domain. E.g.
else * if domain is '*.b.c' and server is 'www.ab.c' they
ret = !strcmpiW( server, domain ); * do not match.
return ret; */
return *(ptr - 1) == '.';
return len == domain.len-2 && !strncmpiW(dot + 1, domain.str + 2, len);
} }
static BOOL HTTP_ShouldBypassProxy(appinfo_t *lpwai, LPCWSTR server) static BOOL HTTP_ShouldBypassProxy(appinfo_t *lpwai, LPCWSTR server)
@ -1772,27 +1764,19 @@ static BOOL HTTP_ShouldBypassProxy(appinfo_t *lpwai, LPCWSTR server)
if (!lpwai->proxyBypass) return FALSE; if (!lpwai->proxyBypass) return FALSE;
ptr = lpwai->proxyBypass; ptr = lpwai->proxyBypass;
do { while(1) {
LPCWSTR tmp = ptr; LPCWSTR tmp = ptr;
ptr = strchrW( ptr, ';' ); ptr = strchrW( ptr, ';' );
if (!ptr) if (!ptr)
ptr = strchrW( tmp, ' ' ); ptr = strchrW( tmp, ' ' );
if (ptr) if (!ptr)
{ ptr = tmp + strlenW(ptr);
if (ptr - tmp < INTERNET_MAX_HOST_NAME_LENGTH) ret = HTTP_DomainMatches( server, substr(tmp, ptr-tmp) );
{ if (ret || !*ptr)
WCHAR domain[INTERNET_MAX_HOST_NAME_LENGTH]; break;
ptr++;
memcpy( domain, tmp, (ptr - tmp) * sizeof(WCHAR) ); }
domain[ptr - tmp] = 0;
ret = HTTP_DomainMatches( server, domain );
}
ptr += 1;
}
else if (*tmp)
ret = HTTP_DomainMatches( server, tmp );
} while (ptr && !ret);
return ret; return ret;
} }