diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index 6fc6ff7f0..f256e1d20 100644 --- a/include/cef_api_hash.h +++ b/include/cef_api_hash.h @@ -34,7 +34,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=06d0c1ccfa43926a01cbeb3ec95ff2a001fd0b45$ +// $hash=da85b3ecfdc813ae487499df87d048a5f8031538$ // #ifndef CEF_INCLUDE_API_HASH_H_ @@ -47,13 +47,13 @@ // way that may cause binary incompatibility with other builds. The universal // hash value will change if any platform is affected whereas the platform hash // values will change only if that particular platform is affected. -#define CEF_API_HASH_UNIVERSAL "3ad9591f7024619a1e2fd796c7ad51ae3a34abbb" +#define CEF_API_HASH_UNIVERSAL "736999b199a558cb5a5a37309bda51a45f9c2549" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "3b8e38ae40c1a930227c6277c39dbc24081ccec1" +#define CEF_API_HASH_PLATFORM "e5eac77b557780b50862f5a770d20f3fd6a4c98f" #elif defined(OS_MACOSX) -#define CEF_API_HASH_PLATFORM "4a77f1908fabccdb01a2d3bdbede5ca09fbaa394" +#define CEF_API_HASH_PLATFORM "2fde0819a2ff07f996c6d996ae54c6181549a122" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "434da6be7db70fd90c4265118ac47ace4073c6ae" +#define CEF_API_HASH_PLATFORM "b1a576d94b3c3e398f1fe7dadfe4442f195d7028" #endif #ifdef __cplusplus diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 48377384a..1423762e0 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -725,6 +725,11 @@ typedef struct _cef_urlparts_t { // Query string component (i.e., everything following the '?'). /// cef_string_t query; + + /// + // Fragment (hash) identifier component (i.e., the string following the '#'). + /// + cef_string_t fragment; } cef_urlparts_t; /// diff --git a/include/internal/cef_types_wrappers.h b/include/internal/cef_types_wrappers.h index 41e79488b..caea5c1cc 100644 --- a/include/internal/cef_types_wrappers.h +++ b/include/internal/cef_types_wrappers.h @@ -743,6 +743,7 @@ struct CefURLPartsTraits { cef_string_clear(&s->origin); cef_string_clear(&s->path); cef_string_clear(&s->query); + cef_string_clear(&s->fragment); } static inline void set(const struct_type* src, @@ -759,6 +760,8 @@ struct CefURLPartsTraits { cef_string_set(src->origin.str, src->origin.length, &target->origin, copy); cef_string_set(src->path.str, src->path.length, &target->path, copy); cef_string_set(src->query.str, src->query.length, &target->query, copy); + cef_string_set(src->fragment.str, src->fragment.length, &target->fragment, + copy); } }; diff --git a/libcef/common/parser_impl.cc b/libcef/common/parser_impl.cc index b516ac771..cd95b3bff 100644 --- a/libcef/common/parser_impl.cc +++ b/libcef/common/parser_impl.cc @@ -27,6 +27,7 @@ bool CefParseURL(const CefString& url, CefURLParts& parts) { CefString(&parts.port).FromString(gurl.port()); CefString(&parts.path).FromString(gurl.path()); CefString(&parts.query).FromString(gurl.query()); + CefString(&parts.fragment).FromString(gurl.ref()); return true; } @@ -42,6 +43,8 @@ bool CefCreateURL(const CefURLParts& parts, CefString& url) { std::string port = CefString(parts.port.str, parts.port.length, false); std::string path = CefString(parts.path.str, parts.path.length, false); std::string query = CefString(parts.query.str, parts.query.length, false); + std::string fragment = + CefString(parts.fragment.str, parts.fragment.length, false); GURL gurl; if (!spec.empty()) { @@ -62,6 +65,8 @@ bool CefCreateURL(const CefURLParts& parts, CefString& url) { ss << path; if (!query.empty()) ss << "?" << query; + if (!fragment.empty()) + ss << "#" << fragment; gurl = GURL(ss.str()); } diff --git a/tests/ceftests/parser_unittest.cc b/tests/ceftests/parser_unittest.cc index 6ed29874f..3f7177e0a 100644 --- a/tests/ceftests/parser_unittest.cc +++ b/tests/ceftests/parser_unittest.cc @@ -69,6 +69,20 @@ TEST(ParserTest, CreateURLSchemeHostPathQuery) { url.ToString().c_str()); } +// Create the URL using scheme, host, path, query and Fragment +TEST(ParserTest, CreateURLSchemeHostPathQueryFragment) { + CefURLParts parts; + CefString url; + CefString(&parts.scheme).FromASCII("http"); + CefString(&parts.host).FromASCII("www.example.com"); + CefString(&parts.path).FromASCII("/path/to.html"); + CefString(&parts.query).FromASCII("foo=test&bar=test2"); + CefString(&parts.fragment).FromASCII("ref"); + EXPECT_TRUE(CefCreateURL(parts, url)); + EXPECT_STREQ("http://www.example.com/path/to.html?foo=test&bar=test2#ref", + url.ToString().c_str()); +} + // Create the URL using all the various components. TEST(ParserTest, CreateURLAll) { CefURLParts parts; @@ -80,9 +94,10 @@ TEST(ParserTest, CreateURLAll) { CefString(&parts.port).FromASCII("88"); CefString(&parts.path).FromASCII("/path/to.html"); CefString(&parts.query).FromASCII("foo=test&bar=test2"); + CefString(&parts.fragment).FromASCII("ref"); EXPECT_TRUE(CefCreateURL(parts, url)); EXPECT_STREQ( - "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2", + "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2#ref", url.ToString().c_str()); } @@ -157,17 +172,45 @@ TEST(ParserTest, ParseURLSchemeHostPathQuery) { EXPECT_STREQ("foo=test&bar=test2", query.ToString().c_str()); } +// Parse the URL using scheme, host, path, query and fragment. +TEST(ParserTest, ParseURLSchemeHostPathQueryFragment) { + CefURLParts parts; + CefString url; + url.FromASCII("http://www.example.com/path/to.html?foo=test&bar=test2#ref"); + EXPECT_TRUE(CefParseURL(url, parts)); + + CefString spec(&parts.spec); + EXPECT_STREQ("http://www.example.com/path/to.html?foo=test&bar=test2#ref", + spec.ToString().c_str()); + EXPECT_EQ(0U, parts.username.length); + EXPECT_EQ(0U, parts.password.length); + CefString scheme(&parts.scheme); + EXPECT_STREQ("http", scheme.ToString().c_str()); + CefString host(&parts.host); + EXPECT_STREQ("www.example.com", host.ToString().c_str()); + EXPECT_EQ(0U, parts.port.length); + CefString origin(&parts.origin); + EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com/"); + CefString path(&parts.path); + EXPECT_STREQ("/path/to.html", path.ToString().c_str()); + CefString query(&parts.query); + EXPECT_STREQ("foo=test&bar=test2", query.ToString().c_str()); + CefString ref(&parts.fragment); + EXPECT_STREQ("ref", ref.ToString().c_str()); +} + // Parse the URL using all the various components. TEST(ParserTest, ParseURLAll) { CefURLParts parts; CefString url; url.FromASCII( - "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2"); + "http://user:pass@www.example.com:88/path/" + "to.html?foo=test&bar=test2#ref"); EXPECT_TRUE(CefParseURL(url, parts)); CefString spec(&parts.spec); EXPECT_STREQ( - "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2", + "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2#ref", spec.ToString().c_str()); CefString scheme(&parts.scheme); EXPECT_STREQ("http", scheme.ToString().c_str()); @@ -185,6 +228,8 @@ TEST(ParserTest, ParseURLAll) { EXPECT_STREQ("/path/to.html", path.ToString().c_str()); CefString query(&parts.query); EXPECT_STREQ("foo=test&bar=test2", query.ToString().c_str()); + CefString ref(&parts.fragment); + EXPECT_STREQ("ref", ref.ToString().c_str()); } // Parse an invalid URL. @@ -199,11 +244,11 @@ TEST(ParserTest, ParseURLInvalid) { TEST(ParserTest, ParseURLNonStandard) { CefURLParts parts; CefString url; - url.FromASCII("custom:something%20else?foo"); + url.FromASCII("custom:something%20else?foo#ref"); EXPECT_TRUE(CefParseURL(url, parts)); CefString spec(&parts.spec); - EXPECT_STREQ("custom:something%20else?foo", spec.ToString().c_str()); + EXPECT_STREQ("custom:something%20else?foo#ref", spec.ToString().c_str()); EXPECT_EQ(0U, parts.username.length); EXPECT_EQ(0U, parts.password.length); CefString scheme(&parts.scheme); @@ -215,6 +260,8 @@ TEST(ParserTest, ParseURLNonStandard) { EXPECT_STREQ("something%20else", path.ToString().c_str()); CefString query(&parts.query); EXPECT_STREQ("foo", query.ToString().c_str()); + CefString ref(&parts.fragment); + EXPECT_STREQ("ref", ref.ToString().c_str()); } TEST(ParserTest, FormatUrlForSecurityDisplay) {