summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp')
-rw-r--r--Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp153
1 files changed, 57 insertions, 96 deletions
diff --git a/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp b/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp
index b5fb0266f..010efb77e 100644
--- a/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp
+++ b/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp
@@ -35,129 +35,91 @@
#include "Navigator.h"
#include "Page.h"
#include <wtf/HashSet.h>
+#include <wtf/NeverDestroyed.h>
namespace WebCore {
-static HashSet<String>* protocolWhitelist;
-
-static void initProtocolHandlerWhitelist()
-{
- protocolWhitelist = new HashSet<String>;
- static const char* protocols[] = {
- "bitcoin",
- "geo",
- "im",
- "irc",
- "ircs",
- "magnet",
- "mailto",
- "mms",
- "news",
- "nntp",
- "sip",
- "sms",
- "smsto",
- "ssh",
- "tel",
- "urn",
- "webcal",
- "wtai",
- "xmpp",
- };
- for (size_t i = 0; i < WTF_ARRAY_LENGTH(protocols); ++i)
- protocolWhitelist->add(protocols[i]);
-}
-
-static bool verifyCustomHandlerURL(const String& baseURL, const String& url, ExceptionCode& ec)
+static bool verifyCustomHandlerURL(const URL& baseURL, const String& url)
{
// The specification requires that it is a SYNTAX_ERR if the "%s" token is
// not present.
static const char token[] = "%s";
int index = url.find(token);
- if (-1 == index) {
- ec = SYNTAX_ERR;
+ if (-1 == index)
return false;
- }
// It is also a SYNTAX_ERR if the custom handler URL, as created by removing
// the "%s" token and prepending the base url, does not resolve.
String newURL = url;
newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);
- URL base(ParsedURLString, baseURL);
- URL kurl(base, newURL);
+ URL kurl(baseURL, newURL);
- if (kurl.isEmpty() || !kurl.isValid()) {
- ec = SYNTAX_ERR;
+ if (kurl.isEmpty() || !kurl.isValid())
return false;
- }
return true;
}
-static bool isProtocolWhitelisted(const String& scheme)
+static inline bool isProtocolWhitelisted(const String& scheme)
{
- if (!protocolWhitelist)
- initProtocolHandlerWhitelist();
- return protocolWhitelist->contains(scheme);
+ static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> protocolWhitelist = []() {
+ HashSet<String, ASCIICaseInsensitiveHash> set;
+ for (auto* protocol : { "bitcoin", "geo", "im", "irc", "ircs", "magnet", "mailto", "mms", "news", "nntp", "sip", "sms", "smsto", "ssh", "tel", "urn", "webcal", "wtai", "xmpp" })
+ set.add(protocol);
+ return set;
+ }();
+ return protocolWhitelist.get().contains(scheme);
}
-static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec)
+static bool verifyProtocolHandlerScheme(const String& scheme)
{
+ if (isProtocolWhitelisted(scheme))
+ return true;
+
+ // FIXME: Should this be case sensitive, or should it be ASCII case-insensitive?
if (scheme.startsWith("web+")) {
- // The specification requires that the length of scheme is at least five characteres (including 'web+' prefix).
+ // The specification requires that the length of scheme is at least five characters (including 'web+' prefix).
if (scheme.length() >= 5 && isValidProtocol(scheme))
return true;
- ec = SECURITY_ERR;
- return false;
}
- if (isProtocolWhitelisted(scheme))
- return true;
- ec = SECURITY_ERR;
return false;
}
NavigatorContentUtils* NavigatorContentUtils::from(Page* page)
{
- return static_cast<NavigatorContentUtils*>(RefCountedSupplement<Page, NavigatorContentUtils>::from(page, NavigatorContentUtils::supplementName()));
+ return static_cast<NavigatorContentUtils*>(Supplement<Page>::from(page, supplementName()));
}
NavigatorContentUtils::~NavigatorContentUtils()
{
}
-PassRefPtr<NavigatorContentUtils> NavigatorContentUtils::create(NavigatorContentUtilsClient* client)
-{
- return adoptRef(new NavigatorContentUtils(client));
-}
-
-void NavigatorContentUtils::registerProtocolHandler(Navigator* navigator, const String& scheme, const String& url, const String& title, ExceptionCode& ec)
+ExceptionOr<void> NavigatorContentUtils::registerProtocolHandler(Navigator& navigator, const String& scheme, const String& url, const String& title)
{
- if (!navigator->frame())
- return;
+ if (!navigator.frame())
+ return { };
- Document* document = navigator->frame()->document();
- if (!document)
- return;
+ URL baseURL = navigator.frame()->document()->baseURL();
- String baseURL = document->baseURL().baseAsString();
+ if (!verifyCustomHandlerURL(baseURL, url))
+ return Exception { SYNTAX_ERR };
- if (!verifyCustomHandlerURL(baseURL, url, ec))
- return;
+ if (!verifyProtocolHandlerScheme(scheme))
+ return Exception { SECURITY_ERR };
- if (!verifyProtocolHandlerScheme(scheme, ec))
- return;
-
- NavigatorContentUtils::from(navigator->frame()->page())->client()->registerProtocolHandler(scheme, baseURL, url, navigator->frame()->displayStringModifiedByEncoding(title));
+ NavigatorContentUtils::from(navigator.frame()->page())->client()->registerProtocolHandler(scheme, baseURL, URL(ParsedURLString, url), navigator.frame()->displayStringModifiedByEncoding(title));
+ return { };
}
#if ENABLE(CUSTOM_SCHEME_HANDLER)
+
static String customHandlersStateString(const NavigatorContentUtilsClient::CustomHandlersState state)
{
- DEFINE_STATIC_LOCAL(const String, newHandler, (ASCIILiteral("new")));
- DEFINE_STATIC_LOCAL(const String, registeredHandler, (ASCIILiteral("registered")));
- DEFINE_STATIC_LOCAL(const String, declinedHandler, (ASCIILiteral("declined")));
+ static NeverDestroyed<String> newHandler(ASCIILiteral("new"));
+ static NeverDestroyed<String> registeredHandler(ASCIILiteral("registered"));
+ static NeverDestroyed<String> declinedHandler(ASCIILiteral("declined"));
switch (state) {
case NavigatorContentUtilsClient::CustomHandlersNew:
@@ -172,41 +134,41 @@ static String customHandlersStateString(const NavigatorContentUtilsClient::Custo
return String();
}
-String NavigatorContentUtils::isProtocolHandlerRegistered(Navigator* navigator, const String& scheme, const String& url, ExceptionCode& ec)
+ExceptionOr<String> NavigatorContentUtils::isProtocolHandlerRegistered(Navigator& navigator, const String& scheme, const String& url)
{
- DEFINE_STATIC_LOCAL(const String, declined, ("declined"));
+ static NeverDestroyed<String> declined(ASCIILiteral("declined"));
- if (!navigator->frame())
- return declined;
+ if (!navigator.frame())
+ return String { declined };
- Document* document = navigator->frame()->document();
- String baseURL = document->baseURL().baseAsString();
+ URL baseURL = navigator.frame()->document()->baseURL();
- if (!verifyCustomHandlerURL(baseURL, url, ec))
- return declined;
+ if (!verifyCustomHandlerURL(baseURL, url))
+ return Exception { SYNTAX_ERR };
- if (!verifyProtocolHandlerScheme(scheme, ec))
- return declined;
+ if (!verifyProtocolHandlerScheme(scheme))
+ return Exception { SECURITY_ERR };
- return customHandlersStateString(NavigatorContentUtils::from(navigator->frame()->page())->client()->isProtocolHandlerRegistered(scheme, baseURL, url));
+ return customHandlersStateString(NavigatorContentUtils::from(navigator.frame()->page())->client()->isProtocolHandlerRegistered(scheme, baseURL, URL(ParsedURLString, url)));
}
-void NavigatorContentUtils::unregisterProtocolHandler(Navigator* navigator, const String& scheme, const String& url, ExceptionCode& ec)
+ExceptionOr<void> NavigatorContentUtils::unregisterProtocolHandler(Navigator& navigator, const String& scheme, const String& url)
{
- if (!navigator->frame())
- return;
+ if (!navigator.frame())
+ return { };
- Document* document = navigator->frame()->document();
- String baseURL = document->baseURL().baseAsString();
+ URL baseURL = navigator.frame()->document()->baseURL();
- if (!verifyCustomHandlerURL(baseURL, url, ec))
- return;
+ if (!verifyCustomHandlerURL(baseURL, url))
+ return Exception { SYNTAX_ERR };
- if (!verifyProtocolHandlerScheme(scheme, ec))
- return;
+ if (!verifyProtocolHandlerScheme(scheme))
+ return Exception { SECURITY_ERR };
- NavigatorContentUtils::from(navigator->frame()->page())->client()->unregisterProtocolHandler(scheme, baseURL, url);
+ NavigatorContentUtils::from(navigator.frame()->page())->client()->unregisterProtocolHandler(scheme, baseURL, URL(ParsedURLString, url));
+ return { };
}
+
#endif
const char* NavigatorContentUtils::supplementName()
@@ -214,12 +176,11 @@ const char* NavigatorContentUtils::supplementName()
return "NavigatorContentUtils";
}
-void provideNavigatorContentUtilsTo(Page* page, NavigatorContentUtilsClient* client)
+void provideNavigatorContentUtilsTo(Page* page, std::unique_ptr<NavigatorContentUtilsClient> client)
{
- RefCountedSupplement<Page, NavigatorContentUtils>::provideTo(page, NavigatorContentUtils::supplementName(), NavigatorContentUtils::create(client));
+ NavigatorContentUtils::provideTo(page, NavigatorContentUtils::supplementName(), std::make_unique<NavigatorContentUtils>(WTFMove(client)));
}
} // namespace WebCore
#endif // ENABLE(NAVIGATOR_CONTENT_UTILS)
-