From: Leonid Pospelov leonidpospelov.dev@gmail.com
--- dlls/urlmon/tests/misc.c | 148 ++++++++++++++++++++++++++++++++++++++ dlls/urlmon/urlmon_main.c | 44 ++++++++++-- 2 files changed, 187 insertions(+), 5 deletions(-)
diff --git a/dlls/urlmon/tests/misc.c b/dlls/urlmon/tests/misc.c index 4cd64749b1d..acffb30c65a 100644 --- a/dlls/urlmon/tests/misc.c +++ b/dlls/urlmon/tests/misc.c @@ -1774,6 +1774,148 @@ static void test_MkParseDisplayNameEx(void) IBindCtx_Release(bctx); }
+static const WCHAR* generate_long_url_valid() +{ + static WCHAR w[2078]; + wmemset(w, L'd', 2077); + w[2077] = L'\0'; + + WCHAR prefix[4] = L"C:/"; + wcsncpy(w, prefix, sizeof(prefix) / sizeof(WCHAR) - 1); + + return w; +} + +static const WCHAR* generate_long_url_invalid() +{ + static WCHAR w[2079]; + wmemset(w, L'd', 2078); + w[2078] = L'\0'; + + WCHAR prefix[4] = L"C:/"; + wcsncpy(w, prefix, sizeof(prefix) / sizeof(WCHAR) - 1); + + return w; +} + +static const struct { + const WCHAR* url; + HRESULT expected_result; +} url_tests[] = { + {L"",1}, + {L"://",1}, + {L"a",1}, + {L"7",1}, + {L"%%%",1}, + {L"-",1}, + {L")(*&^%$#@!QAZWSXEDCRFVTGBYHNUJMIK<OL>P:?{",1}, + {L"$$$",1}, + {L";",1}, + {L""""",1}, + {L"<>",1}, + {L"???",1}, + {L"ddd",1}, + {L"@|@",1}, + {L"#@|@",1}, + {L"",1}, + {L"vk.com",1}, + {L"https://www.vk.com%22,0%7D, + {L"httpc://www.vk.com",1}, + {L"http://www.vk.com%22,0%7D, + {L"ftp://www.vk.com",0}, + {L"https://www.vk%22,0%7D, + {L"https://www.vk.%22,0%7D, + {L"https://www%22,0%7D, + {L"https://%22,0%7D, + {L"file://",0}, + {L"f://",0}, + {L"o://",0}, + {L"ooo://",1}, + {L"d://",0}, + {L"dd://",1}, + {L"C:/",0}, + {L"C:/ss",0}, + {L"ftp://",0}, + {L"ftf://",1}, + {L"\\Media\Pictures\Worth\1000 words",0}, + {L"\\\\Media\Pictures\Worth\1000 words",0}, + {L"\\\\Media\Pictures\Worth\1000 words<",0}, + {L"\\\\Media\Pictures\Worth\1000 words:",0}, + {L"\\\\Media\Pictures\Worth\1000 words:s",0}, + {L"\\\\Media\Pictures\Worth\1000 words:.",0}, + {L"\\?\D:\Plans\Marshall",1}, + {L"\\.\D:\Projects\Human Genome",0}, + {L"C:",0}, + {L":",1}, + {L".\Manhattan",1}, + {L"..\Plans",1}, + {L"\Pacts",1}, + {L"0:",1}, + {L"\\Work\Hard",0}, + {L"\\192.168.1.15\Hard",0}, + {L"https://www.vk.com%5C1%22,0%7D, + {L"sip://www.vk.co",1}, + {L"sms://www.vk.co",1}, + {generate_long_url_valid(),0}, + {generate_long_url_invalid(),1}, + {L"1:",1}, + {L"/",1}, + {L"\",1}, + {L"irc://www.x.com",1}, + {L"data://www.x.com",1}, + {L"\\&\D:\Plans\Marshall",0}, + {L"\\!\D:\Plans\Marshall",0}, + {L"\\j?j\D:\Plans\Marshall",0}, + {L"\\j?\D:\Plans\Marshall",0}, + {L"\\?j\D:\Plans\Marshall",1}, + {L"http://www.%E4%BE%8B%E5%AD%90.com%22,0%7D, + {L"http://%E4%BE%8B%E5%AD%90.com%22,0%7D, + {L"http://www.example.%E5%9B%BD%E9%99%85%22,0%7D, + {L"http://192.0.2.1%22,0%7D, + {L"https://%5B2001:0db8:85a3:0000:0000:8a2e:0370:7334%5D%22,0%7D, + {L"http://localhost%22,0%7D, + {L"https://localhost:8080%22,0%7D, + {L"https://localhost:80808080%22,0%7D, + {L"https://%5B2001:0db8:85a3:00000000:8a2e:0370:7334%5D%22,0%7D, + {L"http://192.0.2222.1%22,0%7D, + {L"http://www.example.com/a_b%22,0%7D, + {L"http://www.example.com/a%20b%22,0%7D, + {L"http://www.example.com/?a=b&c=d%22,0%7D, + {L"http://www.example.com/#!abc%22,0%7D, + {L"http://www.example.com/#abc%22,0%7D, + {L"mailto:email@example.com",0}, + {L"HTTP://www.EXAMPLE.com",0}, + {L"hTTp://www.exaMple.com",0}, + {L"mk://x",0}, + {L"gopher://host /7a_gopher_selector%09foobar",1}, + {L"http:/",0}, + {L"http:",0}, + {L"http",0}, + {L"htt",1}, + {L"https:/",0}, + {L"https:",0}, + {L"https",0}, + {L"http",0}, + {L"ftp:/",0}, + {L"ftp:",0}, + {L"ftp",0}, + {L"ft",1}, + {L"file:/",0}, + {L"file:",0}, + {L"file",0}, + {L"fil",1}, + {L"mailto:/",0}, + {L"mailto:",0}, + {L"mailto",0}, + {L"mailt",1}, + {L"mk:/",0}, + {L"mk:",0}, + {L"mk",0}, + {L"m",1}, + {L"mkkk",1}, + {L"mkkk:/",1} +}; + static void test_IsValidURL(void) { HRESULT hr; @@ -1790,6 +1932,12 @@ static void test_IsValidURL(void) hr = IsValidURL(bctx, wszHttpWineHQ, 0); ok(hr == S_OK, "Expected S_OK, got %08lx\n", hr);
+ DWORD i; + for(i = 0; i < ARRAY_SIZE(default_feature_tests); ++i) { + hr = IsValidURL(bctx, url_tests[i].url, 0); + ok(hr == url_tests[i].expected_result, "[%d] Expected %08lx, got %08lx\n", i, url_tests[i].expected_result, hr); + } + IBindCtx_Release(bctx); }
diff --git a/dlls/urlmon/urlmon_main.c b/dlls/urlmon/urlmon_main.c index 491313b7cf8..9d303d33926 100644 --- a/dlls/urlmon/urlmon_main.c +++ b/dlls/urlmon/urlmon_main.c @@ -493,6 +493,28 @@ HRESULT WINAPI DllRegisterServerEx(void) return E_FAIL; }
+static BOOL StartsWithProtocol(LPCWSTR url, size_t len, LPCWSTR protocol) +{ + if (!url || !protocol) + return FALSE; + + size_t protocolLen = wcslen(protocol); + + if (len < protocolLen) + return FALSE; + + if (_wcsnicmp(url, protocol, protocolLen) != 0) + return FALSE; + + return len == protocolLen || url[protocolLen] == L':'; +} + +static BOOL IsDriveLetterURL(LPCWSTR url, size_t len) +{ + return (len >= 2 && url[1] == L':' && + ((url[0] >= L'a' && url[0] <= L'z') || (url[0] >= L'A' && url[0] <= L'Z'))); +} + /************************************************************************** * IsValidURL (URLMON.@) * @@ -507,18 +529,30 @@ HRESULT WINAPI DllRegisterServerEx(void) * Success: S_OK. * Failure: S_FALSE. * returns E_INVALIDARG if one or more of the args is invalid. - * - * TODO: - * test functionality against windows to see what a valid URL is. */ HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved) { - FIXME("(%p, %s, %ld): stub\n", pBC, debugstr_w(szURL), dwReserved); + const size_t MAX_URL_SIZE = 2078;
if (dwReserved || !szURL) return E_INVALIDARG;
- return S_OK; + const size_t len = wcslen(szURL); + + if (len >= MAX_URL_SIZE) + return S_FALSE; + + if (StartsWithProtocol(szURL, len, L"https") || + StartsWithProtocol(szURL, len, L"http") || + StartsWithProtocol(szURL, len, L"ftp") || + StartsWithProtocol(szURL, len, L"file") || + StartsWithProtocol(szURL, len, L"mailto") || + StartsWithProtocol(szURL, len, L"mk") || + IsDriveLetterURL(szURL, len) || + PathIsUNCW(szURL)) + return S_OK; + + return S_FALSE; }
/**************************************************************************