wininet: Rewrite InternetCrackUrlA to properly handle errors.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
82d413d96d
commit
f1a8c8ae0a
|
@ -1507,168 +1507,122 @@ static BOOL set_url_component(WCHAR **component, DWORD *component_length, const
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
static BOOL set_url_component_WtoA(const WCHAR *comp_w, DWORD length, const WCHAR *url_w, char **comp, DWORD *ret_length,
|
||||||
* ConvertUrlComponentValue (Internal)
|
const char *url_a)
|
||||||
*
|
|
||||||
* Helper function for InternetCrackUrlA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void ConvertUrlComponentValue(LPSTR* lppszComponent, LPDWORD dwComponentLen,
|
|
||||||
LPWSTR lpwszComponent, DWORD dwwComponentLen,
|
|
||||||
LPCSTR lpszStart, LPCWSTR lpwszStart)
|
|
||||||
{
|
{
|
||||||
TRACE("%p %d %p %d %p %p\n", *lppszComponent, *dwComponentLen, lpwszComponent, dwwComponentLen, lpszStart, lpwszStart);
|
size_t size, ret_size = *ret_length;
|
||||||
if (*dwComponentLen != 0)
|
|
||||||
{
|
|
||||||
DWORD nASCIILength=WideCharToMultiByte(CP_ACP,0,lpwszComponent,dwwComponentLen,NULL,0,NULL,NULL);
|
|
||||||
if (*lppszComponent == NULL)
|
|
||||||
{
|
|
||||||
if (lpwszComponent)
|
|
||||||
{
|
|
||||||
int offset = WideCharToMultiByte(CP_ACP, 0, lpwszStart, lpwszComponent-lpwszStart, NULL, 0, NULL, NULL);
|
|
||||||
*lppszComponent = (LPSTR)lpszStart + offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*lppszComponent = NULL;
|
|
||||||
|
|
||||||
*dwComponentLen = nASCIILength;
|
if (!*ret_length)
|
||||||
}
|
return TRUE;
|
||||||
else
|
size = WideCharToMultiByte(CP_ACP, 0, comp_w, length, NULL, 0, NULL, NULL);
|
||||||
{
|
|
||||||
DWORD ncpylen = min((*dwComponentLen)-1, nASCIILength);
|
if (!*comp) {
|
||||||
WideCharToMultiByte(CP_ACP,0,lpwszComponent,dwwComponentLen,*lppszComponent,ncpylen+1,NULL,NULL);
|
*comp = comp_w ? (char*)url_a + WideCharToMultiByte(CP_ACP, 0, url_w, comp_w-url_w, NULL, 0, NULL, NULL) : NULL;
|
||||||
(*lppszComponent)[ncpylen]=0;
|
*ret_length = size;
|
||||||
*dwComponentLen = ncpylen;
|
return TRUE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (size+1 > ret_size) {
|
||||||
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
*ret_length = size+1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret_length = size;
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, comp_w, length, *comp, ret_size-1, NULL, NULL);
|
||||||
|
(*comp)[size] = 0;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL set_url_component_AtoW(const char *comp_a, DWORD len_a, WCHAR **comp_w, DWORD *len_w, WCHAR **buf)
|
||||||
|
{
|
||||||
|
*len_w = len_a;
|
||||||
|
|
||||||
|
if(!comp_a) {
|
||||||
|
*comp_w = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(*comp_w = *buf = heap_alloc(len_a*sizeof(WCHAR)))) {
|
||||||
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* InternetCrackUrlA (WININET.@)
|
* InternetCrackUrlA (WININET.@)
|
||||||
*
|
*
|
||||||
* See InternetCrackUrlW.
|
* See InternetCrackUrlW.
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags,
|
BOOL WINAPI InternetCrackUrlA(const char *url, DWORD url_length, DWORD flags, URL_COMPONENTSA *ret_comp)
|
||||||
LPURL_COMPONENTSA lpUrlComponents)
|
|
||||||
{
|
{
|
||||||
DWORD nLength;
|
WCHAR *host = NULL, *user = NULL, *pass = NULL, *path = NULL, *scheme = NULL, *extra = NULL;
|
||||||
URL_COMPONENTSW UCW;
|
URL_COMPONENTSW comp;
|
||||||
BOOL ret = FALSE;
|
WCHAR *url_w;
|
||||||
WCHAR *lpwszUrl, *hostname = NULL, *username = NULL, *password = NULL, *path = NULL,
|
BOOL ret;
|
||||||
*scheme = NULL, *extra = NULL;
|
|
||||||
|
|
||||||
TRACE("(%s %u %x %p)\n",
|
TRACE("(%s %u %x %p)\n", url_length ? debugstr_an(url, url_length) : debugstr_a(url), url_length, flags, ret_comp);
|
||||||
lpszUrl ? debugstr_an(lpszUrl, dwUrlLength ? dwUrlLength : strlen(lpszUrl)) : "(null)",
|
|
||||||
dwUrlLength, dwFlags, lpUrlComponents);
|
|
||||||
|
|
||||||
if (!lpszUrl || !*lpszUrl || !lpUrlComponents ||
|
if (!url || !*url || !ret_comp || ret_comp->dwStructSize != sizeof(URL_COMPONENTSA)) {
|
||||||
lpUrlComponents->dwStructSize != sizeof(URL_COMPONENTSA))
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
{
|
return FALSE;
|
||||||
INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dwUrlLength<=0)
|
|
||||||
dwUrlLength=-1;
|
|
||||||
nLength=MultiByteToWideChar(CP_ACP,0,lpszUrl,dwUrlLength,NULL,0);
|
|
||||||
|
|
||||||
/* if dwUrlLength=-1 then nLength includes null but length to
|
|
||||||
InternetCrackUrlW should not include it */
|
|
||||||
if (dwUrlLength == -1) nLength--;
|
|
||||||
|
|
||||||
lpwszUrl = heap_alloc((nLength + 1) * sizeof(WCHAR));
|
|
||||||
MultiByteToWideChar(CP_ACP,0,lpszUrl,dwUrlLength,lpwszUrl,nLength + 1);
|
|
||||||
lpwszUrl[nLength] = '\0';
|
|
||||||
|
|
||||||
memset(&UCW,0,sizeof(UCW));
|
|
||||||
UCW.dwStructSize = sizeof(URL_COMPONENTSW);
|
|
||||||
if (lpUrlComponents->dwHostNameLength)
|
|
||||||
{
|
|
||||||
UCW.dwHostNameLength = lpUrlComponents->dwHostNameLength;
|
|
||||||
if (lpUrlComponents->lpszHostName)
|
|
||||||
{
|
|
||||||
hostname = heap_alloc(UCW.dwHostNameLength * sizeof(WCHAR));
|
|
||||||
UCW.lpszHostName = hostname;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (lpUrlComponents->dwUserNameLength)
|
|
||||||
{
|
|
||||||
UCW.dwUserNameLength = lpUrlComponents->dwUserNameLength;
|
|
||||||
if (lpUrlComponents->lpszUserName)
|
|
||||||
{
|
|
||||||
username = heap_alloc(UCW.dwUserNameLength * sizeof(WCHAR));
|
|
||||||
UCW.lpszUserName = username;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lpUrlComponents->dwPasswordLength)
|
|
||||||
{
|
|
||||||
UCW.dwPasswordLength = lpUrlComponents->dwPasswordLength;
|
|
||||||
if (lpUrlComponents->lpszPassword)
|
|
||||||
{
|
|
||||||
password = heap_alloc(UCW.dwPasswordLength * sizeof(WCHAR));
|
|
||||||
UCW.lpszPassword = password;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lpUrlComponents->dwUrlPathLength)
|
|
||||||
{
|
|
||||||
UCW.dwUrlPathLength = lpUrlComponents->dwUrlPathLength;
|
|
||||||
if (lpUrlComponents->lpszUrlPath)
|
|
||||||
{
|
|
||||||
path = heap_alloc(UCW.dwUrlPathLength * sizeof(WCHAR));
|
|
||||||
UCW.lpszUrlPath = path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lpUrlComponents->dwSchemeLength)
|
|
||||||
{
|
|
||||||
UCW.dwSchemeLength = lpUrlComponents->dwSchemeLength;
|
|
||||||
if (lpUrlComponents->lpszScheme)
|
|
||||||
{
|
|
||||||
scheme = heap_alloc(UCW.dwSchemeLength * sizeof(WCHAR));
|
|
||||||
UCW.lpszScheme = scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lpUrlComponents->dwExtraInfoLength)
|
|
||||||
{
|
|
||||||
UCW.dwExtraInfoLength = lpUrlComponents->dwExtraInfoLength;
|
|
||||||
if (lpUrlComponents->lpszExtraInfo)
|
|
||||||
{
|
|
||||||
extra = heap_alloc(UCW.dwExtraInfoLength * sizeof(WCHAR));
|
|
||||||
UCW.lpszExtraInfo = extra;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((ret = InternetCrackUrlW(lpwszUrl, nLength, dwFlags, &UCW)))
|
|
||||||
{
|
|
||||||
ConvertUrlComponentValue(&lpUrlComponents->lpszHostName, &lpUrlComponents->dwHostNameLength,
|
|
||||||
UCW.lpszHostName, UCW.dwHostNameLength, lpszUrl, lpwszUrl);
|
|
||||||
ConvertUrlComponentValue(&lpUrlComponents->lpszUserName, &lpUrlComponents->dwUserNameLength,
|
|
||||||
UCW.lpszUserName, UCW.dwUserNameLength, lpszUrl, lpwszUrl);
|
|
||||||
ConvertUrlComponentValue(&lpUrlComponents->lpszPassword, &lpUrlComponents->dwPasswordLength,
|
|
||||||
UCW.lpszPassword, UCW.dwPasswordLength, lpszUrl, lpwszUrl);
|
|
||||||
ConvertUrlComponentValue(&lpUrlComponents->lpszUrlPath, &lpUrlComponents->dwUrlPathLength,
|
|
||||||
UCW.lpszUrlPath, UCW.dwUrlPathLength, lpszUrl, lpwszUrl);
|
|
||||||
ConvertUrlComponentValue(&lpUrlComponents->lpszScheme, &lpUrlComponents->dwSchemeLength,
|
|
||||||
UCW.lpszScheme, UCW.dwSchemeLength, lpszUrl, lpwszUrl);
|
|
||||||
ConvertUrlComponentValue(&lpUrlComponents->lpszExtraInfo, &lpUrlComponents->dwExtraInfoLength,
|
|
||||||
UCW.lpszExtraInfo, UCW.dwExtraInfoLength, lpszUrl, lpwszUrl);
|
|
||||||
|
|
||||||
lpUrlComponents->nScheme = UCW.nScheme;
|
comp.dwStructSize = sizeof(comp);
|
||||||
lpUrlComponents->nPort = UCW.nPort;
|
|
||||||
|
|
||||||
TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", debugstr_a(lpszUrl),
|
ret = set_url_component_AtoW(ret_comp->lpszHostName, ret_comp->dwHostNameLength,
|
||||||
debugstr_an(lpUrlComponents->lpszScheme, lpUrlComponents->dwSchemeLength),
|
&comp.lpszHostName, &comp.dwHostNameLength, &host)
|
||||||
debugstr_an(lpUrlComponents->lpszHostName, lpUrlComponents->dwHostNameLength),
|
&& set_url_component_AtoW(ret_comp->lpszUserName, ret_comp->dwUserNameLength,
|
||||||
debugstr_an(lpUrlComponents->lpszUrlPath, lpUrlComponents->dwUrlPathLength),
|
&comp.lpszUserName, &comp.dwUserNameLength, &user)
|
||||||
debugstr_an(lpUrlComponents->lpszExtraInfo, lpUrlComponents->dwExtraInfoLength));
|
&& set_url_component_AtoW(ret_comp->lpszPassword, ret_comp->dwPasswordLength,
|
||||||
}
|
&comp.lpszPassword, &comp.dwPasswordLength, &pass)
|
||||||
heap_free(lpwszUrl);
|
&& set_url_component_AtoW(ret_comp->lpszUrlPath, ret_comp->dwUrlPathLength,
|
||||||
heap_free(hostname);
|
&comp.lpszUrlPath, &comp.dwUrlPathLength, &path)
|
||||||
heap_free(username);
|
&& set_url_component_AtoW(ret_comp->lpszScheme, ret_comp->dwSchemeLength,
|
||||||
heap_free(password);
|
&comp.lpszScheme, &comp.dwSchemeLength, &scheme)
|
||||||
heap_free(path);
|
&& set_url_component_AtoW(ret_comp->lpszExtraInfo, ret_comp->dwExtraInfoLength,
|
||||||
heap_free(scheme);
|
&comp.lpszExtraInfo, &comp.dwExtraInfoLength, &extra);
|
||||||
heap_free(extra);
|
|
||||||
return ret;
|
if(ret && !(url_w = heap_strndupAtoW(url, url_length ? url_length : -1, &url_length))) {
|
||||||
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret && (ret = InternetCrackUrlW(url_w, url_length, flags, &comp))) {
|
||||||
|
ret_comp->nScheme = comp.nScheme;
|
||||||
|
ret_comp->nPort = comp.nPort;
|
||||||
|
|
||||||
|
ret = set_url_component_WtoA(comp.lpszHostName, comp.dwHostNameLength, url_w,
|
||||||
|
&ret_comp->lpszHostName, &ret_comp->dwHostNameLength, url)
|
||||||
|
&& set_url_component_WtoA(comp.lpszUserName, comp.dwUserNameLength, url_w,
|
||||||
|
&ret_comp->lpszUserName, &ret_comp->dwUserNameLength, url)
|
||||||
|
&& set_url_component_WtoA(comp.lpszPassword, comp.dwPasswordLength, url_w,
|
||||||
|
&ret_comp->lpszPassword, &ret_comp->dwPasswordLength, url)
|
||||||
|
&& set_url_component_WtoA(comp.lpszUrlPath, comp.dwUrlPathLength, url_w,
|
||||||
|
&ret_comp->lpszUrlPath, &ret_comp->dwUrlPathLength, url)
|
||||||
|
&& set_url_component_WtoA(comp.lpszScheme, comp.dwSchemeLength, url_w,
|
||||||
|
&ret_comp->lpszScheme, &ret_comp->dwSchemeLength, url)
|
||||||
|
&& set_url_component_WtoA(comp.lpszExtraInfo, comp.dwExtraInfoLength, url_w,
|
||||||
|
&ret_comp->lpszExtraInfo, &ret_comp->dwExtraInfoLength, url);
|
||||||
|
|
||||||
|
if(ret)
|
||||||
|
TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", debugstr_a(url),
|
||||||
|
debugstr_an(ret_comp->lpszScheme, ret_comp->dwSchemeLength),
|
||||||
|
debugstr_an(ret_comp->lpszHostName, ret_comp->dwHostNameLength),
|
||||||
|
debugstr_an(ret_comp->lpszUrlPath, ret_comp->dwUrlPathLength),
|
||||||
|
debugstr_an(ret_comp->lpszExtraInfo, ret_comp->dwExtraInfoLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_free(host);
|
||||||
|
heap_free(user);
|
||||||
|
heap_free(pass);
|
||||||
|
heap_free(path);
|
||||||
|
heap_free(scheme);
|
||||||
|
heap_free(extra);
|
||||||
|
heap_free(url_w);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const WCHAR url_schemes[][7] =
|
static const WCHAR url_schemes[][7] =
|
||||||
|
|
Loading…
Reference in New Issue