NavigatorRegisterProtocolHandler.cpp [plain text]
#include "config.h"
#include "NavigatorRegisterProtocolHandler.h"
#if ENABLE(REGISTER_PROTOCOL_HANDLER)
#include "Chrome.h"
#include "Document.h"
#include "ExceptionCode.h"
#include "Frame.h"
#include "Navigator.h"
#include "Page.h"
#include <wtf/HashSet.h>
namespace WebCore {
static HashSet<String>* protocolWhitelist;
static void initProtocolHandlerWhitelist()
{
protocolWhitelist = new HashSet<String>;
static const char* protocols[] = {
"irc",
"mailto",
"mms",
"news",
"nntp",
"sms",
"smsto",
"tel",
"urn",
"webcal",
};
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 const char token[] = "%s";
int index = url.find(token);
if (-1 == index) {
ec = SYNTAX_ERR;
return false;
}
String newURL = url;
newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);
KURL base(ParsedURLString, baseURL);
KURL kurl(base, newURL);
if (kurl.isEmpty() || !kurl.isValid()) {
ec = SYNTAX_ERR;
return false;
}
return true;
}
static bool isProtocolWhitelisted(const String& scheme)
{
if (!protocolWhitelist)
initProtocolHandlerWhitelist();
return protocolWhitelist->contains(scheme);
}
static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec)
{
if (scheme.startsWith("web+")) {
if (isValidProtocol(scheme))
return true;
ec = SECURITY_ERR;
return false;
}
if (isProtocolWhitelisted(scheme))
return true;
ec = SECURITY_ERR;
return false;
}
NavigatorRegisterProtocolHandler::NavigatorRegisterProtocolHandler()
{
}
NavigatorRegisterProtocolHandler::~NavigatorRegisterProtocolHandler()
{
}
void NavigatorRegisterProtocolHandler::registerProtocolHandler(Navigator* navigator, const String& scheme, const String& url, const String& title, ExceptionCode& ec)
{
if (!navigator->frame())
return;
Document* document = navigator->frame()->document();
if (!document)
return;
String baseURL = document->baseURL().baseAsString();
if (!verifyCustomHandlerURL(baseURL, url, ec))
return;
if (!verifyProtocolHandlerScheme(scheme, ec))
return;
Page* page = navigator->frame()->page();
if (!page)
return;
page->chrome()->registerProtocolHandler(scheme, baseURL, url, navigator->frame()->displayStringModifiedByEncoding(title));
}
}
#endif // ENABLE(REGISTER_PROTOCOL_HANDLER)