Hi.
I have modified my patch about compatibility of InternetCrackUrlA function,to deal with the failed case.
If the pointer member of one component is set to point a buffer,but the length member is not big enough,then the component should not be returned, and the length member is set to the value needed.
And later i'll post the patch for the conformance test.
Bye.
ChangeLog: Fill the nPort field with the corresponding scheme; Fix the path and extrainfo components' parse; Deal with the failed case.
Index: wine/dlls/wininet/internet.c =================================================================== RCS file: /home/wine/wine/dlls/wininet/internet.c,v retrieving revision 1.73 diff -u -r1.73 internet.c --- wine/dlls/wininet/internet.c 30 Dec 2003 19:16:37 -0000 1.73 +++ wine/dlls/wininet/internet.c 28 Feb 2004 10:22:19 -0000 @@ -845,29 +845,28 @@ DWORD nLength; URL_COMPONENTSW UCW; WCHAR* lpwszUrl; + BOOL result; if(dwUrlLength==0) dwUrlLength=strlen(lpszUrl); lpwszUrl=HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(dwUrlLength+1)); memset(lpwszUrl,0,sizeof(WCHAR)*(dwUrlLength+1)); nLength=MultiByteToWideChar(CP_ACP,0,lpszUrl,dwUrlLength,lpwszUrl,dwUrlLength+1); - memset(&UCW,0,sizeof(UCW)); - if(lpUrlComponents->dwHostNameLength!=0) - UCW.dwHostNameLength=1; - if(lpUrlComponents->dwUserNameLength!=0) - UCW.dwUserNameLength=1; - if(lpUrlComponents->dwPasswordLength!=0) - UCW.dwPasswordLength=1; - if(lpUrlComponents->dwUrlPathLength!=0) - UCW.dwUrlPathLength=1; - if(lpUrlComponents->dwSchemeLength!=0) - UCW.dwSchemeLength=1; - if(lpUrlComponents->dwExtraInfoLength!=0) - UCW.dwExtraInfoLength=1; - if(!InternetCrackUrlW(lpwszUrl,nLength,dwFlags,&UCW)) - { - HeapFree(GetProcessHeap(), 0, lpwszUrl); - return FALSE; - } + + memcpy(&UCW,lpUrlComponents,sizeof(UCW)); + if (UCW.lpszScheme && UCW.dwSchemeLength) + UCW.lpszScheme = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(UCW.dwSchemeLength+1)); + if (UCW.lpszHostName && UCW.dwHostNameLength) + UCW.lpszHostName = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(UCW.dwHostNameLength+1)); + if (UCW.lpszUserName && UCW.dwUserNameLength) + UCW.lpszUserName = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(UCW.dwUserNameLength+1)); + if (UCW.lpszPassword && UCW.dwPasswordLength) + UCW.lpszPassword = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(UCW.dwPasswordLength+1)); + if (UCW.lpszUrlPath && UCW.dwUrlPathLength) + UCW.lpszUrlPath = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(UCW.dwUrlPathLength+1)); + if (UCW.lpszExtraInfo && UCW.dwExtraInfoLength) + UCW.lpszExtraInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(UCW.dwExtraInfoLength+1)); + result = InternetCrackUrlW(lpwszUrl,nLength,dwFlags,&UCW); + ConvertUrlComponentValue(&lpUrlComponents->lpszHostName, &lpUrlComponents->dwHostNameLength, UCW.lpszHostName, UCW.dwHostNameLength, lpszUrl, lpwszUrl); @@ -888,7 +887,19 @@ lpszUrl, lpwszUrl); lpUrlComponents->nScheme=UCW.nScheme; lpUrlComponents->nPort=UCW.nPort; + lpUrlComponents->dwSchemeLength=UCW.dwSchemeLength; + lpUrlComponents->dwHostNameLength=UCW.dwHostNameLength; + lpUrlComponents->dwUserNameLength=UCW.dwUserNameLength; + lpUrlComponents->dwPasswordLength=UCW.dwPasswordLength; + lpUrlComponents->dwUrlPathLength=UCW.dwUrlPathLength; + lpUrlComponents->dwExtraInfoLength=UCW.dwExtraInfoLength; HeapFree(GetProcessHeap(), 0, lpwszUrl); + HeapFree(GetProcessHeap(), 0, UCW.lpszScheme); + HeapFree(GetProcessHeap(), 0, UCW.lpszHostName); + HeapFree(GetProcessHeap(), 0, UCW.lpszUserName); + HeapFree(GetProcessHeap(), 0, UCW.lpszPassword); + HeapFree(GetProcessHeap(), 0, UCW.lpszUrlPath); + HeapFree(GetProcessHeap(), 0, UCW.lpszExtraInfo);
TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", lpszUrl, debugstr_an(lpUrlComponents->lpszScheme,lpUrlComponents->dwSchemeLength), @@ -896,7 +907,7 @@ debugstr_an(lpUrlComponents->lpszUrlPath,lpUrlComponents->dwUrlPathLength), debugstr_an(lpUrlComponents->lpszExtraInfo,lpUrlComponents->dwExtraInfoLength));
- return TRUE; + return result; }
/*********************************************************************** @@ -972,10 +983,14 @@ } else { - INT ncpylen = min((*dwComponentLen)-1, len); - strncpyW(*lppszComponent, lpszStart, ncpylen); - (*lppszComponent)[ncpylen] = '\0'; - *dwComponentLen = ncpylen; + if (*dwComponentLen<len+1) { + **lppszComponent = '\0'; + *dwComponentLen = len+1; + return FALSE; + } + strncpyW(*lppszComponent, lpszStart, len); + (*lppszComponent)[len] = '\0'; + *dwComponentLen = len; } }
@@ -999,6 +1014,8 @@ LPWSTR lpszcp = NULL; WCHAR lpszSeparators[3]={';','?',0}; WCHAR lpszSlash[2]={'/',0}; + BOOL result = TRUE; + if(dwUrlLength==0) dwUrlLength=strlenW(lpszUrl);
@@ -1027,12 +1044,12 @@
/* Parse <params> */ lpszParam = strpbrkW(lpszap, lpszSeparators); - if (lpszParam != NULL) + if (lpszParam != NULL && (lpUC->dwExtraInfoLength || lpUC->lpszExtraInfo)) { if (!SetUrlComponentValueW(&lpUC->lpszExtraInfo, &lpUC->dwExtraInfoLength, lpszParam, dwUrlLength-(lpszParam-lpszUrl))) { - return FALSE; + result = FALSE; } }
@@ -1045,7 +1062,7 @@ lpUC->nScheme = GetInternetSchemeW(lpszUrl, lpszcp - lpszUrl); if (!SetUrlComponentValueW(&lpUC->lpszScheme, &lpUC->dwSchemeLength, lpszUrl, lpszcp - lpszUrl)) - return FALSE; + result = FALSE;
/* Eat ':' in protocol. */ lpszcp++; @@ -1112,14 +1129,16 @@ lpszcp++; }
- SetUrlComponentValueW(&lpUC->lpszUserName, &lpUC->dwUserNameLength, - lpszUser, lpszPasswd - lpszUser); + if (!SetUrlComponentValueW(&lpUC->lpszUserName, &lpUC->dwUserNameLength, + lpszUser, lpszPasswd - lpszUser)) + result = FALSE;
if (lpszPasswd != lpszHost) lpszPasswd++; - SetUrlComponentValueW(&lpUC->lpszPassword, &lpUC->dwPasswordLength, + if (!SetUrlComponentValueW(&lpUC->lpszPassword, &lpUC->dwPasswordLength, lpszPasswd == lpszHost ? NULL : lpszPasswd, - lpszHost - lpszPasswd); + lpszHost - lpszPasswd)) + result = FALSE;
lpszcp++; /* Advance to beginning of host */ } @@ -1133,8 +1152,9 @@ entire string up to the first '/' */ if(lpUC->nScheme==INTERNET_SCHEME_RES) { - SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength, - lpszHost, lpszPort - lpszHost); + if (!SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength, + lpszHost, lpszPort - lpszHost)) + result = FALSE; lpUC->nPort = 0; lpszcp=lpszNetLoc; } @@ -1158,12 +1178,29 @@ } else { - SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength, - lpszHost, lpszPort - lpszHost); + if (!SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength, + lpszHost, lpszPort - lpszHost)) + result = FALSE; if (lpszPort != lpszNetLoc) lpUC->nPort = atoiW(++lpszPort); else - lpUC->nPort = 0; + switch(lpUC->nScheme) { + case INTERNET_SCHEME_FTP: + lpUC->nPort = INTERNET_DEFAULT_FTP_PORT; + break; + case INTERNET_SCHEME_HTTPS: + lpUC->nPort = INTERNET_DEFAULT_HTTPS_PORT; + break; + case INTERNET_SCHEME_HTTP: + lpUC->nPort = INTERNET_DEFAULT_HTTP_PORT; + break; + case INTERNET_SCHEME_GOPHER: + lpUC->nPort = INTERNET_DEFAULT_GOPHER_PORT; + break; + default: + lpUC->nPort = 0; + break; + } } } } @@ -1198,7 +1235,7 @@
if (!SetUrlComponentValueW(&lpUC->lpszUrlPath, &lpUC->dwUrlPathLength, lpszcp, len)) - return FALSE; + result = FALSE; } else { @@ -1210,7 +1247,7 @@ debugstr_wn(lpUC->lpszUrlPath,lpUC->dwUrlPathLength), debugstr_wn(lpUC->lpszExtraInfo,lpUC->dwExtraInfoLength));
- return TRUE; + return result; }
/***********************************************************************