Bug 1499092 - move bulk of registerProtocolHandler checks into compiled code so we don't need a dedicated component in the child process, r=nika

Differential Revision: https://phabricator.services.mozilla.com/D13697

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Gijs Kruitbosch 2018-12-13 13:47:39 +00:00
Родитель 61cf4613b9
Коммит 7ab8abdd16
15 изменённых файлов: 251 добавлений и 459 удалений

Просмотреть файл

@ -1,2 +1,2 @@
component {792a7e82-06a0-437c-af63-b2d12e808acc} WebContentConverter.js
contract @mozilla.org/embeddor.implemented/web-content-handler-registrar;1 {792a7e82-06a0-437c-af63-b2d12e808acc}
component {792a7e82-06a0-437c-af63-b2d12e808acc} WebContentConverter.js process=main
contract @mozilla.org/embeddor.implemented/web-content-handler-registrar;1 {792a7e82-06a0-437c-af63-b2d12e808acc} process=main

Просмотреть файл

@ -5,135 +5,11 @@
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
function LOG(str) {
// dump("*** " + str + "\n");
}
const WCCR_CLASSID = Components.ID("{792a7e82-06a0-437c-af63-b2d12e808acc}");
const WCC_CLASSID = Components.ID("{db7ebf28-cc40-415f-8a51-1b111851df1e}");
const WCC_CLASSNAME = "Web Service Handler";
const PREF_HANDLER_EXTERNAL_PREFIX = "network.protocol-handler.external";
const STRING_BUNDLE_URI = "chrome://browser/locale/feeds/subscribe.properties";
const NS_ERROR_MODULE_DOM = 2152923136;
const NS_ERROR_DOM_SYNTAX_ERR = NS_ERROR_MODULE_DOM + 12;
const Utils = {
makeURI(aURL, aOriginCharset, aBaseURI) {
return Services.io.newURI(aURL, aOriginCharset, aBaseURI);
},
checkAndGetURI(aURIString, aContentWindow) {
let uri;
try {
let baseURI = aContentWindow.document.baseURIObject;
uri = this.makeURI(aURIString, null, baseURI);
} catch (ex) {
throw NS_ERROR_DOM_SYNTAX_ERR;
}
// For security reasons we reject non-http(s) urls (see bug 354316),
// we may need to revise this once we support more content types
if (uri.scheme != "http" && uri.scheme != "https") {
throw this.getSecurityError(
"Permission denied to add " + uri.spec + " as a content or protocol handler",
aContentWindow);
}
// We also reject handlers registered from a different host (see bug 402287)
if (!["http:", "https:"].includes(aContentWindow.location.protocol) ||
aContentWindow.location.hostname != uri.host) {
throw this.getSecurityError(
"Permission denied to add " + uri.spec + " as a content or protocol handler",
aContentWindow);
}
// If the uri doesn't contain '%s', it won't be a good handler
if (!uri.spec.includes("%s"))
throw NS_ERROR_DOM_SYNTAX_ERR;
return uri;
},
// This list should be kept up-to-date with the spec:
// https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers
_safeProtocols: new Set([
"bitcoin",
"geo",
"im",
"irc",
"ircs",
"magnet",
"mailto",
"mms",
"news",
"nntp",
"openpgp4fpr",
"sip",
"sms",
"smsto",
"ssh",
"tel",
"urn",
"webcal",
"wtai",
"xmpp",
]),
// NB: Throws if aProtocol is not allowed.
checkProtocolHandlerAllowed(aProtocol, aURIString, aWindowOrNull) {
if (aProtocol.startsWith("web+")) {
if (!/[a-z]+/.test(aProtocol.substring(4 /* web+ */))) {
throw this.getSecurityError(
`Permission denied to add a protocol handler for ${aProtocol}`,
aWindowOrNull);
}
} else if (!this._safeProtocols.has(aProtocol)) {
throw this.getSecurityError(
`Permission denied to add a protocol handler for ${aProtocol}`,
aWindowOrNull);
}
// First, check to make sure this isn't already handled internally (we don't
// want to let them take over, say "chrome").
let handler = Services.io.getProtocolHandler(aProtocol);
if (!(handler instanceof Ci.nsIExternalProtocolHandler)) {
// This is handled internally, so we don't want them to register
throw this.getSecurityError(
`Permission denied to add ${aURIString} as a protocol handler`,
aWindowOrNull);
}
// check if it is in the black list
let pb = Services.prefs;
let allowed =
pb.getBoolPref(PREF_HANDLER_EXTERNAL_PREFIX + "." + aProtocol,
pb.getBoolPref(PREF_HANDLER_EXTERNAL_PREFIX + "-default"));
if (!allowed) {
throw this.getSecurityError(
`Not allowed to register a protocol handler for ${aProtocol}`,
aWindowOrNull);
}
},
// Return a SecurityError exception from the given Window if one is given. If
// none is given, just return the given error string, for lack of anything
// better.
getSecurityError(errorString, aWindowOrNull) {
if (!aWindowOrNull) {
return errorString;
}
return new aWindowOrNull.DOMException(errorString, "SecurityError");
},
};
function WebContentConverterRegistrar() {
}
@ -191,8 +67,9 @@ WebContentConverterRegistrar.prototype = {
for (let i = 0; i < handlers.length; i++) {
try { // We only want to test web handlers
let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
if (handler.uriTemplate == aURITemplate)
if (handler.uriTemplate == aURITemplate) {
return true;
}
} catch (e) { /* it wasn't a web handler */ }
}
return false;
@ -201,79 +78,67 @@ WebContentConverterRegistrar.prototype = {
/**
* See nsIWebContentHandlerRegistrar
*/
registerProtocolHandler(aProtocol, aURIString, aTitle, aBrowserOrWindow) {
registerProtocolHandler(aProtocol, aURI, aTitle, aDocumentURI, aBrowserOrWindow) {
aProtocol = (aProtocol || "").toLowerCase();
LOG("registerProtocolHandler(" + aProtocol + "," + aURIString + "," + aTitle + ")");
let haveWindow = (aBrowserOrWindow instanceof Ci.nsIDOMWindow);
let uri;
if (haveWindow) {
uri = Utils.checkAndGetURI(aURIString, aBrowserOrWindow);
} else {
// aURIString must not be a relative URI.
uri = Utils.makeURI(aURIString, null);
if (!aURI || !aDocumentURI) {
return;
}
let browser = aBrowserOrWindow; // This is the e10s case.
if (aBrowserOrWindow instanceof Ci.nsIDOMWindow) {
// In the non-e10s case, grab the browser off the same-process window.
let rootDocShell = aBrowserOrWindow.docShell.sameTypeRootTreeItem;
browser = rootDocShell.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
}
let browserWindow = browser.ownerGlobal;
try {
browserWindow.navigator.checkProtocolHandlerAllowed(aProtocol, aURI, aDocumentURI);
} catch (ex) {
// We should have already shown the user an error.
return;
}
// If the protocol handler is already registered, just return early.
if (this._protocolHandlerRegistered(aProtocol, uri.spec)) {
if (this._protocolHandlerRegistered(aProtocol, aURI.spec)) {
return;
}
let browser;
if (haveWindow) {
let browserWindow =
this._getBrowserWindowForContentWindow(aBrowserOrWindow);
browser = this._getBrowserForContentWindow(browserWindow,
aBrowserOrWindow);
} else {
browser = aBrowserOrWindow;
}
if (PrivateBrowsingUtils.isBrowserPrivate(browser)) {
// Inside the private browsing mode, we don't want to alert the user to save
// a protocol handler. We log it to the error console so that web developers
// would have some way to tell what's going wrong.
Services.console.
logStringMessage("Web page denied access to register a protocol handler inside private browsing mode");
return;
}
Utils.checkProtocolHandlerAllowed(aProtocol, aURIString,
haveWindow ? aBrowserOrWindow : null);
// Now Ask the user and provide the proper callback
let message = this._getFormattedString("addProtocolHandlerMessage",
[uri.host, aProtocol]);
[aURI.host, aProtocol]);
let notificationIcon = uri.prePath + "/favicon.ico";
let notificationIcon = aURI.prePath + "/favicon.ico";
let notificationValue = "Protocol Registration: " + aProtocol;
let addButton = {
label: this._getString("addProtocolHandlerAddButton"),
accessKey: this._getString("addProtocolHandlerAddButtonAccesskey"),
protocolInfo: { protocol: aProtocol, uri: uri.spec, name: aTitle },
protocolInfo: { protocol: aProtocol, uri: aURI.spec, name: aTitle },
callback(aNotification, aButtonInfo) {
let protocol = aButtonInfo.protocolInfo.protocol;
let name = aButtonInfo.protocolInfo.name;
let protocol = aButtonInfo.protocolInfo.protocol;
let name = aButtonInfo.protocolInfo.name;
let handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
createInstance(Ci.nsIWebHandlerApp);
handler.name = name;
handler.uriTemplate = aButtonInfo.protocolInfo.uri;
let handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
createInstance(Ci.nsIWebHandlerApp);
handler.name = name;
handler.uriTemplate = aButtonInfo.protocolInfo.uri;
let eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
getService(Ci.nsIExternalProtocolService);
let handlerInfo = eps.getProtocolHandlerInfo(protocol);
handlerInfo.possibleApplicationHandlers.appendElement(handler);
let eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
getService(Ci.nsIExternalProtocolService);
let handlerInfo = eps.getProtocolHandlerInfo(protocol);
handlerInfo.possibleApplicationHandlers.appendElement(handler);
// Since the user has agreed to add a new handler, chances are good
// that the next time they see a handler of this type, they're going
// to want to use it. Reset the handlerInfo to ask before the next
// use.
handlerInfo.alwaysAskBeforeHandling = true;
// Since the user has agreed to add a new handler, chances are good
// that the next time they see a handler of this type, they're going
// to want to use it. Reset the handlerInfo to ask before the next
// use.
handlerInfo.alwaysAskBeforeHandling = true;
let hs = Cc["@mozilla.org/uriloader/handler-service;1"].
getService(Ci.nsIHandlerService);
hs.store(handlerInfo);
},
let hs = Cc["@mozilla.org/uriloader/handler-service;1"].
getService(Ci.nsIHandlerService);
hs.store(handlerInfo);
},
};
let notificationBox = browser.getTabBrowser().getNotificationBox(browser);
notificationBox.appendNotification(message,
@ -283,60 +148,6 @@ WebContentConverterRegistrar.prototype = {
[addButton]);
},
/**
* Returns the browser chrome window in which the content window is in
*/
_getBrowserWindowForContentWindow(aContentWindow) {
return aContentWindow.docShell.rootTreeItem.domWindow
.wrappedJSObject;
},
/**
* Returns the <xul:browser> element associated with the given content
* window.
*
* @param aBrowserWindow
* The browser window in which the content window is in.
* @param aContentWindow
* The content window. It's possible to pass a child content window
* (i.e. the content window of a frame/iframe).
*/
_getBrowserForContentWindow(aBrowserWindow, aContentWindow) {
// This depends on pseudo APIs of browser.js and tabbrowser.xml
aContentWindow = aContentWindow.top;
return aBrowserWindow.gBrowser.browsers.find((browser) =>
browser.contentWindow == aContentWindow);
},
classID: WCCR_CLASSID,
/**
* See nsISupports
*/
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebContentHandlerRegistrar]),
};
function WebContentConverterRegistrarContent() {
}
WebContentConverterRegistrarContent.prototype = {
registerProtocolHandler(aProtocol, aURIString, aTitle, aBrowserOrWindow) {
aProtocol = (aProtocol || "").toLowerCase();
// aBrowserOrWindow must be a window.
let messageManager = aBrowserOrWindow.docShell
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsITabChild)
.messageManager;
let uri = Utils.checkAndGetURI(aURIString, aBrowserOrWindow);
Utils.checkProtocolHandlerAllowed(aProtocol, aURIString, aBrowserOrWindow);
messageManager.sendAsyncMessage("WCCR:registerProtocolHandler",
{ protocol: aProtocol,
uri: uri.spec,
title: aTitle });
},
classID: WCCR_CLASSID,
/**
@ -346,6 +157,4 @@ WebContentConverterRegistrarContent.prototype = {
};
this.NSGetFactory =
(Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) ?
XPCOMUtils.generateNSGetFactory([WebContentConverterRegistrarContent]) :
XPCOMUtils.generateNSGetFactory([WebContentConverterRegistrar]);
XPCOMUtils.generateNSGetFactory([WebContentConverterRegistrar]);

Просмотреть файл

@ -51,8 +51,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=402788
is(testRegisterHandler(true, "fweb+oo", "http://remotehost:8888/%s", "Foo handler"), false, "registering a web+foo protocol handler with a different host should not work");
// restriction to http(s) for the uri of the handler (bug 401343)
// https should work (http already tested in the generic case)
is(testRegisterHandler(true, "web+foo", "https://mochi.test:8888/%s", "Foo handler"), true, "registering a web+foo protocol handler with https scheme should work");
// http is already tested in the generic case
// ftp should not work
is(testRegisterHandler(true, "web+foo", "ftp://mochi.test:8888/%s", "Foo handler"), false, "registering a web+foo protocol handler with ftp scheme should not work");
// chrome should not work

Просмотреть файл

@ -403,7 +403,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
DateTimePickerParent: "resource://gre/modules/DateTimePickerParent.jsm",
Discovery: "resource:///modules/Discovery.jsm",
ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
Feeds: "resource:///modules/Feeds.jsm",
FileSource: "resource://gre/modules/L10nRegistry.jsm",
FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
FxAccounts: "resource://gre/modules/FxAccounts.jsm",
@ -532,7 +531,6 @@ const listeners = {
"RemoteLogins:removeLogin": ["LoginManagerParent"],
"RemoteLogins:insecureLoginFormPresent": ["LoginManagerParent"],
// PLEASE KEEP THIS LIST IN SYNC WITH THE MOBILE LISTENERS IN BrowserCLH.js
"WCCR:registerProtocolHandler": ["Feeds"],
"rtcpeer:CancelRequest": ["webrtcUI"],
"rtcpeer:Request": ["webrtcUI"],
"webrtc:CancelRequest": ["webrtcUI"],

Просмотреть файл

@ -1,23 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = [ "Feeds" ];
var Feeds = {
// Listeners are added in nsBrowserGlue.js
receiveMessage(aMessage) {
let data = aMessage.data;
switch (aMessage.name) {
case "WCCR:registerProtocolHandler": {
let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
getService(Ci.nsIWebContentHandlerRegistrar);
registrar.registerProtocolHandler(data.protocol, data.uri, data.title,
aMessage.target);
break;
}
}
},
};

Просмотреть файл

@ -136,7 +136,6 @@ EXTRA_JS_MODULES += [
'Discovery.jsm',
'ExtensionsUI.jsm',
'FaviconLoader.jsm',
'Feeds.jsm',
'FormValidationHandler.jsm',
'HomePage.jsm',
'LaterRun.jsm',

Просмотреть файл

@ -74,6 +74,10 @@
#include "nsIPresentationService.h"
#include "nsIScriptError.h"
#include "nsIExternalProtocolHandler.h"
#include "TabChild.h"
#include "URIUtils.h"
#include "mozilla/dom/MediaDevices.h"
#include "MediaManager.h"
@ -821,27 +825,179 @@ void Navigator::RegisterContentHandler(const nsAString& aMIMEType,
const nsAString& aTitle,
ErrorResult& aRv) {}
void Navigator::RegisterProtocolHandler(const nsAString& aProtocol,
const nsAString& aURI,
const nsAString& aTitle,
ErrorResult& aRv) {
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
// This list should be kept up-to-date with the spec:
// https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers
static const char* const kSafeSchemes[] = {
"bitcoin", "geo", "im", "irc", "ircs", "magnet", "mailto",
"mms", "news", "nntp", "openpgp4fpr", "sip", "sms", "smsto",
"ssh", "tel", "urn", "webcal", "wtai", "xmpp"};
void Navigator::CheckProtocolHandlerAllowed(const nsAString& aScheme,
nsIURI* aHandlerURI,
nsIURI* aDocumentURI,
ErrorResult& aRv) {
auto raisePermissionDeniedHandler = [&] {
nsAutoCString spec;
aHandlerURI->GetSpec(spec);
nsPrintfCString message("Permission denied to add %s as a protocol handler",
spec.get());
aRv.ThrowDOMException(NS_ERROR_DOM_SECURITY_ERR, message);
};
auto raisePermissionDeniedScheme = [&] {
nsPrintfCString message(
"Permission denied to add a protocol handler for %s",
NS_ConvertUTF16toUTF8(aScheme).get());
aRv.ThrowDOMException(NS_ERROR_DOM_SECURITY_ERR, message);
};
if (!aDocumentURI || !aHandlerURI) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
if (!mWindow->IsSecureContext() && mWindow->GetDoc()) {
mWindow->GetDoc()->WarnOnceAbout(
nsIDocument::eRegisterProtocolHandlerInsecure);
nsCString spec;
aHandlerURI->GetSpec(spec);
// If the uri doesn't contain '%s', it won't be a good handler - the %s
// gets replaced with the handled URI.
if (!FindInReadable(NS_LITERAL_CSTRING("%s"), spec)) {
aRv.ThrowDOMException(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
// For security reasons we reject non-http(s) urls (see bug 354316),
nsAutoCString docScheme;
nsAutoCString handlerScheme;
aDocumentURI->GetScheme(docScheme);
aHandlerURI->GetScheme(handlerScheme);
if ((!docScheme.EqualsLiteral("https") && !docScheme.EqualsLiteral("http")) ||
(!handlerScheme.EqualsLiteral("https") &&
!handlerScheme.EqualsLiteral("http"))) {
raisePermissionDeniedHandler();
return;
}
// Should be same-origin:
nsAutoCString handlerHost;
aHandlerURI->GetHostPort(handlerHost);
nsAutoCString documentHost;
aDocumentURI->GetHostPort(documentHost);
if (!handlerHost.Equals(documentHost) || !handlerScheme.Equals(docScheme)) {
raisePermissionDeniedHandler();
return;
}
// Having checked the handler URI, check the scheme:
nsAutoCString scheme;
ToLowerCase(NS_ConvertUTF16toUTF8(aScheme), scheme);
if (StringBeginsWith(scheme, NS_LITERAL_CSTRING("web+"))) {
// Check for non-ascii
nsReadingIterator<char> iter;
nsReadingIterator<char> iterEnd;
auto remainingScheme = Substring(scheme, 4 /* web+ */);
remainingScheme.BeginReading(iter);
remainingScheme.EndReading(iterEnd);
// Scheme suffix must be non-empty
if (iter == iterEnd) {
raisePermissionDeniedScheme();
return;
}
for (; iter != iterEnd; iter++) {
if (*iter < 'a' || *iter > 'z') {
raisePermissionDeniedScheme();
return;
}
}
} else {
bool matches = false;
for (const char* safeScheme : kSafeSchemes) {
if (scheme.Equals(safeScheme)) {
matches = true;
break;
}
}
if (!matches) {
raisePermissionDeniedScheme();
return;
}
}
nsCOMPtr<nsIProtocolHandler> handler;
nsCOMPtr<nsIIOService> io = services::GetIOService();
if (NS_FAILED(
io->GetProtocolHandler(scheme.get(), getter_AddRefs(handler)))) {
raisePermissionDeniedScheme();
return;
}
// Check to make sure this isn't already handled internally (we don't
// want to let them take over, say "chrome"). In theory, the checks above
// should have already taken care of this.
nsCOMPtr<nsIExternalProtocolHandler> externalHandler =
do_QueryInterface(handler);
MOZ_RELEASE_ASSERT(
externalHandler,
"We should never allow overriding a builtin protocol handler");
// check if we have prefs set saying not to add this.
bool defaultExternal =
Preferences::GetBool("network.protocol-handler.external-default");
nsPrintfCString specificPref("network.protocol-handler.external.%s",
scheme.get());
if (!Preferences::GetBool(specificPref.get(), defaultExternal)) {
raisePermissionDeniedScheme();
return;
}
}
void Navigator::RegisterProtocolHandler(const nsAString& aScheme,
const nsAString& aURI,
const nsAString& aTitle,
ErrorResult& aRv) {
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell() ||
!mWindow->GetDoc()) {
return;
}
nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(mWindow);
if (loadContext->UsePrivateBrowsing()) {
// If we're a private window, don't alert the user or webpage. We log to the
// console so that web developers have some way to tell what's going wrong.
nsContentUtils::ReportToConsole(
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"),
mWindow->GetDoc(), nsContentUtils::eDOM_PROPERTIES,
"RegisterProtocolHandlerPrivateBrowsingWarning");
return;
}
nsCOMPtr<nsIDocument> doc = mWindow->GetDoc();
if (!mWindow->IsSecureContext()) {
doc->WarnOnceAbout(nsIDocument::eRegisterProtocolHandlerInsecure);
}
// Determine if doc is allowed to assign this handler
nsIURI* docURI = doc->GetDocumentURIObject();
nsCOMPtr<nsIURI> handlerURI;
NS_NewURI(getter_AddRefs(handlerURI), NS_ConvertUTF16toUTF8(aURI),
doc->GetDocumentCharacterSet(), docURI);
CheckProtocolHandlerAllowed(aScheme, handlerURI, docURI, aRv);
if (aRv.Failed()) {
return;
}
if (XRE_IsContentProcess()) {
nsAutoString scheme(aScheme);
nsAutoString title(aTitle);
RefPtr<TabChild> tabChild = TabChild::GetFrom(mWindow);
tabChild->SendRegisterProtocolHandler(scheme, handlerURI, title, docURI);
return;
}
nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
if (!registrar) {
return;
if (registrar) {
aRv = registrar->RegisterProtocolHandler(aScheme, handlerURI, aTitle,
docURI, mWindow->GetOuterWindow());
}
aRv = registrar->RegisterProtocolHandler(aProtocol, aURI, aTitle,
mWindow->GetOuterWindow());
}
Geolocation* Navigator::GetGeolocation(ErrorResult& aRv) {

Просмотреть файл

@ -113,6 +113,9 @@ class Navigator final : public nsISupports, public nsWrapperCache {
void GetUserAgent(nsAString& aUserAgent, CallerType aCallerType,
ErrorResult& aRv) const;
bool OnLine();
void CheckProtocolHandlerAllowed(const nsAString& aScheme,
nsIURI* aHandlerURI, nsIURI* aDocumentURI,
ErrorResult& aRv);
void RegisterProtocolHandler(const nsAString& aScheme, const nsAString& aURL,
const nsAString& aTitle, ErrorResult& aRv);
void RegisterContentHandler(const nsAString& aMIMEType, const nsAString& aURL,

Просмотреть файл

@ -6,6 +6,8 @@
#include "nsISupports.idl"
interface nsIURI;
/**
* nsIWebContentHandlerRegistrar
*
@ -26,8 +28,9 @@ interface nsIWebContentHandlerRegistrar : nsISupports
* content window from which the method has been called.
*/
void registerProtocolHandler(in AString protocol,
in AString uri,
in nsIURI uri,
in AString title,
in nsIURI documentURI,
in nsISupports windowOrBrowser);
/**
* Removes a registered protocol handler

Просмотреть файл

@ -88,6 +88,7 @@ using mozilla::FontRange from "ipc/nsGUIEventIPC.h";
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using mozilla::dom::BrowsingContextId from "mozilla/dom/ipc/IdType.h";
using refcounted class nsIURI from "mozilla/ipc/URIUtils.h";
namespace mozilla {
namespace dom {
@ -521,6 +522,9 @@ parent:
async SetHasBeforeUnload(bool aHasBeforeUnload);
async RegisterProtocolHandler(nsString scheme, nsIURI handlerURI, nsString title,
nsIURI documentURI);
child:
async NativeSynthesisResponse(uint64_t aObserverId, nsCString aResponse);

Просмотреть файл

@ -63,6 +63,7 @@
#include "nsIURI.h"
#include "nsIWindowWatcher.h"
#include "nsIWebBrowserChrome.h"
#include "nsIWebContentHandlerRegistrar.h"
#include "nsIXULBrowserWindow.h"
#include "nsIXULWindow.h"
#include "nsViewManager.h"
@ -2099,6 +2100,19 @@ mozilla::ipc::IPCResult TabParent::RecvSetHasBeforeUnload(
return IPC_OK();
}
mozilla::ipc::IPCResult TabParent::RecvRegisterProtocolHandler(
const nsString& aScheme, nsIURI* aHandlerURI, const nsString& aTitle,
nsIURI* aDocURI) {
nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
if (registrar) {
registrar->RegisterProtocolHandler(aScheme, aHandlerURI, aTitle, aDocURI,
mFrameElement);
}
return IPC_OK();
}
bool TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {

Просмотреть файл

@ -156,6 +156,10 @@ class TabParent final : public PBrowserParent,
virtual mozilla::ipc::IPCResult RecvSetHasBeforeUnload(
const bool& aHasBeforeUnload) override;
virtual mozilla::ipc::IPCResult RecvRegisterProtocolHandler(
const nsString& aScheme, nsIURI* aHandlerURI, const nsString& aTitle,
nsIURI* aDocURI) override;
virtual mozilla::ipc::IPCResult RecvBrowserFrameOpenWindow(
PBrowserParent* aOpener, const nsString& aURL, const nsString& aName,
const nsString& aFeatures,

Просмотреть файл

@ -344,6 +344,8 @@ InvalidKeyframePropertyValue=Keyframe property value “%1$S” is invalid accor
ReadableStreamReadingFailed=Failed to read data from the ReadableStream: “%S”.
# LOCALIZATION NOTE: Do not translate "registerProtocolHandler".
RegisterProtocolHandlerInsecureWarning=Use of the registerProtocolHandler for insecure connections will be removed in version 62.
# LOCALIZATION NOTE: Do not translate "registerProtocolHandler"
RegisterProtocolHandlerPrivateBrowsingWarning=Cant use registerProtocolHandler inside private browsing mode.
MixedDisplayObjectSubrequestWarning=Loading insecure content within a plugin embedded in a secure connection is going to be removed.
MotionEventWarning=Use of the motion sensor is deprecated.
OrientationEventWarning=Use of the orientation sensor is deprecated.

Просмотреть файл

@ -23,6 +23,8 @@
* and create derivative works of this document.
*/
interface URI;
// http://www.whatwg.org/specs/web-apps/current-work/#the-navigator-object
[HeaderFile="Navigator.h"]
interface Navigator {
@ -80,6 +82,8 @@ interface NavigatorOnLine {
[NoInterfaceObject]
interface NavigatorContentUtils {
// content handler registration
[Throws, ChromeOnly]
void checkProtocolHandlerAllowed(DOMString scheme, URI handlerURI, URI documentURI);
[Throws, Func="nsGlobalWindowInner::RegisterProtocolHandlerAllowedForContext"]
void registerProtocolHandler(DOMString scheme, DOMString url, DOMString title);
[Pref="dom.registerContentHandler.enabled", Throws]

Просмотреть файл

@ -1,180 +0,0 @@
[protocol.https.html]
[a url argument pointing to a different domain name, without %s should throw SYNTAX_ERR]
expected: FAIL
[a protocol argument containing non-alphanumeric characters (like a cyrillic “а”) should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the mocha protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the res protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the view-source protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the blob protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[%s instead of domain name should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a protocol argument containing :// should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the opera protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the cid protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a url argument pointing to a non-http[s\] scheme should throw SECURITY_ERR due to not being of the same origin]
expected:
if os == "android": FAIL
[a protocol argument containing an unrecognized scheme should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a url argument pointing to a different domain name should throw SECURITY_ERR (2)]
expected:
if os == "android": FAIL
[attempting to override the javascript protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the operamail protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a url argument without %s (but with %) should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[a protocol argument containing : should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the http protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[an empty url argument should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the wyciwyg protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a protocol argument containing a backspace character should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the tcl protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a url argument without %s should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the about protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the chrome protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a protocol argument containing http:// should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the wss protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a protocol argument containing a LF character should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the mid protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a url argument pointing to a different domain name should throw SECURITY_ERR (3)]
expected:
if os == "android": FAIL
[attempting to override the ftp protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[%s instead of subdomain name should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the file protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the vbscript protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[looping handlers should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a url argument without %s (but with %a) should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the attachment protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the shttp protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a protocol argument containing a null character should throw SYNTAX_ERR]
expected:
if os == "android": FAIL
[attempting to override the livescript protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the https protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[a url argument pointing to a different domain name should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the data protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the resource protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL
[attempting to override the ws protocol should throw SECURITY_ERR]
expected:
if os == "android": FAIL