Only return it from UrlGetPartA().
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernelbase/path.c | 3 ++- dlls/shlwapi/tests/url.c | 8 ++------ 2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/dlls/kernelbase/path.c b/dlls/kernelbase/path.c index 410d87ce620..be7754dade2 100644 --- a/dlls/kernelbase/path.c +++ b/dlls/kernelbase/path.c @@ -4166,6 +4166,7 @@ HRESULT WINAPI UrlGetPartA(const char *url, char *out, DWORD *out_len, DWORD par len2 = WideCharToMultiByte(CP_ACP, 0, outW, len + 1, out, *out_len, NULL, NULL); *out_len = len2 - 1; heap_free(inW); + if (hr == S_OK && !*out_len) hr = S_FALSE; return hr; }
@@ -4382,7 +4383,7 @@ HRESULT WINAPI UrlGetPartW(const WCHAR *url, WCHAR *out, DWORD *out_len, DWORD p } TRACE("len=%ld %s\n", *out_len, wine_dbgstr_w(out));
- return *out_len ? S_OK : S_FALSE; + return S_OK; }
BOOL WINAPI UrlIsA(const char *url, URLIS Urlis) diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c index 476358c6d45..31581f82847 100644 --- a/dlls/shlwapi/tests/url.c +++ b/dlls/shlwapi/tests/url.c @@ -748,8 +748,6 @@ static void test_UrlGetPart(void) {"telnet://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "telnet:hostname"}, };
- winetest_mute_threshold = 5; - hr = UrlGetPartA(NULL, NULL, NULL, URL_PART_SCHEME, 0); ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
@@ -837,7 +835,7 @@ static void test_UrlGetPart(void) size = 1; wcscpy(bufferW, L"x"); hr = UrlGetPartW(urlW, bufferW, &size, part, flags); - todo_wine_if (tests[i].todo_hr || tests[i].hr == S_FALSE) + todo_wine_if (tests[i].todo_hr) { if (tests[i].hr == S_OK) ok(hr == E_POINTER, "Got hr %#lx.\n", hr); @@ -870,7 +868,7 @@ static void test_UrlGetPart(void) size = ARRAY_SIZE(bufferW); wcscpy(bufferW, L"x"); hr = UrlGetPartW(urlW, bufferW, &size, part, flags); - todo_wine_if ((tests[i].hr == S_FALSE || tests[i].todo_hr) && strcmp(url, "a:") && strcmp(url, "0:")) + todo_wine_if (tests[i].todo_hr && strcmp(url, "a:") && strcmp(url, "0:")) ok(hr == (tests[i].hr == S_FALSE ? S_OK : tests[i].hr), "Got hr %#lx.\n", hr); if (SUCCEEDED(hr)) { @@ -886,8 +884,6 @@ static void test_UrlGetPart(void)
winetest_pop_context(); } - - winetest_mute_threshold = 42; }
/* ########################### */
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernelbase/path.c | 2 +- dlls/shlwapi/tests/url.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/kernelbase/path.c b/dlls/kernelbase/path.c index be7754dade2..917fd644770 100644 --- a/dlls/kernelbase/path.c +++ b/dlls/kernelbase/path.c @@ -4198,7 +4198,7 @@ static void parse_url( const WCHAR *url, struct parsed_url *pl ) memset(pl, 0, sizeof(*pl)); pl->scheme = url; work = parse_scheme( pl->scheme ); - if (*work != ':') return; + if (work < url + 2 || *work != ':') return; pl->scheme_len = work - pl->scheme; work++; if (!is_slash( work[0] ) || !is_slash( work[1] )) diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c index 31581f82847..fb3df96e13d 100644 --- a/dlls/shlwapi/tests/url.c +++ b/dlls/shlwapi/tests/url.c @@ -714,8 +714,8 @@ static void test_UrlGetPart(void) {"scheme :", URL_PART_SCHEME, 0, S_FALSE, ""}, {"sch eme:", URL_PART_SCHEME, 0, S_FALSE, ""}, {":", URL_PART_SCHEME, 0, S_FALSE, ""}, - {"a:", URL_PART_SCHEME, 0, S_FALSE, "", .todo_hr = TRUE}, - {"0:", URL_PART_SCHEME, 0, S_FALSE, "", .todo_hr = TRUE}, + {"a:", URL_PART_SCHEME, 0, S_FALSE, ""}, + {"0:", URL_PART_SCHEME, 0, S_FALSE, ""}, {"ab:", URL_PART_SCHEME, 0, S_OK, "ab"},
{"about://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, @@ -868,7 +868,7 @@ static void test_UrlGetPart(void) size = ARRAY_SIZE(bufferW); wcscpy(bufferW, L"x"); hr = UrlGetPartW(urlW, bufferW, &size, part, flags); - todo_wine_if (tests[i].todo_hr && strcmp(url, "a:") && strcmp(url, "0:")) + todo_wine_if (tests[i].todo_hr) ok(hr == (tests[i].hr == S_FALSE ? S_OK : tests[i].hr), "Got hr %#lx.\n", hr); if (SUCCEEDED(hr)) {
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernelbase/path.c | 109 +++++++++++++++++++++------------------ dlls/shlwapi/tests/url.c | 16 +++--- 2 files changed, 68 insertions(+), 57 deletions(-)
diff --git a/dlls/kernelbase/path.c b/dlls/kernelbase/path.c index 917fd644770..fbe4728efda 100644 --- a/dlls/kernelbase/path.c +++ b/dlls/kernelbase/path.c @@ -72,6 +72,7 @@ struct parsed_url DWORD port_len; /* [out] size of Port (until "/" or eos) */ const WCHAR *query; /* [out] start of Query */ DWORD query_len; /* [out] size of Query (until eos) */ + DWORD scheme_number; };
static WCHAR *heap_strdupAtoW(const char *str) @@ -4201,49 +4202,69 @@ static void parse_url( const WCHAR *url, struct parsed_url *pl ) if (work < url + 2 || *work != ':') return; pl->scheme_len = work - pl->scheme; work++; + pl->scheme_number = get_scheme_code(pl->scheme, pl->scheme_len); if (!is_slash( work[0] ) || !is_slash( work[1] )) return; + work += 2;
- pl->username = work + 2; - work = parse_url_element( pl->username, L":@/\?#" ); - pl->username_len = work - pl->username; - if (*work == ':') + if (pl->scheme_number != URL_SCHEME_FILE) { - pl->password = work + 1; - work = parse_url_element( pl->password, L"@/\?#" ); - pl->password_len = work - pl->password; - if (*work != '@') + pl->username = work; + work = parse_url_element( pl->username, L":@/\?#" ); + pl->username_len = work - pl->username; + if (*work == ':') { - /* what we just parsed must be the hostname and port - * so reset pointers and clear then let it parse */ + pl->password = work + 1; + work = parse_url_element( pl->password, L"@/\?#" ); + pl->password_len = work - pl->password; + if (*work == '@') + { + work++; + } + else + { + /* what we just parsed must be the hostname and port + * so reset pointers and clear then let it parse */ + pl->username_len = pl->password_len = 0; + work = pl->username; + pl->username = pl->password = 0; + } + } + else if (*work == '@') + { + /* no password */ + pl->password_len = 0; + pl->password = 0; + work++; + } + else + { + /* what was parsed was hostname, so reset pointers and let it parse */ pl->username_len = pl->password_len = 0; - work = pl->username - 1; + work = pl->username; pl->username = pl->password = 0; } } - else if (*work == '@') + + pl->hostname = work; + if (pl->scheme_number == URL_SCHEME_FILE) { - /* no password */ - pl->password_len = 0; - pl->password = 0; + work = parse_url_element( pl->hostname, L"/\?#" ); + pl->hostname_len = work - pl->hostname; + if (pl->hostname_len >= 2 && pl->hostname[1] == ':') + pl->hostname_len = 0; } else { - /* what was parsed was hostname, so reset pointers and let it parse */ - pl->username_len = pl->password_len = 0; - work = pl->username - 1; - pl->username = pl->password = 0; - } + work = parse_url_element( pl->hostname, L":/\?#" ); + pl->hostname_len = work - pl->hostname;
- pl->hostname = work + 1; - work = parse_url_element( pl->hostname, L":/\?#" ); - pl->hostname_len = work - pl->hostname; - - if (*work == ':') - { - pl->port = work + 1; - work = parse_url_element( pl->port, L"/\?#" ); - pl->port_len = work - pl->port; + if (*work == ':') + { + pl->port = work + 1; + work = parse_url_element( pl->port, L"/\?#" ); + pl->port_len = work - pl->port; + } }
if ((pl->query = wcschr( work, '?' ))) @@ -4255,26 +4276,19 @@ static void parse_url( const WCHAR *url, struct parsed_url *pl )
HRESULT WINAPI UrlGetPartW(const WCHAR *url, WCHAR *out, DWORD *out_len, DWORD part, DWORD flags) { - DWORD scheme, size, schsize; LPCWSTR addr, schaddr; struct parsed_url pl; + DWORD size, schsize;
TRACE("%s, %p, %p(%ld), %#lx, %#lx\n", wine_dbgstr_w(url), out, out_len, *out_len, part, flags);
if (!url || !out || !out_len || !*out_len) return E_INVALIDARG;
- addr = wcschr(url, ':'); - if (!addr) - scheme = URL_SCHEME_UNKNOWN; - else - scheme = get_scheme_code(url, addr - url); - parse_url(url, &pl);
- switch (scheme) + switch (pl.scheme_number) { - case URL_SCHEME_FILE: case URL_SCHEME_FTP: case URL_SCHEME_GOPHER: case URL_SCHEME_HTTP: @@ -4285,6 +4299,11 @@ HRESULT WINAPI UrlGetPartW(const WCHAR *url, WCHAR *out, DWORD *out_len, DWORD p case URL_SCHEME_SNEWS: break;
+ case URL_SCHEME_FILE: + if (part != URL_PART_SCHEME && part != URL_PART_QUERY && part != URL_PART_HOSTNAME) + return E_FAIL; + break; + default: if (part != URL_PART_SCHEME && part != URL_PART_QUERY) return E_FAIL; @@ -4299,16 +4318,8 @@ HRESULT WINAPI UrlGetPartW(const WCHAR *url, WCHAR *out, DWORD *out_len, DWORD p break;
case URL_PART_HOSTNAME: - if (scheme == URL_SCHEME_FILE && (!pl.hostname_len || (pl.hostname_len == 1 && *(pl.hostname + 1) == ':'))) - { - addr = NULL; - size = 0; - } - else - { - addr = pl.hostname; - size = pl.hostname_len; - } + addr = pl.hostname; + size = pl.hostname_len; break;
case URL_PART_USERNAME: @@ -4342,7 +4353,7 @@ HRESULT WINAPI UrlGetPartW(const WCHAR *url, WCHAR *out, DWORD *out_len, DWORD p return E_INVALIDARG; }
- if (flags == URL_PARTFLAG_KEEPSCHEME && scheme != URL_SCHEME_FILE) + if (flags == URL_PARTFLAG_KEEPSCHEME && pl.scheme_number != URL_SCHEME_FILE) { if (!pl.scheme || !pl.scheme_len) return E_FAIL; diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c index fb3df96e13d..7cf7097a9ba 100644 --- a/dlls/shlwapi/tests/url.c +++ b/dlls/shlwapi/tests/url.c @@ -596,7 +596,7 @@ static void test_UrlGetPart(void) DWORD flags; HRESULT hr; const char *expect; - BOOL todo_hr, todo_result; + BOOL todo_hr; } tests[] = { @@ -684,10 +684,10 @@ static void test_UrlGetPart(void) {"http:///index.html", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:"}, {"file://h o s t/c:/windows/file", URL_PART_HOSTNAME, 0, S_OK, "h o s t"}, {"file://h o s t/c:/windows/file", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "h o s t"}, - {"file://foo:bar@localhost:21/file?query=x", URL_PART_USERNAME, 0, E_FAIL, .todo_hr = TRUE}, - {"file://foo:bar@localhost:21/file?query=x", URL_PART_PASSWORD, 0, E_FAIL, .todo_hr = TRUE}, - {"file://foo:bar@localhost:21/file?query=x", URL_PART_HOSTNAME, 0, S_OK, "foo:bar@localhost:21", .todo_result = TRUE}, - {"file://foo:bar@localhost:21/file?query=x", URL_PART_PORT, 0, E_FAIL, .todo_hr = TRUE}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_USERNAME, 0, E_FAIL}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_PASSWORD, 0, E_FAIL}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_HOSTNAME, 0, S_OK, "foo:bar@localhost:21"}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_PORT, 0, E_FAIL}, {"file://foo:bar@localhost:21/file?query=x", URL_PART_QUERY, 0, S_OK, "query=x"}, {"http://user:pass 123@www.wine hq.org", URL_PART_HOSTNAME, 0, S_OK, "www.wine hq.org"}, {"http://user:pass 123@www.wine hq.org", URL_PART_PASSWORD, 0, S_OK, "pass 123"}, @@ -799,7 +799,7 @@ static void test_UrlGetPart(void) { if (expect) { - todo_wine_if (tests[i].todo_hr || tests[i].todo_result) + todo_wine_if (tests[i].todo_hr) ok(size == strlen(expect) + 1, "Got size %lu.\n", size); } } @@ -820,7 +820,7 @@ static void test_UrlGetPart(void) ok(size == strlen(buffer), "Got size %lu.\n", size); if (expect) { - todo_wine_if (tests[i].todo_hr || tests[i].todo_result) + todo_wine_if (tests[i].todo_hr) ok(!strcmp(buffer, expect), "Got result %s.\n", debugstr_a(buffer)); } } @@ -854,7 +854,7 @@ static void test_UrlGetPart(void) { if (expect) { - todo_wine_if (tests[i].todo_hr || tests[i].todo_result) + todo_wine_if (tests[i].todo_hr) ok(size == strlen(expect) + 1, "Got size %lu.\n", size); } }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernelbase/path.c | 4 +++ dlls/shlwapi/tests/url.c | 59 ++++++++++------------------------------ 2 files changed, 19 insertions(+), 44 deletions(-)
diff --git a/dlls/kernelbase/path.c b/dlls/kernelbase/path.c index fbe4728efda..7eda9bd483c 100644 --- a/dlls/kernelbase/path.c +++ b/dlls/kernelbase/path.c @@ -4204,7 +4204,11 @@ static void parse_url( const WCHAR *url, struct parsed_url *pl ) work++; pl->scheme_number = get_scheme_code(pl->scheme, pl->scheme_len); if (!is_slash( work[0] ) || !is_slash( work[1] )) + { + if (pl->scheme_number != URL_SCHEME_FILE) + pl->scheme_number = URL_SCHEME_UNKNOWN; return; + } work += 2;
if (pl->scheme_number != URL_SCHEME_FILE) diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c index 7cf7097a9ba..6957e244213 100644 --- a/dlls/shlwapi/tests/url.c +++ b/dlls/shlwapi/tests/url.c @@ -596,7 +596,6 @@ static void test_UrlGetPart(void) DWORD flags; HRESULT hr; const char *expect; - BOOL todo_hr; } tests[] = { @@ -657,8 +656,8 @@ static void test_UrlGetPart(void) {"http://user@host@q", URL_PART_USERNAME, 0, S_OK, "user"}, {"http://user@host@q", URL_PART_HOSTNAME, 0, S_OK, "host@q"},
- {"http:localhost/index.html", URL_PART_HOSTNAME, 0, E_FAIL, .todo_hr = TRUE}, - {"http:/localhost/index.html", URL_PART_HOSTNAME, 0, E_FAIL, .todo_hr = TRUE}, + {"http:localhost/index.html", URL_PART_HOSTNAME, 0, E_FAIL}, + {"http:/localhost/index.html", URL_PART_HOSTNAME, 0, E_FAIL},
{"http://localhost%5C%5Cindex.html", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, {"http:/\localhost/index.html", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, @@ -780,13 +779,10 @@ static void test_UrlGetPart(void) size = 1; strcpy(buffer, "x"); hr = UrlGetPartA(url, buffer, &size, part, flags); - todo_wine_if (tests[i].todo_hr) - { - if (tests[i].hr == S_OK) - ok(hr == E_POINTER, "Got hr %#lx.\n", hr); - else - ok(hr == tests[i].hr, "Got hr %#lx.\n", hr); - } + if (tests[i].hr == S_OK) + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + else + ok(hr == tests[i].hr, "Got hr %#lx.\n", hr);
if (hr == S_FALSE) { @@ -796,33 +792,20 @@ static void test_UrlGetPart(void) else { if (hr == E_POINTER) - { - if (expect) - { - todo_wine_if (tests[i].todo_hr) - ok(size == strlen(expect) + 1, "Got size %lu.\n", size); - } - } + ok(size == strlen(expect) + 1, "Got size %lu.\n", size); else - { ok(size == 1, "Got size %lu.\n", size); - } ok(!strcmp(buffer, "x"), "Got result %s.\n", debugstr_a(buffer)); }
size = sizeof(buffer); strcpy(buffer, "x"); hr = UrlGetPartA(url, buffer, &size, part, flags); - todo_wine_if (tests[i].todo_hr) - ok(hr == tests[i].hr, "Got hr %#lx.\n", hr); + ok(hr == tests[i].hr, "Got hr %#lx.\n", hr); if (SUCCEEDED(hr)) { ok(size == strlen(buffer), "Got size %lu.\n", size); - if (expect) - { - todo_wine_if (tests[i].todo_hr) - ok(!strcmp(buffer, expect), "Got result %s.\n", debugstr_a(buffer)); - } + ok(!strcmp(buffer, expect), "Got result %s.\n", debugstr_a(buffer)); } else { @@ -835,13 +818,10 @@ static void test_UrlGetPart(void) size = 1; wcscpy(bufferW, L"x"); hr = UrlGetPartW(urlW, bufferW, &size, part, flags); - todo_wine_if (tests[i].todo_hr) - { - if (tests[i].hr == S_OK) - ok(hr == E_POINTER, "Got hr %#lx.\n", hr); - else - ok(hr == (tests[i].hr == S_FALSE ? S_OK : tests[i].hr), "Got hr %#lx.\n", hr); - } + if (tests[i].hr == S_OK) + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + else + ok(hr == (tests[i].hr == S_FALSE ? S_OK : tests[i].hr), "Got hr %#lx.\n", hr);
if (SUCCEEDED(hr)) { @@ -851,25 +831,16 @@ static void test_UrlGetPart(void) else { if (hr == E_POINTER) - { - if (expect) - { - todo_wine_if (tests[i].todo_hr) - ok(size == strlen(expect) + 1, "Got size %lu.\n", size); - } - } + ok(size == strlen(expect) + 1, "Got size %lu.\n", size); else - { ok(size == 1, "Got size %lu.\n", size); - } ok(!wcscmp(bufferW, L"x"), "Got result %s.\n", debugstr_w(bufferW)); }
size = ARRAY_SIZE(bufferW); wcscpy(bufferW, L"x"); hr = UrlGetPartW(urlW, bufferW, &size, part, flags); - todo_wine_if (tests[i].todo_hr) - ok(hr == (tests[i].hr == S_FALSE ? S_OK : tests[i].hr), "Got hr %#lx.\n", hr); + ok(hr == (tests[i].hr == S_FALSE ? S_OK : tests[i].hr), "Got hr %#lx.\n", hr); if (SUCCEEDED(hr)) { ok(size == wcslen(bufferW), "Got size %lu.\n", size);