Index: dll/win32/winhttp/session.c =================================================================== --- dll/win32/winhttp/session.c (revision 73355) +++ dll/win32/winhttp/session.c (working copy) @@ -177,6 +177,12 @@ TRACE("WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT: %p\n", *(HANDLE *)buffer); session->unload_event = *(HANDLE *)buffer; return TRUE; + case WINHTTP_OPTION_MAX_CONNS_PER_SERVER: + FIXME("WINHTTP_OPTION_MAX_CONNS_PER_SERVER: %d\n", *(DWORD *)buffer); + return TRUE; + case WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER: + FIXME("WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER: %d\n", *(DWORD *)buffer); + return TRUE; default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_INVALID_PARAMETER ); @@ -971,6 +977,14 @@ if (!(session->proxy_password = buffer_to_str( buffer, buflen ))) return FALSE; return TRUE; } + case WINHTTP_OPTION_CLIENT_CERT_CONTEXT: + if (!(hdr->flags & WINHTTP_FLAG_SECURE)) + { + SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_STATE ); + return FALSE; + } + FIXME("WINHTTP_OPTION_CLIENT_CERT_CONTEXT\n"); + return TRUE; default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_INVALID_PARAMETER ); @@ -1196,7 +1210,7 @@ { BOOL ret = TRUE; - if (!buffer) + if (!buffer && buflen) { set_last_error( ERROR_INVALID_PARAMETER ); return FALSE; @@ -1329,8 +1343,14 @@ CFRelease( settings ); return ret; #else - static int once; - if (!once++) FIXME( "no support on this platform\n" ); + static BOOL first = TRUE; + if (first) + { + FIXME( "no support on this platform\n" ); + first = FALSE; + } + else + TRACE( "no support on this platform\n" ); return FALSE; #endif } @@ -1722,6 +1742,8 @@ memset( &uc, 0, sizeof(uc) ); uc.dwStructSize = sizeof(uc); + uc.dwHostNameLength = -1; + uc.dwUrlPathLength = -1; if (!WinHttpCrackUrl( url, 0, 0, &uc )) return NULL; if (!(hostname = heap_alloc( (uc.dwHostNameLength + 1) * sizeof(WCHAR) ))) return NULL; memcpy( hostname, uc.lpszHostName, uc.dwHostNameLength * sizeof(WCHAR) ); @@ -1783,6 +1805,7 @@ char *result, *urlA; DWORD len_result; struct AUTO_PROXY_SCRIPT_BUFFER buffer; + URL_COMPONENTSW uc; buffer.dwStructSize = sizeof(buffer); buffer.lpszScriptBuffer = script; @@ -1794,10 +1817,23 @@ heap_free( urlA ); return FALSE; } - if ((ret = InternetGetProxyInfo( urlA, strlen(urlA), NULL, 0, &result, &len_result ))) + + memset( &uc, 0, sizeof(uc) ); + uc.dwStructSize = sizeof(uc); + uc.dwHostNameLength = -1; + + if (WinHttpCrackUrl( url, 0, 0, &uc )) { - ret = parse_script_result( result, info ); - heap_free( result ); + char *hostnameA = strdupWA_sized( uc.lpszHostName, uc.dwHostNameLength ); + + if ((ret = InternetGetProxyInfo( urlA, strlen(urlA), + hostnameA, strlen(hostnameA), &result, &len_result ))) + { + ret = parse_script_result( result, info ); + heap_free( result ); + } + + heap_free( hostnameA ); } heap_free( urlA ); return InternetDeInitializeAutoProxyDll( NULL, 0 ); Index: dll/win32/winhttp/url.c =================================================================== --- dll/win32/winhttp/url.c (revision 73355) +++ dll/win32/winhttp/url.c (working copy) @@ -21,37 +21,29 @@ static const WCHAR scheme_http[] = {'h','t','t','p',0}; static const WCHAR scheme_https[] = {'h','t','t','p','s',0}; -static BOOL set_component( WCHAR **str, DWORD *str_len, WCHAR *value, DWORD len, DWORD flags ) +static DWORD set_component( WCHAR **str, DWORD *str_len, WCHAR *value, DWORD len, DWORD flags, BOOL *overflow ) { - if (*str && !*str_len) - { - set_last_error( ERROR_INVALID_PARAMETER ); - return FALSE; - } - if (!*str_len) return TRUE; + if (*str && !*str_len) return ERROR_INVALID_PARAMETER; + if (!*str_len) return ERROR_SUCCESS; if (!*str) { - if (len && *str_len && (flags & (ICU_DECODE|ICU_ESCAPE))) - { - set_last_error( ERROR_INVALID_PARAMETER ); - return FALSE; - } + if (len && *str_len && (flags & (ICU_DECODE|ICU_ESCAPE))) return ERROR_INVALID_PARAMETER; *str = value; *str_len = len; } else { - if (len > (*str_len) - 1) + if (len >= *str_len) { - *str_len = len + 1; - set_last_error( ERROR_INSUFFICIENT_BUFFER ); - return FALSE; + *str_len = len+1; + *overflow = TRUE; + return ERROR_SUCCESS; } memcpy( *str, value, len * sizeof(WCHAR) ); (*str)[len] = 0; *str_len = len; } - return TRUE; + return ERROR_SUCCESS; } static WCHAR *decode_url( LPCWSTR url, DWORD *len ) @@ -159,16 +151,30 @@ return ret; } +static DWORD parse_port( const WCHAR *str, DWORD len, INTERNET_PORT *ret ) +{ + const WCHAR *p = str; + DWORD port = 0; + while (len && isdigitW( *p )) + { + if ((port = port * 10 + *p - '0') > 65535) return ERROR_WINHTTP_INVALID_URL; + p++; len--; + } + *ret = port; + return ERROR_SUCCESS; +} + /*********************************************************************** * WinHttpCrackUrl (winhttp.@) */ BOOL WINAPI WinHttpCrackUrl( LPCWSTR url, DWORD len, DWORD flags, LPURL_COMPONENTSW uc ) { - BOOL ret = FALSE; WCHAR *p, *q, *r, *url_decoded = NULL, *url_escaped = NULL; INTERNET_SCHEME scheme = 0; + BOOL overflow = FALSE; + DWORD err; - TRACE("%s, %d, %x, %p\n", debugstr_w(url), len, flags, uc); + TRACE("%s, %d, %x, %p\n", debugstr_wn(url, len), len, flags, uc); if (!url || !uc || uc->dwStructSize != sizeof(URL_COMPONENTS)) { @@ -204,47 +210,55 @@ else if (p - url == 5 && !strncmpiW( url, scheme_https, 5 )) scheme = INTERNET_SCHEME_HTTPS; else { - set_last_error( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ); + err = ERROR_WINHTTP_UNRECOGNIZED_SCHEME; goto exit; } - if (!(set_component( &uc->lpszScheme, &uc->dwSchemeLength, (WCHAR *)url, p - url, flags ))) goto exit; + if ((err = set_component( &uc->lpszScheme, &uc->dwSchemeLength, (WCHAR *)url, p - url, flags, &overflow ))) goto exit; + p++; /* skip ':' */ - if (!p[0] || p[0] != '/' || p[1] != '/') goto exit; + if (!p[0] || p[0] != '/' || p[1] != '/') + { + err = ERROR_WINHTTP_INVALID_URL; + goto exit; + } p += 2; - - if (!p[0]) goto exit; + if (!p[0]) + { + err = ERROR_WINHTTP_INVALID_URL; + goto exit; + } if ((q = memchrW( p, '@', len - (p - url) )) && !(memchrW( p, '/', q - p ))) { if ((r = memchrW( p, ':', q - p ))) { - if (!(set_component( &uc->lpszUserName, &uc->dwUserNameLength, p, r - p, flags ))) goto exit; + if ((err = set_component( &uc->lpszUserName, &uc->dwUserNameLength, p, r - p, flags, &overflow ))) goto exit; r++; - if (!(set_component( &uc->lpszPassword, &uc->dwPasswordLength, r, q - r, flags ))) goto exit; + if ((err = set_component( &uc->lpszPassword, &uc->dwPasswordLength, r, q - r, flags, &overflow ))) goto exit; } else { - if (!(set_component( &uc->lpszUserName, &uc->dwUserNameLength, p, q - p, flags ))) goto exit; - if (!(set_component( &uc->lpszPassword, &uc->dwPasswordLength, NULL, 0, flags ))) goto exit; + if ((err = set_component( &uc->lpszUserName, &uc->dwUserNameLength, p, q - p, flags, &overflow ))) goto exit; + if ((err = set_component( &uc->lpszPassword, &uc->dwPasswordLength, NULL, 0, flags, &overflow ))) goto exit; } p = q + 1; } else { - if (!(set_component( &uc->lpszUserName, &uc->dwUserNameLength, NULL, 0, flags ))) goto exit; - if (!(set_component( &uc->lpszPassword, &uc->dwPasswordLength, NULL, 0, flags ))) goto exit; + if ((err = set_component( &uc->lpszUserName, &uc->dwUserNameLength, NULL, 0, flags, &overflow ))) goto exit; + if ((err = set_component( &uc->lpszPassword, &uc->dwPasswordLength, NULL, 0, flags, &overflow ))) goto exit; } if ((q = memchrW( p, '/', len - (p - url) ))) { if ((r = memchrW( p, ':', q - p ))) { - if (!(set_component( &uc->lpszHostName, &uc->dwHostNameLength, p, r - p, flags ))) goto exit; + if ((err = set_component( &uc->lpszHostName, &uc->dwHostNameLength, p, r - p, flags, &overflow ))) goto exit; r++; - uc->nPort = atoiW( r ); + if ((err = parse_port( r, q - r, &uc->nPort ))) goto exit; } else { - if (!(set_component( &uc->lpszHostName, &uc->dwHostNameLength, p, q - p, flags ))) goto exit; + if ((err = set_component( &uc->lpszHostName, &uc->dwHostNameLength, p, q - p, flags, &overflow ))) goto exit; if (scheme == INTERNET_SCHEME_HTTP) uc->nPort = INTERNET_DEFAULT_HTTP_PORT; if (scheme == INTERNET_SCHEME_HTTPS) uc->nPort = INTERNET_DEFAULT_HTTPS_PORT; } @@ -251,13 +265,13 @@ if ((r = memchrW( q, '?', len - (q - url) ))) { - if (!(set_component( &uc->lpszUrlPath, &uc->dwUrlPathLength, q, r - q, flags ))) goto exit; - if (!(set_component( &uc->lpszExtraInfo, &uc->dwExtraInfoLength, r, len - (r - url), flags ))) goto exit; + if ((err = set_component( &uc->lpszUrlPath, &uc->dwUrlPathLength, q, r - q, flags, &overflow ))) goto exit; + if ((err = set_component( &uc->lpszExtraInfo, &uc->dwExtraInfoLength, r, len - (r - url), flags, &overflow ))) goto exit; } else { - if (!(set_component( &uc->lpszUrlPath, &uc->dwUrlPathLength, q, len - (q - url), flags ))) goto exit; - if (!(set_component( &uc->lpszExtraInfo, &uc->dwExtraInfoLength, (WCHAR *)url + len, 0, flags ))) goto exit; + if ((err = set_component( &uc->lpszUrlPath, &uc->dwUrlPathLength, q, len - (q - url), flags, &overflow ))) goto exit; + if ((err = set_component( &uc->lpszExtraInfo, &uc->dwExtraInfoLength, (WCHAR *)url + len, 0, flags, &overflow ))) goto exit; } } else @@ -264,35 +278,34 @@ { if ((r = memchrW( p, ':', len - (p - url) ))) { - if (!(set_component( &uc->lpszHostName, &uc->dwHostNameLength, p, r - p, flags ))) goto exit; + if ((err = set_component( &uc->lpszHostName, &uc->dwHostNameLength, p, r - p, flags, &overflow ))) goto exit; r++; - uc->nPort = atoiW( r ); + if ((err = parse_port( r, len - (r - url), &uc->nPort ))) goto exit; } else { - if (!(set_component( &uc->lpszHostName, &uc->dwHostNameLength, p, len - (p - url), flags ))) goto exit; + if ((err = set_component( &uc->lpszHostName, &uc->dwHostNameLength, p, len - (p - url), flags, &overflow ))) goto exit; if (scheme == INTERNET_SCHEME_HTTP) uc->nPort = INTERNET_DEFAULT_HTTP_PORT; if (scheme == INTERNET_SCHEME_HTTPS) uc->nPort = INTERNET_DEFAULT_HTTPS_PORT; } - if (!(set_component( &uc->lpszUrlPath, &uc->dwUrlPathLength, (WCHAR *)url + len, 0, flags ))) goto exit; - if (!(set_component( &uc->lpszExtraInfo, &uc->dwExtraInfoLength, (WCHAR *)url + len, 0, flags ))) goto exit; + if ((err = set_component( &uc->lpszUrlPath, &uc->dwUrlPathLength, (WCHAR *)url + len, 0, flags, &overflow ))) goto exit; + if ((err = set_component( &uc->lpszExtraInfo, &uc->dwExtraInfoLength, (WCHAR *)url + len, 0, flags, &overflow ))) goto exit; } - ret = TRUE; - - TRACE("scheme(%s) host(%s) port(%d) path(%s) extra(%s)\n", - debugstr_wn( uc->lpszScheme, uc->dwSchemeLength ), - debugstr_wn( uc->lpszHostName, uc->dwHostNameLength ), - uc->nPort, - debugstr_wn( uc->lpszUrlPath, uc->dwUrlPathLength ), + TRACE("scheme(%s) host(%s) port(%d) path(%s) extra(%s)\n", debugstr_wn( uc->lpszScheme, uc->dwSchemeLength ), + debugstr_wn( uc->lpszHostName, uc->dwHostNameLength ), uc->nPort, debugstr_wn( uc->lpszUrlPath, uc->dwUrlPathLength ), debugstr_wn( uc->lpszExtraInfo, uc->dwExtraInfoLength )); exit: - if (ret) uc->nScheme = scheme; + if (!err) + { + if (overflow) err = ERROR_INSUFFICIENT_BUFFER; + uc->nScheme = scheme; + } heap_free( url_decoded ); heap_free( url_escaped ); - if (ret) set_last_error( ERROR_SUCCESS ); - return ret; + set_last_error( err ); + return !err; } static INTERNET_SCHEME get_scheme( const WCHAR *scheme, DWORD len ) Index: dll/win32/winhttp/winhttp_private.h =================================================================== --- dll/win32/winhttp/winhttp_private.h (revision 73355) +++ dll/win32/winhttp/winhttp_private.h (working copy) @@ -380,4 +380,19 @@ return dst; } +static inline char *strdupWA_sized( const WCHAR *src, DWORD size ) +{ + char *dst = NULL; + if (src) + { + int len = WideCharToMultiByte( CP_ACP, 0, src, size, NULL, 0, NULL, NULL ) + 1; + if ((dst = heap_alloc( len ))) + { + WideCharToMultiByte( CP_ACP, 0, src, len, dst, size, NULL, NULL ); + dst[len - 1] = 0; + } + } + return dst; +} + #endif /* _WINE_WINHTTP_PRIVATE_H_ */