 
            From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/iertutil/tests/iertutil.c | 265 +++++++++++++++++++++++++++++---- 1 file changed, 233 insertions(+), 32 deletions(-)
diff --git a/dlls/iertutil/tests/iertutil.c b/dlls/iertutil/tests/iertutil.c index 0f77b8a7f28..c7e18f5af18 100644 --- a/dlls/iertutil/tests/iertutil.c +++ b/dlls/iertutil/tests/iertutil.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 Zhiyi Zhang for CodeWeavers + * Copyright 2024-2025 Zhiyi Zhang for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -96,15 +96,160 @@ static void test_IUriRuntimeClassFactory(void)
static void test_IUriRuntimeClass(void) { + static const struct + { + const WCHAR *src; + const WCHAR *RawUri; + const WCHAR *AbsoluteUri; + const WCHAR *DisplayUri; + const WCHAR *Domain; + const WCHAR *Extension; + const WCHAR *Fragment; + const WCHAR *Host; + const WCHAR *Password; + const WCHAR *Path; + const WCHAR *Query; + const WCHAR *SchemeName; + const WCHAR *UserName; + INT32 Port; + BOOL invalid; + } + tests[] = + { + /* Invalid URIs */ + {L"://example.com", .invalid = TRUE}, + {L"//", .invalid = TRUE}, + {L"//a", .invalid = TRUE}, + {L"a", .invalid = TRUE}, + {L"///a", .invalid = TRUE}, + {L"http://www.host.com:port", .invalid = TRUE}, + {L"http://example.com:+80/", .invalid = TRUE}, + {L"http://example.com:-80/", .invalid = TRUE}, + {L"http_s://example.com", .invalid = TRUE}, + {L"/a/b/c/./../../g", .invalid = TRUE}, + {L"mid/content=5/../6", .invalid = TRUE}, + {L"#frag", .invalid = TRUE}, + {L"http://example.com/a%2z", .invalid = TRUE}, + {L"http://example.com/a%z", .invalid = TRUE}, + {L"http://u:p?a@", .invalid = TRUE}, + {L"http://%5B1%5D/", .invalid = TRUE}, + {L"http://%5Bfe80::1ff:fe23:4567:890a%eth0%5D/", .invalid = TRUE}, + {L"http://%5Bfe80::1ff:fe23:4567:890a%25eth0%5D/", .invalid = TRUE}, + /* Valid URIs */ + /* URI syntax tests */ + {L"http:", L"http:", NULL, L"http:", NULL, NULL, NULL, NULL, NULL, NULL, NULL, L"http", NULL, 80}, + {L"http:/", L"http:/", NULL, L"http:/", NULL, NULL, NULL, NULL, NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://u:p@", L"http://u:p@", L"http://u:p@/", L"http:///", NULL, NULL, NULL, NULL, L"p", L"/", NULL, L"http", L"u", 80}, + {L"http://u:p;a@", L"http://u:p;a@", L"http://u:p;a@/", L"http:///", NULL, NULL, NULL, NULL, L"p;a", L"/", NULL, L"http", L"u", 80}, + {L"http://u;a:p@", L"http://u;a:p@", L"http://u;a:p@/", L"http:///", NULL, NULL, NULL, NULL, L"p", L"/", NULL, L"http", L"u;a", 80}, + {L"http://u:p:a@", L"http://u:p:a@", L"http://u:p:a@/", L"http:///", NULL, NULL, NULL, NULL, L"p:a", L"/", NULL, L"http", L"u", 80}, + {L"http://example.com", L"http://example.com", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://example.com/", L"http://example.com/", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://example.com:/", L"http://example.com:/", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://example.com:80/", L"http://example.com:80/", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"https://example.com:443/", L"https://example.com:443/", L"https://example.com/", L"https://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"https", NULL, 443}, + {L"http://example.com/data", L"http://example.com/data", L"http://example.com/data", L"http://example.com/data", L"example.com", NULL, NULL, L"example.com", NULL, L"/data", NULL, L"http", NULL, 80}, + {L"http://example.com/data/", L"http://example.com/data/", L"http://example.com/data/", L"http://example.com/data/", L"example.com", NULL, NULL, L"example.com", NULL, L"/data/", NULL, L"http", NULL, 80}, + {L"http://u:p@example.com/", L"http://u:p@example.com/", L"http://u:p@example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", L"p", L"/", NULL, L"http", L"u", 80}, + {L"http://u@example.com/", L"http://u@example.com/", L"http://u@example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", L"u", 80}, + {L"http://user:@example.com", L"http://user:@example.com", L"http://user:@example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", L"user", 80}, + {L"http://:pass@example.com", L"http://:pass@example.com", L"http://:pass@example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", L"pass", L"/", NULL, L"http", NULL, 80}, + {L"http://:@example.com", L"http://:@example.com", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"1http://example.com", L"1http://example.com", L"1http://example.com/", L"1http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"1http", NULL, -1}, + {L"ahttp://example.com", L"ahttp://example.com", L"ahttp://example.com/", L"ahttp://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"ahttp", NULL, -1}, + {L"http://example.com?q=a?b", L"http://example.com?q=a?b", L"http://example.com/?q=a?b", L"http://example.com/?q=a?b", L"example.com", NULL, NULL, L"example.com", NULL, L"/", L"?q=a?b", L"http", NULL, 80}, + {L"http://example.com?q=a b", L"http://example.com?q=a b", L"http://example.com/?q=a b", L"http://example.com/?q=a b", L"example.com", NULL, NULL, L"example.com", NULL, L"/", L"?q=a b", L"http", NULL, 80}, + {L"http://example.com#a b", L"http://example.com#a b", L"http://example.com/#a b", L"http://example.com/#a b", L"example.com", NULL, L"#a b", L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://a/b/c?d#e", L"http://a/b/c?d#e", L"http://a/b/c?d#e", L"http://a/b/c?d#e", NULL, NULL, L"#e", L"a", NULL, L"/b/c", L"?d", L"http", NULL, 80}, + {L"mailto:John.Doe@example.com", L"mailto:John.Doe@example.com", L"mailto:John.Doe@example.com", L"mailto:John.Doe@example.com", NULL, L".com", NULL, NULL, NULL, L"John.Doe@example.com", NULL, L"mailto", NULL, -1}, + {L"news:comp.infosystems.www.servers.unix", L"news:comp.infosystems.www.servers.unix", L"news:comp.infosystems.www.servers.unix", L"news:comp.infosystems.www.servers.unix", NULL, L".unix", NULL, NULL, NULL, L"comp.infosystems.www.servers.unix", NULL, L"news", NULL, -1}, + {L"tel:+1-816-555-1212", L"tel:+1-816-555-1212", L"tel:+1-816-555-1212", L"tel:+1-816-555-1212", NULL, NULL, NULL, NULL, NULL, L"+1-816-555-1212", NULL, L"tel", NULL, -1}, + {L"telnet://192.0.2.16:80/", L"telnet://192.0.2.16:80/", L"telnet://192.0.2.16:80/", L"telnet://192.0.2.16:80/", NULL, NULL, NULL, L"192.0.2.16", NULL, L"/", NULL, L"telnet", NULL, 80}, + {L"urn:oasis:names:specification:docbook:dtd:xml:4.1.2", L"urn:oasis:names:specification:docbook:dtd:xml:4.1.2", L"urn:oasis:names:specification:docbook:dtd:xml:4.1.2", L"urn:oasis:names:specification:docbook:dtd:xml:4.1.2", NULL, L".2", NULL, NULL, NULL, L"oasis:names:specification:docbook:dtd:xml:4.1.2", NULL, L"urn", NULL, -1}, + {L"urn:ietf:rfc:2648", L"urn:ietf:rfc:2648", L"urn:ietf:rfc:2648", L"urn:ietf:rfc:2648", NULL, NULL, NULL, NULL, NULL, L"ietf:rfc:2648", NULL, L"urn", NULL, -1}, + /* IPv4 hosts */ + {L"http://1/", L"http://1/", L"http://0.0.0.1/", L"http://0.0.0.1/", NULL, NULL, NULL, L"0.0.0.1", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://1.2/", L"http://1.2/", L"http://1.0.0.2/", L"http://1.0.0.2/", NULL, NULL, NULL, L"1.0.0.2", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://1.2.3/", L"http://1.2.3/", L"http://1.2.0.3/", L"http://1.2.0.3/", NULL, NULL, NULL, L"1.2.0.3", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://1.2.3.4/", L"http://1.2.3.4/", L"http://1.2.3.4/", L"http://1.2.3.4/", NULL, NULL, NULL, L"1.2.3.4", NULL, L"/", NULL, L"http", NULL, 80}, + /* IPv6 hosts */ + {L"http://%5B::1%5D/", L"http://%5B::1%5D/", L"http://%5B::1%5D/", L"http://%5B::1%5D/", NULL, NULL, NULL, L"::1", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://%5B::1%5D:8080/", L"http://%5B::1%5D:8080/", L"http://%5B::1%5D:8080/", L"http://%5B::1%5D:8080/", NULL, NULL, NULL, L"::1", NULL, L"/", NULL, L"http", NULL, 8080}, + {L"http://%5B::ffff:127.0.0.1%5D/", L"http://%5B::ffff:127.0.0.1%5D/", L"http://%5B::ffff:127.0.0.1%5D/", L"http://%5B::ffff:127.0.0.1%5D/", NULL, NULL, NULL, L"::ffff:127.0.0.1", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://%5B2001:db8::7%5D/", L"http://%5B2001:db8::7%5D/", L"http://%5B2001:db8::7%5D/", L"http://%5B2001:db8::7%5D/", NULL, NULL, NULL, L"2001:db8::7", NULL, L"/", NULL, L"http", NULL, 80}, + /* Domain. Domain is the registrable domain name, which is the effective top-level domain plus one */ + {L"http://www.example.com", L"http://www.example.com", L"http://www.example.com/", L"http://www.example.com/", L"example.com", NULL, NULL, L"www.example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://www.github.io", L"http://www.github.io", L"http://www.github.io/", L"http://www.github.io/", L"www.github.io", NULL, NULL, L"www.github.io", NULL, L"/", NULL, L"http", NULL, 80}, + /* Default ports */ + {L"ftp://", L"ftp://", L"ftp:///", L"ftp:///", NULL, NULL, NULL, NULL, NULL, L"/", NULL, L"ftp", NULL, 21}, + {L"telnet://", L"telnet://", L"telnet:///", L"telnet:///", NULL, NULL, NULL, NULL, NULL, L"/", NULL, L"telnet", NULL, 23}, + {L"http://", L"http://", L"http:///", L"http:///", NULL, NULL, NULL, NULL, NULL, L"/", NULL, L"http", NULL, 80}, + {L"https://", L"https://", L"https:///", L"https:///", NULL, NULL, NULL, NULL, NULL, L"/", NULL, L"https", NULL, 443}, + /* Extension */ + {L"http://example.com/.txt", L"http://example.com/.txt", L"http://example.com/.txt", L"http://example.com/.txt", L"example.com", L".txt", NULL, L"example.com", NULL, L"/.txt", NULL, L"http", NULL, 80}, + {L"http://example.com/1.txt", L"http://example.com/1.txt", L"http://example.com/1.txt", L"http://example.com/1.txt", L"example.com", L".txt", NULL, L"example.com", NULL, L"/1.txt", NULL, L"http", NULL, 80}, + {L"http://example.com/1..txt", L"http://example.com/1..txt", L"http://example.com/1..txt", L"http://example.com/1..txt", L"example.com", L".txt", NULL, L"example.com", NULL, L"/1..txt", NULL, L"http", NULL, 80}, + {L"http://example.com/1.2.txt", L"http://example.com/1.2.txt", L"http://example.com/1.2.txt", L"http://example.com/1.2.txt", L"example.com", L".txt", NULL, L"example.com", NULL, L"/1.2.txt", NULL, L"http", NULL, 80}, + /* Backslash normalization */ + {L"dummy://a\b//c\d?e\f#g\h", L"dummy://a\b//c\d?e\f#g\h", L"dummy://a\b//c\d?e\f#g\h", L"dummy://a\b//c\d?e\f#g\h", NULL, NULL, L"#g\h", L"a\b", NULL, L"//c\d", L"?e\f", L"dummy", NULL, -1}, + {L"http://a%5C%5Cb//c%5C%5Cd?e%5C%5Cf#g%5C%5Ch", L"http://a%5C%5Cb//c%5C%5Cd?e%5C%5Cf#g%5C%5Ch", L"http://a/b//c/d?e%5C%5Cf#g%5C%5Ch", L"http://a/b//c/d?e%5C%5Cf#g%5C%5Ch", NULL, NULL, L"#g\h", L"a", NULL, L"/b//c/d", L"?e\f", L"http", NULL, 80}, + {L"https://a%5C%5Cb//c%5C%5Cd?e%5C%5Cf#g%5C%5Ch", L"https://a%5C%5Cb//c%5C%5Cd?e%5C%5Cf#g%5C%5Ch", L"https://a/b//c/d?e%5C%5Cf#g%5C%5Ch", L"https://a/b//c/d?e%5C%5Cf#g%5C%5Ch", NULL, NULL, L"#g\h", L"a", NULL, L"/b//c/d", L"?e\f", L"https", NULL, 443}, + {L"ftp://a\b//c\d?e\f#g\h", L"ftp://a\b//c\d?e\f#g\h", L"ftp://a/b//c/d?e\f#g\h", L"ftp://a/b//c/d?e\f#g\h", NULL, NULL, L"#g\h", L"a", NULL, L"/b//c/d", L"?e\f", L"ftp", NULL, 21}, + {L"file://\sample\sample.bundle", L"file://\sample\sample.bundle", L"file:///sample/sample.bundle", L"file:///sample/sample.bundle", NULL, L".bundle", NULL, NULL, NULL, L"/sample/sample.bundle", NULL, L"file", NULL, -1}, + /* Dot segments removal */ + {L"http://example.com/.", L"http://example.com/.", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://example.com/..", L"http://example.com/..", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://example.com/...", L"http://example.com/...", L"http://example.com/...", L"http://example.com/...", L"example.com", L".", NULL, L"example.com", NULL, L"/...", NULL, L"http", NULL, 80}, + {L"http://example.com/a/.", L"http://example.com/a/.", L"http://example.com/a/", L"http://example.com/a/", L"example.com", NULL, NULL, L"example.com", NULL, L"/a/", NULL, L"http", NULL, 80}, + {L"http://example.com/a/..", L"http://example.com/a/..", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://example.com/a/b/../../c", L"http://example.com/a/b/../../c", L"http://example.com/c", L"http://example.com/c", L"example.com", NULL, NULL, L"example.com", NULL, L"/c", NULL, L"http", NULL, 80}, + {L"http://example.com/a/b/.././c", L"http://example.com/a/b/.././c", L"http://example.com/a/c", L"http://example.com/a/c", L"example.com", NULL, NULL, L"example.com", NULL, L"/a/c", NULL, L"http", NULL, 80}, + {L"http://example.com/a/b/..", L"http://example.com/a/b/..", L"http://example.com/a/", L"http://example.com/a/", L"example.com", NULL, NULL, L"example.com", NULL, L"/a/", NULL, L"http", NULL, 80}, + {L"http://example.com/a/b/.", L"http://example.com/a/b/.", L"http://example.com/a/b/", L"http://example.com/a/b/", L"example.com", NULL, NULL, L"example.com", NULL, L"/a/b/", NULL, L"http", NULL, 80}, + /* Implicit file scheme */ + {L"a:", L"a:", L"file:///a:", L"file:///a:", NULL, NULL, NULL, NULL, NULL, L"/a:", NULL, L"file", NULL, -1}, + {L"A:", L"A:", L"file:///A:", L"file:///A:", NULL, NULL, NULL, NULL, NULL, L"/A:", NULL, L"file", NULL, -1}, + {L"a:/", L"a:/", L"file:///a:/", L"file:///a:/", NULL, NULL, NULL, NULL, NULL, L"/a:/", NULL, L"file", NULL, -1}, + {L"z:/", L"z:/", L"file:///z:/", L"file:///z:/", NULL, NULL, NULL, NULL, NULL, L"/z:/", NULL, L"file", NULL, -1}, + {L"a://", L"a://", L"file:///a://", L"file:///a://", NULL, NULL, NULL, NULL, NULL, L"/a://", NULL, L"file", NULL, -1}, + {L"a:b/c", L"a:b/c", L"file:///a:b/c", L"file:///a:b/c", NULL, NULL, NULL, NULL, NULL, L"/a:b/c", NULL, L"file", NULL, -1}, + {L"ab:c/d", L"ab:c/d", L"ab:c/d", L"ab:c/d", NULL, NULL, NULL, NULL, NULL, L"c/d", NULL, L"ab", NULL, -1}, + /* White spaces */ + {L"http:// example.com/", L"http:// example.com/", L"http://%20example.com/", L"http://%20example.com/", L"%20example.com", NULL, NULL, L"%20example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://%5Ctexample.com/", L"http://example.com/", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://%5Crexample.com/", L"http://example.com/", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"http://%5Cnexample.com/", L"http://example.com/", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + /* Percent encoding */ + {L"http://example.com/a%20b", L"http://example.com/a%20b", L"http://example.com/a%20b", L"http://example.com/a%20b", L"example.com", NULL, NULL, L"example.com", NULL, L"/a%20b", NULL, L"http", NULL, 80}, + {L"http://example.com/a%2f/b", L"http://example.com/a%2f/b", L"http://example.com/a%2f/b", L"http://example.com/a%2f/b", L"example.com", NULL, NULL, L"example.com", NULL, L"/a%2f/b", NULL, L"http", NULL, 80}, + {L"http://example.com/a%2F/b", L"http://example.com/a%2F/b", L"http://example.com/a%2F/b", L"http://example.com/a%2F/b", L"example.com", NULL, NULL, L"example.com", NULL, L"/a%2F/b", NULL, L"http", NULL, 80}, + {L"http://%FF%FF%FF.com", L"http://%FF%FF%FF.com", L"http://%ff%ff%ff.com/", L"http://%ff%ff%ff.com/", L"%ff%ff%ff.com", NULL, NULL, L"%ff%ff%ff.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"dummy://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"dummy://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"dummy://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"dummy://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"exam ple.com", NULL, L"#frag ment", L"exam ple.com", L"pass word", L"/pa th", L"?qu ery=val ue", L"dummy", L"us er", -1}, + {L"http://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"http://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"http://us%20er:pass%20word@exam%20ple.com/pa%20th?qu ery=val ue#frag ment", L"http://exam%20ple.com/pa%20th?qu ery=val ue#frag ment", L"exam%20ple.com", NULL, L"#frag ment", L"exam%20ple.com", L"pass%20word", L"/pa%20th", L"?qu ery=val ue", L"http", L"us%20er", 80}, + {L"https://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"https://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"https://us%20er:pass%20word@exam%20ple.com/pa%20th?qu ery=val ue#frag ment", L"https://exam%20ple.com/pa%20th?qu ery=val ue#frag ment", L"exam%20ple.com", NULL, L"#frag ment", L"exam%20ple.com", L"pass%20word", L"/pa%20th", L"?qu ery=val ue", L"https", L"us%20er", 443}, + {L"ftp://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"ftp://us er:pass word@exam ple.com/pa th?qu ery=val ue#frag ment", L"ftp://us%20er:pass%20word@exam%20ple.com/pa%20th?qu ery=val ue#frag ment", L"ftp://exam%20ple.com/pa%20th?qu ery=val ue#frag ment", L"exam%20ple.com", NULL, L"#frag ment", L"exam%20ple.com", L"pass%20word", L"/pa%20th", L"?qu ery=val ue", L"ftp", L"us%20er", 21}, + {L"file://a b/c d", L"file://a b/c d", L"file://a%20b/c%20d", L"file://a%20b/c%20d", NULL, NULL, NULL, L"a%20b", NULL, L"/c%20d", NULL, L"file", NULL, -1}, + {L"http://example.com/path/to /resource", L"http://example.com/path/to /resource", L"http://example.com/path/to%20/resource", L"http://example.com/path/to%20/resource", L"example.com", NULL, NULL, L"example.com", NULL, L"/path/to%20/resource", NULL, L"http", NULL, 80}, + /* Punycode */ + {L"http://xn--0zwm56d.example.com/", L"http://xn--0zwm56d.example.com/", L"http://%5Cu6d4b%5Cu8bd5.example.com/", L"http://%5Cu6d4b%5Cu8bd5.example.com/", L"example.com", NULL, NULL, L"\u6d4b\u8bd5.example.com", NULL, L"/", NULL, L"http", NULL, 80}, + /* Unicode */ + {L"http://example.com/%5Cu00e4%5Cu00f6%5Cu00fc", L"http://example.com/%5Cu00e4%5Cu00f6%5Cu00fc", L"http://example.com/%5Cu00e4%5Cu00f6%5Cu00fc", L"http://example.com/%5Cu00e4%5Cu00f6%5Cu00fc", L"example.com", NULL, NULL, L"example.com", NULL, L"/\u00e4\u00f6\u00fc", NULL, L"http", NULL, 80}, + /* Miscellaneous tests */ + {L"HTTP://EXAMPLE.COM/", L"HTTP://EXAMPLE.COM/", L"http://example.com/", L"http://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"http", NULL, 80}, + {L"dummy:", L"dummy:", L"dummy:", L"dummy:", NULL, NULL, NULL, NULL, NULL, NULL, NULL, L"dummy", NULL, -1}, + {L"dummy://example.com", L"dummy://example.com", L"dummy://example.com/", L"dummy://example.com/", L"example.com", NULL, NULL, L"example.com", NULL, L"/", NULL, L"dummy", NULL, -1}, + }; static const WCHAR *class_name = L"Windows.Foundation.Uri"; IActivationFactory *activation_factory = NULL; IUriRuntimeClassFactory *uri_factory = NULL; IUriRuntimeClass *uri_class = NULL; IInspectable *inspectable = NULL; - IPropertyValue *value; + IPropertyValue *prop_value; + const WCHAR *buffer; + INT32 int32_value; HSTRING str, uri; + unsigned int i; HRESULT hr; - INT32 res;
hr = RoInitialize(RO_INIT_MULTITHREADED); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -124,40 +269,96 @@ static void test_IUriRuntimeClass(void) hr = IActivationFactory_QueryInterface(activation_factory, &IID_IUriRuntimeClassFactory, (void **)&uri_factory); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- hr = WindowsCreateString(L"https://www.winehq.org/", wcslen(L"https://www.winehq.org/"), &uri); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - hr = IUriRuntimeClassFactory_CreateUri(uri_factory, uri, &uri_class); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + winetest_push_context("%s", wine_dbgstr_w(tests[i].src));
- hr = IUriRuntimeClass_QueryInterface(uri_class, &IID_IInspectable, (void **)&inspectable); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(uri_class == (void *)inspectable, "QueryInterface IID_IInspectable returned %p, expected %p.\n", - inspectable, uri_factory); - IInspectable_Release(inspectable); + hr = WindowsCreateString(tests[i].src, wcslen(tests[i].src), &uri); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IUriRuntimeClassFactory_CreateUri(uri_factory, uri, &uri_class); + if (tests[i].invalid) + { + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + WindowsDeleteString(uri); + winetest_pop_context(); + continue; + } + else + { + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + }
- hr = IUriRuntimeClass_QueryInterface(uri_class, &IID_IPropertyValue, (void **)&value); - ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + if (i == 0) + { + hr = IUriRuntimeClass_QueryInterface(uri_class, &IID_IInspectable, (void **)&inspectable); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(uri_class == (void *)inspectable, "QueryInterface IID_IInspectable returned %p, expected %p.\n", + inspectable, uri_factory); + IInspectable_Release(inspectable);
- /* Test IUriRuntimeClass_get_RawUri() */ - hr = IUriRuntimeClass_get_RawUri(uri_class, &str); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(str != uri, "Expected a different pointer.\n"); - hr = WindowsCompareStringOrdinal(uri, str, &res); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(res == 0, "Expected %s, got %s.\n", debugstr_hstring(uri), debugstr_hstring(str)); - WindowsDeleteString(str); + hr = IUriRuntimeClass_QueryInterface(uri_class, &IID_IPropertyValue, (void **)&prop_value); + ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + }
- /* Test IUriRuntimeClass_get_AbsoluteUri() */ - hr = IUriRuntimeClass_get_AbsoluteUri(uri_class, &str); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(str != uri, "Expected a different pointer.\n"); - hr = WindowsCompareStringOrdinal(uri, str, &res); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(res == 0, "Expected %s, got %s.\n", debugstr_hstring(uri), debugstr_hstring(str)); - WindowsDeleteString(str); +#define TEST_HSTRING(prop) \ + winetest_push_context(#prop); \ + str = NULL; \ + hr = IUriRuntimeClass_get_##prop(uri_class, &str); \ + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); \ + ok(str != uri, "Expected a different pointer.\n"); \ + if (tests[i].prop) \ + { \ + ok(!!str, "Expected a valid pointer.\n"); \ + buffer = WindowsGetStringRawBuffer(str, NULL); \ + ok(!wcscmp(buffer, tests[i].prop), "Expected %s, got %s.\n", wine_dbgstr_w(tests[i].prop), \ + debugstr_hstring(str)); \ + WindowsDeleteString(str); \ + } \ + else \ + { \ + ok(!str, "Expected a NULL pointer.\n"); \ + } \ + winetest_pop_context(); + +#define TEST_INT32(prop) \ + winetest_push_context(#prop); \ + hr = IUriRuntimeClass_get_##prop(uri_class, &int32_value); \ + if (tests[i].prop == -1) \ + { \ + ok(hr == S_FALSE, "Got unexpected hr %#lx.\n", hr); \ + } \ + else \ + { \ + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); \ + ok(int32_value == tests[i].prop, "Expected " #prop " %d, got %d.\n", tests[i].prop, \ + int32_value); \ + } \ + winetest_pop_context(); + + TEST_HSTRING(AbsoluteUri) + TEST_HSTRING(DisplayUri) + + /* TODO: TEST_HSTRING(Domain) */ + + TEST_HSTRING(Extension) + TEST_HSTRING(Fragment) + TEST_HSTRING(Host) + TEST_HSTRING(Password) + TEST_HSTRING(Path) + TEST_HSTRING(Query) + TEST_HSTRING(RawUri) + TEST_HSTRING(SchemeName) + TEST_HSTRING(UserName) + TEST_INT32(Port) + +#undef TEST_HSTRING +#undef TEST_HSTRING + + IUriRuntimeClass_Release(uri_class); + WindowsDeleteString(uri); + winetest_pop_context(); + }
- WindowsDeleteString(uri); - IUriRuntimeClass_Release(uri_class); IUriRuntimeClassFactory_Release(uri_factory); IActivationFactory_Release(activation_factory); RoUninitialize();