summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/navigatorcontentutils
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/Modules/navigatorcontentutils')
-rw-r--r--Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp153
-rw-r--r--Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.h32
-rw-r--r--Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.idl7
-rw-r--r--Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtilsClient.h15
4 files changed, 80 insertions, 127 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)
-
diff --git a/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.h b/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.h
index 99151c287..bf2647751 100644
--- a/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.h
+++ b/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.h
@@ -24,15 +24,13 @@
* DAMAGE.
*/
-#ifndef NavigatorContentUtils_h
-#define NavigatorContentUtils_h
+#pragma once
#if ENABLE(NAVIGATOR_CONTENT_UTILS)
+#include "ExceptionOr.h"
#include "NavigatorContentUtilsClient.h"
-#include "RefCountedSupplement.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/text/WTFString.h>
+#include "Supplementable.h"
namespace WebCore {
@@ -41,34 +39,30 @@ class Navigator;
typedef int ExceptionCode;
-class NavigatorContentUtils : public RefCountedSupplement<Page, NavigatorContentUtils> {
+class NavigatorContentUtils final : public Supplement<Page> {
public:
+ explicit NavigatorContentUtils(std::unique_ptr<NavigatorContentUtilsClient> client)
+ : m_client(WTFMove(client))
+ { }
+
virtual ~NavigatorContentUtils();
static const char* supplementName();
static NavigatorContentUtils* from(Page*);
- static void registerProtocolHandler(Navigator*, const String& scheme, const String& url, const String& title, ExceptionCode&);
+ static ExceptionOr<void> registerProtocolHandler(Navigator&, const String& scheme, const String& url, const String& title);
#if ENABLE(CUSTOM_SCHEME_HANDLER)
- static String isProtocolHandlerRegistered(Navigator*, const String& scheme, const String& url, ExceptionCode&);
- static void unregisterProtocolHandler(Navigator*, const String& scheme, const String& url, ExceptionCode&);
+ static ExceptionOr<String> isProtocolHandlerRegistered(Navigator&, const String& scheme, const String& url);
+ static ExceptionOr<void> unregisterProtocolHandler(Navigator&, const String& scheme, const String& url);
#endif
- static PassRefPtr<NavigatorContentUtils> create(NavigatorContentUtilsClient*);
-
private:
- explicit NavigatorContentUtils(NavigatorContentUtilsClient* client)
- : m_client(client)
- { }
-
- NavigatorContentUtilsClient* client() { return m_client; }
+ NavigatorContentUtilsClient* client() { return m_client.get(); }
- NavigatorContentUtilsClient* m_client;
+ std::unique_ptr<NavigatorContentUtilsClient> m_client;
};
} // namespace WebCore
#endif // ENABLE(NAVIGATOR_CONTENT_UTILS)
-
-#endif // NavigatorContentUtils_h
diff --git a/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.idl b/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.idl
index a9f4b3114..f3eca86ba 100644
--- a/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.idl
+++ b/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.idl
@@ -20,8 +20,7 @@
// http://www.w3.org/TR/html5/system-state-and-capabilities.html#custom-handlers
partial interface Navigator {
- [Conditional=NAVIGATOR_CONTENT_UTILS, RaisesException] void registerProtocolHandler(DOMString scheme, DOMString url, DOMString title);
- [Conditional=NAVIGATOR_CONTENT_UTILS&CUSTOM_SCHEME_HANDLER, RaisesException] DOMString isProtocolHandlerRegistered(DOMString scheme, DOMString url);
- [Conditional=NAVIGATOR_CONTENT_UTILS&CUSTOM_SCHEME_HANDLER, RaisesException] void unregisterProtocolHandler(DOMString scheme, DOMString url);
+ [Conditional=NAVIGATOR_CONTENT_UTILS, MayThrowException] void registerProtocolHandler(DOMString scheme, DOMString url, DOMString title);
+ [Conditional=NAVIGATOR_CONTENT_UTILS&CUSTOM_SCHEME_HANDLER, MayThrowException] DOMString isProtocolHandlerRegistered(DOMString scheme, DOMString url);
+ [Conditional=NAVIGATOR_CONTENT_UTILS&CUSTOM_SCHEME_HANDLER, MayThrowException] void unregisterProtocolHandler(DOMString scheme, DOMString url);
};
-
diff --git a/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtilsClient.h b/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtilsClient.h
index 25d67cc10..b70e896db 100644
--- a/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtilsClient.h
+++ b/Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtilsClient.h
@@ -23,11 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef NavigatorContentUtilsClient_h
-#define NavigatorContentUtilsClient_h
+#pragma once
#if ENABLE(NAVIGATOR_CONTENT_UTILS)
+#include "URL.h"
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -37,7 +37,7 @@ class Page;
class NavigatorContentUtilsClient {
public:
virtual ~NavigatorContentUtilsClient() { }
- virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) = 0;
+ virtual void registerProtocolHandler(const String& scheme, const URL& baseURL, const URL&, const String& title) = 0;
#if ENABLE(CUSTOM_SCHEME_HANDLER)
enum CustomHandlersState {
@@ -46,14 +46,13 @@ public:
CustomHandlersDeclined
};
- virtual CustomHandlersState isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url) = 0;
- virtual void unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url) = 0;
+ virtual CustomHandlersState isProtocolHandlerRegistered(const String& scheme, const URL& baseURL, const URL&) = 0;
+ virtual void unregisterProtocolHandler(const String& scheme, const URL& baseURL, const URL&) = 0;
#endif
};
-void provideNavigatorContentUtilsTo(Page*, NavigatorContentUtilsClient*);
+void provideNavigatorContentUtilsTo(Page*, std::unique_ptr<NavigatorContentUtilsClient>);
-}
+} // namespace WebCore
#endif // ENABLE(NAVIGATOR_CONTENT_UTILS)
-#endif // NavigatorContentUtilsClient_h