Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / navigatorcontentutils / NavigatorContentUtils.cpp
index 05b2bf6..8e7d378 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * 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",
@@ -63,11 +64,11 @@ static void initProtocolHandlerWhitelist()
         "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.
@@ -83,54 +84,71 @@ static bool verifyCustomHandlerURL(const KURL& baseURL, const String& url, Excep
     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)
@@ -139,19 +157,16 @@ void NavigatorContentUtils::registerProtocolHandler(Navigator& navigator, const
         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)
@@ -181,16 +196,18 @@ String NavigatorContentUtils::isProtocolHandlerRegistered(Navigator& navigator,
         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)
@@ -199,16 +216,16 @@ void NavigatorContentUtils::unregisterProtocolHandler(Navigator& navigator, cons
         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()
@@ -216,9 +233,9 @@ 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