diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 00dfa0f..d5a6c7f 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1442,9 +1442,10 @@ static DWORD HTTPREQ_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b case INTERNET_OPTION_HANDLE_TYPE: TRACE("INTERNET_OPTION_HANDLE_TYPE\n"); - if (*size < sizeof(ULONG)) + if (*size < sizeof(DWORD)) { + *size = sizeof(DWORD); return ERROR_INSUFFICIENT_BUFFER; - + } *size = sizeof(DWORD); *(DWORD*)buffer = INTERNET_HANDLE_TYPE_HTTP_REQUEST; return ERROR_SUCCESS; @@ -1471,16 +1472,19 @@ static DWORD HTTPREQ_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b if(unicode) { len = (strlenW(url)+1) * sizeof(WCHAR); - if(*size < len) + if(*size < len) { + *size = len; return ERROR_INSUFFICIENT_BUFFER; - + } *size = len; strcpyW(buffer, url); return ERROR_SUCCESS; }else { len = WideCharToMultiByte(CP_ACP, 0, url, -1, buffer, *size, NULL, NULL); - if(len > *size) + if(*size < len) { + *size = len; return ERROR_INSUFFICIENT_BUFFER; + } *size = len; return ERROR_SUCCESS; @@ -1519,16 +1523,16 @@ static DWORD HTTPREQ_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b case INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT: { PCCERT_CONTEXT context; - if(*size < sizeof(INTERNET_CERTIFICATE_INFOW)) { - *size = sizeof(INTERNET_CERTIFICATE_INFOW); - return ERROR_INSUFFICIENT_BUFFER; - } - context = (PCCERT_CONTEXT)NETCON_GetCert(&(req->netConnection)); if(context) { INTERNET_CERTIFICATE_INFOW *info = (INTERNET_CERTIFICATE_INFOW*)buffer; DWORD len; + if(*size < sizeof(INTERNET_CERTIFICATE_INFOW)) { + *size = sizeof(INTERNET_CERTIFICATE_INFOW); + return ERROR_INSUFFICIENT_BUFFER; + } + memset(info, 0, sizeof(INTERNET_CERTIFICATE_INFOW)); info->ftExpiry = context->pCertInfo->NotAfter; info->ftStart = context->pCertInfo->NotBefore; @@ -1576,6 +1580,12 @@ static DWORD HTTPREQ_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b CertFreeCertificateContext(context); return ERROR_SUCCESS; } + else { + if(*size < sizeof(INTERNET_CERTIFICATE_INFOW)) { + *size = sizeof(INTERNET_CERTIFICATE_INFOW); + return ERROR_INTERNET_INVALID_OPERATION; + } + } } } @@ -2191,7 +2201,8 @@ static BOOL WINAPI HTTP_HttpQueryInfoW( LPWININETHTTPREQW lpwhr, DWORD dwInfoLev BOOL ret = FALSE; if (request_only) - headers = HTTP_BuildHeaderRequestString(lpwhr, lpwhr->lpszVerb, lpwhr->lpszPath, lpwhr->lpszVersion); + headers = HTTP_BuildHeaderRequestString(lpwhr, lpwhr->lpszVerb, + lpwhr->lpszPath, lpwhr->lpszVersion); else headers = lpwhr->lpszRawHeaders; @@ -2311,7 +2322,9 @@ static BOOL WINAPI HTTP_HttpQueryInfoW( LPWININETHTTPREQW lpwhr, DWORD dwInfoLev } if (lpdwIndex) + { (*lpdwIndex)++; + } /* coalesce value to requested type */ if (dwInfoLevel & HTTP_QUERY_FLAG_NUMBER) diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index d06298f..b9376e1 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -504,8 +504,10 @@ static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b case INTERNET_OPTION_HANDLE_TYPE: TRACE("INTERNET_OPTION_HANDLE_TYPE\n"); - if (*size < sizeof(ULONG)) + if (*size < sizeof(DWORD)) { + *size = sizeof(DWORD); return ERROR_INSUFFICIENT_BUFFER; + } *size = sizeof(DWORD); *(DWORD*)buffer = INTERNET_HANDLE_TYPE_INTERNET; @@ -545,8 +547,10 @@ static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b proxyBytesRequired = (lstrlenW(ai->lpszProxy) + 1) * sizeof(WCHAR); if (ai->lpszProxyBypass) proxyBypassBytesRequired = (lstrlenW(ai->lpszProxyBypass) + 1) * sizeof(WCHAR); - if (*size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired) - return ERROR_INSUFFICIENT_BUFFER; + if (*size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired) { + *size = sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired; + return ERROR_INSUFFICIENT_BUFFER; + } proxy = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW)); proxy_bypass = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired); @@ -577,7 +581,10 @@ static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b proxyBypassBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->lpszProxyBypass, -1, NULL, 0, NULL, NULL); if (*size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired) + { + *size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired; return ERROR_INSUFFICIENT_BUFFER; + } proxy = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA)); proxy_bypass = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired); @@ -599,6 +606,10 @@ static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b *size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired; return ERROR_SUCCESS; } + case INTERNET_OPTION_MAX_CONNS_PER_SERVER: + case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER: + *size = 0; + return ERROR_INTERNET_INVALID_OPERATION; } return INET_QueryOption(option, buffer, size, unicode); @@ -2028,8 +2039,10 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) case INTERNET_OPTION_REQUEST_FLAGS: TRACE("INTERNET_OPTION_REQUEST_FLAGS\n"); - if (*size < sizeof(ULONG)) + if (*size < sizeof(ULONG)) { + *size = sizeof(ULONG); return ERROR_INSUFFICIENT_BUFFER; + } *(ULONG*)buffer = 4; *size = sizeof(ULONG); @@ -2037,8 +2050,10 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) return ERROR_SUCCESS; case INTERNET_OPTION_HTTP_VERSION: - if (*size < sizeof(HTTP_VERSION_INFO)) + if (*size < sizeof(HTTP_VERSION_INFO)) { + *size = sizeof(HTTP_VERSION_INFO); return ERROR_INSUFFICIENT_BUFFER; + } /* * Presently hardcoded to 1.1 @@ -2052,8 +2067,10 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) case INTERNET_OPTION_CONNECTED_STATE: FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n"); - if (*size < sizeof(ULONG)) + if (*size < sizeof(ULONG)) { + *size = sizeof(ULONG); return ERROR_INSUFFICIENT_BUFFER; + } *(ULONG*)buffer = INTERNET_STATE_CONNECTED; *size = sizeof(ULONG); @@ -2072,9 +2089,11 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) case INTERNET_OPTION_MAX_CONNS_PER_SERVER: TRACE("INTERNET_OPTION_MAX_CONNS_PER_SERVER\n"); - - if (*size < sizeof(ULONG)) + + if (*size < sizeof(ULONG)) { + *size = sizeof(ULONG); return ERROR_INSUFFICIENT_BUFFER; + } *(ULONG*)buffer = 2; *size = sizeof(ULONG); @@ -2084,8 +2103,10 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER: TRACE("INTERNET_OPTION_MAX_CONNS_1_0_SERVER\n"); - if (*size < sizeof(ULONG)) + if (*size < sizeof(ULONG)) { + *size = sizeof(ULONG); return ERROR_INSUFFICIENT_BUFFER; + } *(ULONG*)size = 4; *size = sizeof(ULONG); @@ -2101,8 +2122,10 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) TRACE("INTERNET_OPTION_VERSION\n"); - if (*size < sizeof(INTERNET_VERSION_INFO)) + if (*size < sizeof(INTERNET_VERSION_INFO)) { + *size = sizeof(INTERNET_VERSION_INFO); return ERROR_INSUFFICIENT_BUFFER; + } memcpy(buffer, &info, sizeof(info)); *size = sizeof(info); @@ -2116,8 +2139,10 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) FIXME("INTERNET_OPTION_PER_CONNECTION_OPTION stub\n"); - if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) + if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) { + *size = sizeof(INTERNET_PER_CONN_OPTION_LISTW); return ERROR_INSUFFICIENT_BUFFER; + } for (i = 0; i < con->dwOptionCount; i++) { INTERNET_PER_CONN_OPTIONW *option = con->pOptions + i; diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 14adc43..0f06e84 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -363,6 +363,171 @@ static void test_version(void) } /* ############################### */ +static void internetQWCheckOption(HINTERNET hinet,DWORD dwOption,LPCSTR format,DWORD goodSize) +{ + DWORD retval,len=0; + + retval=InternetQueryOptionW(hinet,dwOption,NULL,&len); + ok(len == goodSize,format,len,goodSize); +} + +static void internetQWCheckErr(DWORD goodErr,LPCSTR format) +{ + DWORD err; + + err = GetLastError(); + ok(err == goodErr,format,err, goodErr); +} + +static void test_InternetQueryOptionWNullBuffer(void) +{ + HINTERNET hinet,hinet1; + const WCHAR useragent[] = {'W','i','n','i','n','e','t',' ','T','e','s','t',0}; + const WCHAR szUrl[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',0}; + + internetQWCheckOption(NULL,INTERNET_OPTION_MAX_CONNS_PER_SERVER, + "Open: INTERNET_OPTION_MAX_CONNS_PER_SERVER Got wrong length %d instead of %d\n", + sizeof(ULONG)); + internetQWCheckErr(ERROR_INSUFFICIENT_BUFFER, + "Open: INTERNET_OPTION_MAX_CONNS_PER_SERVER Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(NULL,INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER, + "Open: INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER Got wrong length %d instead of %d\n", + sizeof(ULONG)); + internetQWCheckErr(ERROR_INSUFFICIENT_BUFFER, + "Open: INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER Wrong Error %d Expecting %d\n"); + + + hinet = InternetOpenW(useragent,0,NULL,NULL,0); + ok((hinet != 0x0),"InternetOpen Failed\n"); + + internetQWCheckOption(hinet,INTERNET_OPTION_REQUEST_FLAGS, + "INTERNET_OPTION_REQUEST_FLAGS Got wrong length %d instead of %d\n", + sizeof(ULONG)); + + internetQWCheckOption(hinet,INTERNET_OPTION_HTTP_VERSION, + "INTERNET_OPTION_HTTP_VERSION Got wrong length %d instead of %d\n", + sizeof(HTTP_VERSION_INFO)); + + internetQWCheckOption(hinet,INTERNET_OPTION_CONNECTED_STATE, + "INTERNET_OPTION_CONNECTED_STATE Got wrong length %d instead of %d\n", + sizeof(ULONG)); + + internetQWCheckOption(hinet,INTERNET_OPTION_PROXY, + "INTERNET_OPTION_PROXY Got wrong length %d instead of %d\n", + sizeof(INTERNET_PROXY_INFO)); + + internetQWCheckOption(hinet,INTERNET_OPTION_VERSION, + "INTERNET_OPTION_VERSION Got wrong length %d instead of %d\n", + sizeof(INTERNET_VERSION_INFO)); + + internetQWCheckOption(hinet,INTERNET_OPTION_MAX_CONNS_PER_SERVER, + "INTERNET_OPTION_MAX_CONNS_PER_SERVER Got wrong length %d instead of %d\n" + ,0); + internetQWCheckErr(ERROR_INTERNET_INVALID_OPERATION, + "INTERNET_OPTION_MAX_CONNS_PER_SERVER Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet,INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER, + "INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER Got wrong length %d instead of %d\n", + 0); + internetQWCheckErr(ERROR_INTERNET_INVALID_OPERATION, + "INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet,INTERNET_OPTION_SECURITY_FLAGS, + "INTERNET_OPTION_SECURITY_FLAGS Got wrong length %d instead of %d\n", + 0); + todo_wine{internetQWCheckErr(ERROR_INTERNET_INCORRECT_HANDLE_TYPE, + "INTERNET_OPTION_SECURITY_FLAGS Wrong Error %d Expecting %d\n");} + + todo_wine{ internetQWCheckOption(hinet,INTERNET_OPTION_PER_CONNECTION_OPTION, + "INTERNET_OPTION_PER_CONNECTION_OPTION Got wrong length %d instead of %d\n", + 0); + internetQWCheckErr(ERROR_INVALID_PARAMETER, + "INTERNET_OPTION_PER_CONNECTION_OPTION Wrong Error %d Expecting %d\n"); + } + + internetQWCheckOption(hinet,INTERNET_OPTION_HANDLE_TYPE, + "INTERNET_OPTION_HANDLE_TYPE Got wrong length %d instead of %d\n", + sizeof(DWORD)); + internetQWCheckErr(ERROR_INSUFFICIENT_BUFFER, + "INTERNET_OPTION_HANDLE_TYPE Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet,INTERNET_OPTION_USER_AGENT, + "INTERNET_OPTION_USER_AGENT Got wrong length %d instead of %d\n", + sizeof(useragent)); + internetQWCheckErr(ERROR_INSUFFICIENT_BUFFER, + "INTERNET_OPTION_USER_AGENT Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet,INTERNET_OPTION_URL, + "INTERNET_OPTION_URL Got wrong length %d instead of %d\n", + 0); + internetQWCheckErr(ERROR_INTERNET_INCORRECT_HANDLE_TYPE, + "INTERNET_OPTION_URL Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet,INTERNET_OPTION_DATAFILE_NAME, + "INTERNET_OPTION_DATAFILE_NAME Got wrong length %d instead of %d\n", + 0); + internetQWCheckErr(ERROR_INTERNET_INCORRECT_HANDLE_TYPE, + "INTERNET_OPTION_DATAFILE_NAME Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet,INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, + "INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT Got wrong length %d instead of %d\n", + 0); + internetQWCheckErr(ERROR_INTERNET_INCORRECT_HANDLE_TYPE, + "INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT Wrong Error %d Expecting %d\n"); + + + hinet1 = InternetOpenUrlW(hinet,szUrl,0,0,0,0); + + todo_wine {internetQWCheckOption(hinet1,INTERNET_OPTION_SECURITY_FLAGS, + "Open: INTERNET_OPTION_SECURITY_FLAGS Got wrong length %d instead of %d\n", + sizeof(ULONG)); + internetQWCheckErr(ERROR_INSUFFICIENT_BUFFER, + "Open: INTERNET_OPTION_SECURITY_FLAGS Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet1,INTERNET_OPTION_PER_CONNECTION_OPTION, + "Open: INTERNET_OPTION_PER_CONNECTION_OPTION Got wrong length %d instead of %d\n", + 0); + internetQWCheckErr(ERROR_INVALID_PARAMETER, + "Open: INTERNET_OPTION_PER_CONNECTION_OPTION Wrong Error %d Expecting %d\n");} + + internetQWCheckOption(hinet1,INTERNET_OPTION_HANDLE_TYPE, + "Open: INTERNET_OPTION_HANDLE_TYPE Got wrong length %d instead of %d\n", + sizeof(DWORD)); + internetQWCheckErr(ERROR_INSUFFICIENT_BUFFER, + "Open: INTERNET_OPTION_HANDLE_TYPE Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet1,INTERNET_OPTION_USER_AGENT, + "Open: INTERNET_OPTION_USER_AGENT Got wrong length %d instead of %d\n", + 0); + internetQWCheckErr(ERROR_INTERNET_INCORRECT_HANDLE_TYPE, + "Open: INTERNET_OPTION_USER_AGENT Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet1,INTERNET_OPTION_URL, + "Open: INTERNET_OPTION_URL Got wrong length %d instead of %d\n", + sizeof(szUrl)+2); + internetQWCheckErr(ERROR_INSUFFICIENT_BUFFER, + "Open: INTERNET_OPTION_URL Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet1,INTERNET_OPTION_DATAFILE_NAME, + "Open: INTERNET_OPTION_DATAFILE_NAME Got wrong length %d instead of %d\n", + 0); + internetQWCheckErr(ERROR_INTERNET_ITEM_NOT_FOUND, + "Open: INTERNET_OPTION_DATAFILE_NAME Wrong Error %d Expecting %d\n"); + + internetQWCheckOption(hinet1,INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, + "Open: INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT Got wrong length %d instead of %d\n", + sizeof(INTERNET_CERTIFICATE_INFO)); + internetQWCheckErr(ERROR_INTERNET_INVALID_OPERATION, + "Open: INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT Wrong Error %d Expecting %d\n"); + + + InternetCloseHandle(hinet1); + InternetCloseHandle(hinet); + +} + +/* ############################### */ START_TEST(internet) { @@ -371,4 +536,5 @@ START_TEST(internet) test_get_cookie(); test_version(); test_null(); + test_InternetQueryOptionWNullBuffer(); } -- 1.6.0.1