/*
* Copyright (C) 2011, Google Inc. All rights reserved.
- * Copyright (C) 2012, Samsung Electronics. All rights reserved.
+ * Copyright (C) 2014, Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
#include "config.h"
#include "modules/navigatorcontentutils/NavigatorContentUtils.h"
-#include "bindings/v8/ExceptionState.h"
+#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Navigator.h"
#include "core/page/Page.h"
#include "wtf/HashSet.h"
+#include "wtf/text/StringBuilder.h"
-namespace WebCore {
+namespace blink {
-static HashSet<String>* protocolWhitelist;
+static HashSet<String>* schemeWhitelist;
-static void initProtocolHandlerWhitelist()
+static void initCustomSchemeHandlerWhitelist()
{
- protocolWhitelist = new HashSet<String>;
- static const char* const protocols[] = {
+ schemeWhitelist = new HashSet<String>;
+ static const char* const schemes[] = {
"bitcoin",
"geo",
"im",
"wtai",
"xmpp",
};
- for (size_t i = 0; i < WTF_ARRAY_LENGTH(protocols); ++i)
- protocolWhitelist->add(protocols[i]);
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(schemes); ++i)
+ schemeWhitelist->add(schemes[i]);
}
-static bool verifyCustomHandlerURL(const KURL& baseURL, const String& url, ExceptionState& exceptionState)
+static bool verifyCustomHandlerURL(const Document& document, const String& url, ExceptionState& exceptionState)
{
// The specification requires that it is a SyntaxError if the "%s" token is
// not present.
String newURL = url;
newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);
- KURL kurl(baseURL, newURL);
+ KURL kurl = document.completeURL(url);
if (kurl.isEmpty() || !kurl.isValid()) {
- exceptionState.throwDOMException(SyntaxError, "The custom handler URL created by removing '%s' and prepending '" + baseURL.string() + "' is invalid.");
+ exceptionState.throwDOMException(SyntaxError, "The custom handler URL created by removing '%s' and prepending '" + document.baseURL().string() + "' is invalid.");
+ return false;
+ }
+
+ // The specification says that the API throws SecurityError exception if the
+ // URL's origin differs from the document's origin.
+ if (!document.securityOrigin()->canRequest(kurl)) {
+ exceptionState.throwSecurityError("Can only register custom handler in the document's origin.");
return false;
}
return true;
}
-static bool isProtocolWhitelisted(const String& scheme)
+static bool isSchemeWhitelisted(const String& scheme)
{
- if (!protocolWhitelist)
- initProtocolHandlerWhitelist();
- return protocolWhitelist->contains(scheme);
+ if (!schemeWhitelist)
+ initCustomSchemeHandlerWhitelist();
+
+ StringBuilder builder;
+ unsigned length = scheme.length();
+ for (unsigned i = 0; i < length; ++i)
+ builder.append(toASCIILower(scheme[i]));
+
+ return schemeWhitelist->contains(builder.toString());
}
-static bool verifyProtocolHandlerScheme(const String& scheme, const String& method, ExceptionState& exceptionState)
+static bool verifyCustomHandlerScheme(const String& scheme, ExceptionState& exceptionState)
{
+ if (!isValidProtocol(scheme)) {
+ exceptionState.throwSecurityError("The scheme '" + scheme + "' is not valid protocol");
+ return false;
+ }
+
if (scheme.startsWith("web+")) {
// The specification requires that the length of scheme is at least five characteres (including 'web+' prefix).
- if (scheme.length() >= 5 && isValidProtocol(scheme))
+ if (scheme.length() >= 5)
return true;
- if (!isValidProtocol(scheme))
- exceptionState.throwSecurityError("The scheme '" + scheme + "' is not a valid protocol.");
- else
- exceptionState.throwSecurityError("The scheme '" + scheme + "' is less than five characters long.");
+
+ exceptionState.throwSecurityError("The scheme '" + scheme + "' is less than five characters long.");
return false;
}
- if (isProtocolWhitelisted(scheme))
+ if (isSchemeWhitelisted(scheme))
return true;
- exceptionState.throwSecurityError("The scheme '" + scheme + "' doesn't belong to the protocol whitelist. Please prefix non-whitelisted schemes with the string 'web+'.");
+
+ exceptionState.throwSecurityError("The scheme '" + scheme + "' doesn't belong to the scheme whitelist. Please prefix non-whitelisted schemes with the string 'web+'.");
return false;
}
NavigatorContentUtils* NavigatorContentUtils::from(Page& page)
{
- return static_cast<NavigatorContentUtils*>(RefCountedSupplement<Page, NavigatorContentUtils>::from(page, NavigatorContentUtils::supplementName()));
+ return static_cast<NavigatorContentUtils*>(WillBeHeapSupplement<Page>::from(page, supplementName()));
}
NavigatorContentUtils::~NavigatorContentUtils()
{
}
-PassRefPtr<NavigatorContentUtils> NavigatorContentUtils::create(NavigatorContentUtilsClient* client)
+PassOwnPtrWillBeRawPtr<NavigatorContentUtils> NavigatorContentUtils::create(PassOwnPtr<NavigatorContentUtilsClient> client)
{
- return adoptRef(new NavigatorContentUtils(client));
+ return adoptPtrWillBeNoop(new NavigatorContentUtils(client));
}
void NavigatorContentUtils::registerProtocolHandler(Navigator& navigator, const String& scheme, const String& url, const String& title, ExceptionState& exceptionState)
return;
Document* document = navigator.frame()->document();
- if (!document)
- return;
-
- KURL baseURL = document->baseURL();
+ ASSERT(document);
- if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
+ if (!verifyCustomHandlerURL(*document, url, exceptionState))
return;
- if (!verifyProtocolHandlerScheme(scheme, "registerProtocolHandler", exceptionState))
+ if (!verifyCustomHandlerScheme(scheme, exceptionState))
return;
ASSERT(navigator.frame()->page());
- NavigatorContentUtils::from(*navigator.frame()->page())->client()->registerProtocolHandler(scheme, baseURL, KURL(ParsedURLString, url), title);
+ NavigatorContentUtils::from(*navigator.frame()->page())->client()->registerProtocolHandler(scheme, document->completeURL(url), title);
}
static String customHandlersStateString(const NavigatorContentUtilsClient::CustomHandlersState state)
return declined;
Document* document = navigator.frame()->document();
- KURL baseURL = document->baseURL();
+ ASSERT(document);
+ if (document->activeDOMObjectsAreStopped())
+ return declined;
- if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
+ if (!verifyCustomHandlerURL(*document, url, exceptionState))
return declined;
- if (!verifyProtocolHandlerScheme(scheme, "isProtocolHandlerRegistered", exceptionState))
+ if (!verifyCustomHandlerScheme(scheme, exceptionState))
return declined;
ASSERT(navigator.frame()->page());
- return customHandlersStateString(NavigatorContentUtils::from(*navigator.frame()->page())->client()->isProtocolHandlerRegistered(scheme, baseURL, KURL(ParsedURLString, url)));
+ return customHandlersStateString(NavigatorContentUtils::from(*navigator.frame()->page())->client()->isProtocolHandlerRegistered(scheme, document->completeURL(url)));
}
void NavigatorContentUtils::unregisterProtocolHandler(Navigator& navigator, const String& scheme, const String& url, ExceptionState& exceptionState)
return;
Document* document = navigator.frame()->document();
- KURL baseURL = document->baseURL();
+ ASSERT(document);
- if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
+ if (!verifyCustomHandlerURL(*document, url, exceptionState))
return;
- if (!verifyProtocolHandlerScheme(scheme, "unregisterProtocolHandler", exceptionState))
+ if (!verifyCustomHandlerScheme(scheme, exceptionState))
return;
ASSERT(navigator.frame()->page());
- NavigatorContentUtils::from(*navigator.frame()->page())->client()->unregisterProtocolHandler(scheme, baseURL, KURL(ParsedURLString, url));
+ NavigatorContentUtils::from(*navigator.frame()->page())->client()->unregisterProtocolHandler(scheme, document->completeURL(url));
}
const char* NavigatorContentUtils::supplementName()
return "NavigatorContentUtils";
}
-void provideNavigatorContentUtilsTo(Page& page, NavigatorContentUtilsClient* client)
+void provideNavigatorContentUtilsTo(Page& page, PassOwnPtr<NavigatorContentUtilsClient> client)
{
- RefCountedSupplement<Page, NavigatorContentUtils>::provideTo(page, NavigatorContentUtils::supplementName(), NavigatorContentUtils::create(client));
+ NavigatorContentUtils::provideTo(page, NavigatorContentUtils::supplementName(), NavigatorContentUtils::create(client));
}
-} // namespace WebCore
+} // namespace blink