kernelbase: Do not parse username, password, and port separately for file URLs in UrlGetPart().
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c2daf4f01e
commit
a110b2e68e
|
@ -72,6 +72,7 @@ struct parsed_url
|
||||||
DWORD port_len; /* [out] size of Port (until "/" or eos) */
|
DWORD port_len; /* [out] size of Port (until "/" or eos) */
|
||||||
const WCHAR *query; /* [out] start of Query */
|
const WCHAR *query; /* [out] start of Query */
|
||||||
DWORD query_len; /* [out] size of Query (until eos) */
|
DWORD query_len; /* [out] size of Query (until eos) */
|
||||||
|
DWORD scheme_number;
|
||||||
};
|
};
|
||||||
|
|
||||||
static WCHAR *heap_strdupAtoW(const char *str)
|
static WCHAR *heap_strdupAtoW(const char *str)
|
||||||
|
@ -4201,10 +4202,14 @@ static void parse_url( const WCHAR *url, struct parsed_url *pl )
|
||||||
if (work < url + 2 || *work != ':') return;
|
if (work < url + 2 || *work != ':') return;
|
||||||
pl->scheme_len = work - pl->scheme;
|
pl->scheme_len = work - pl->scheme;
|
||||||
work++;
|
work++;
|
||||||
|
pl->scheme_number = get_scheme_code(pl->scheme, pl->scheme_len);
|
||||||
if (!is_slash( work[0] ) || !is_slash( work[1] ))
|
if (!is_slash( work[0] ) || !is_slash( work[1] ))
|
||||||
return;
|
return;
|
||||||
|
work += 2;
|
||||||
|
|
||||||
pl->username = work + 2;
|
if (pl->scheme_number != URL_SCHEME_FILE)
|
||||||
|
{
|
||||||
|
pl->username = work;
|
||||||
work = parse_url_element( pl->username, L":@/\\?#" );
|
work = parse_url_element( pl->username, L":@/\\?#" );
|
||||||
pl->username_len = work - pl->username;
|
pl->username_len = work - pl->username;
|
||||||
if (*work == ':')
|
if (*work == ':')
|
||||||
|
@ -4212,12 +4217,16 @@ static void parse_url( const WCHAR *url, struct parsed_url *pl )
|
||||||
pl->password = work + 1;
|
pl->password = work + 1;
|
||||||
work = parse_url_element( pl->password, L"@/\\?#" );
|
work = parse_url_element( pl->password, L"@/\\?#" );
|
||||||
pl->password_len = work - pl->password;
|
pl->password_len = work - pl->password;
|
||||||
if (*work != '@')
|
if (*work == '@')
|
||||||
|
{
|
||||||
|
work++;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* what we just parsed must be the hostname and port
|
/* what we just parsed must be the hostname and port
|
||||||
* so reset pointers and clear then let it parse */
|
* so reset pointers and clear then let it parse */
|
||||||
pl->username_len = pl->password_len = 0;
|
pl->username_len = pl->password_len = 0;
|
||||||
work = pl->username - 1;
|
work = pl->username;
|
||||||
pl->username = pl->password = 0;
|
pl->username = pl->password = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4226,16 +4235,27 @@ static void parse_url( const WCHAR *url, struct parsed_url *pl )
|
||||||
/* no password */
|
/* no password */
|
||||||
pl->password_len = 0;
|
pl->password_len = 0;
|
||||||
pl->password = 0;
|
pl->password = 0;
|
||||||
|
work++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* what was parsed was hostname, so reset pointers and let it parse */
|
/* what was parsed was hostname, so reset pointers and let it parse */
|
||||||
pl->username_len = pl->password_len = 0;
|
pl->username_len = pl->password_len = 0;
|
||||||
work = pl->username - 1;
|
work = pl->username;
|
||||||
pl->username = pl->password = 0;
|
pl->username = pl->password = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pl->hostname = work + 1;
|
pl->hostname = work;
|
||||||
|
if (pl->scheme_number == URL_SCHEME_FILE)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
work = parse_url_element( pl->hostname, L":/\\?#" );
|
work = parse_url_element( pl->hostname, L":/\\?#" );
|
||||||
pl->hostname_len = work - pl->hostname;
|
pl->hostname_len = work - pl->hostname;
|
||||||
|
|
||||||
|
@ -4245,6 +4265,7 @@ static void parse_url( const WCHAR *url, struct parsed_url *pl )
|
||||||
work = parse_url_element( pl->port, L"/\\?#" );
|
work = parse_url_element( pl->port, L"/\\?#" );
|
||||||
pl->port_len = work - pl->port;
|
pl->port_len = work - pl->port;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((pl->query = wcschr( work, '?' )))
|
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)
|
HRESULT WINAPI UrlGetPartW(const WCHAR *url, WCHAR *out, DWORD *out_len, DWORD part, DWORD flags)
|
||||||
{
|
{
|
||||||
DWORD scheme, size, schsize;
|
|
||||||
LPCWSTR addr, schaddr;
|
LPCWSTR addr, schaddr;
|
||||||
struct parsed_url pl;
|
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);
|
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)
|
if (!url || !out || !out_len || !*out_len)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
addr = wcschr(url, ':');
|
|
||||||
if (!addr)
|
|
||||||
scheme = URL_SCHEME_UNKNOWN;
|
|
||||||
else
|
|
||||||
scheme = get_scheme_code(url, addr - url);
|
|
||||||
|
|
||||||
parse_url(url, &pl);
|
parse_url(url, &pl);
|
||||||
|
|
||||||
switch (scheme)
|
switch (pl.scheme_number)
|
||||||
{
|
{
|
||||||
case URL_SCHEME_FILE:
|
|
||||||
case URL_SCHEME_FTP:
|
case URL_SCHEME_FTP:
|
||||||
case URL_SCHEME_GOPHER:
|
case URL_SCHEME_GOPHER:
|
||||||
case URL_SCHEME_HTTP:
|
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:
|
case URL_SCHEME_SNEWS:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case URL_SCHEME_FILE:
|
||||||
|
if (part != URL_PART_SCHEME && part != URL_PART_QUERY && part != URL_PART_HOSTNAME)
|
||||||
|
return E_FAIL;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (part != URL_PART_SCHEME && part != URL_PART_QUERY)
|
if (part != URL_PART_SCHEME && part != URL_PART_QUERY)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
@ -4299,16 +4318,8 @@ HRESULT WINAPI UrlGetPartW(const WCHAR *url, WCHAR *out, DWORD *out_len, DWORD p
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case URL_PART_HOSTNAME:
|
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;
|
addr = pl.hostname;
|
||||||
size = pl.hostname_len;
|
size = pl.hostname_len;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case URL_PART_USERNAME:
|
case URL_PART_USERNAME:
|
||||||
|
@ -4342,7 +4353,7 @@ HRESULT WINAPI UrlGetPartW(const WCHAR *url, WCHAR *out, DWORD *out_len, DWORD p
|
||||||
return E_INVALIDARG;
|
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)
|
if (!pl.scheme || !pl.scheme_len)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
|
@ -596,7 +596,7 @@ static void test_UrlGetPart(void)
|
||||||
DWORD flags;
|
DWORD flags;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
const char *expect;
|
const char *expect;
|
||||||
BOOL todo_hr, todo_result;
|
BOOL todo_hr;
|
||||||
}
|
}
|
||||||
tests[] =
|
tests[] =
|
||||||
{
|
{
|
||||||
|
@ -684,10 +684,10 @@ static void test_UrlGetPart(void)
|
||||||
{"http:///index.html", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:"},
|
{"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, 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://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_USERNAME, 0, E_FAIL},
|
||||||
{"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_PASSWORD, 0, E_FAIL},
|
||||||
{"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_HOSTNAME, 0, S_OK, "foo:bar@localhost:21"},
|
||||||
{"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_PORT, 0, E_FAIL},
|
||||||
{"file://foo:bar@localhost:21/file?query=x", URL_PART_QUERY, 0, S_OK, "query=x"},
|
{"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_HOSTNAME, 0, S_OK, "www.wine hq.org"},
|
||||||
{"http://user:pass 123@www.wine hq.org", URL_PART_PASSWORD, 0, S_OK, "pass 123"},
|
{"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)
|
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);
|
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);
|
ok(size == strlen(buffer), "Got size %lu.\n", size);
|
||||||
if (expect)
|
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));
|
ok(!strcmp(buffer, expect), "Got result %s.\n", debugstr_a(buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -854,7 +854,7 @@ static void test_UrlGetPart(void)
|
||||||
{
|
{
|
||||||
if (expect)
|
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);
|
ok(size == strlen(expect) + 1, "Got size %lu.\n", size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue