From b6d62587629802ab9a01550cacb3e39b9c20d80c Mon Sep 17 00:00:00 2001 From: roytam1 Date: Thu, 24 Mar 2022 11:03:39 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1182537 - Use channel->ascynOpen2 in dom/security/nsCORSListenerProxy (r=sicking) (5c4b779a12) - Bug 1155758 - Make about:serviceworkers work in B2G. r=fabrice (195eca3894) - Bug 1162920 - JavaScript error at aboutServiceWorkers.js when updating the service worker. r=fabrice (2d3a831a8c) - Bug 1155153 - [e10s] about:serviceworkers should work in e10s mode. Update B2G implementation. r=baku (0d1c2999c1) - Bug 1171915 - about:serviceworkers in b2g should use originAttributes when calling ServiceWorkerManager. r=baku,fabrice (faa3725da9) - Bug 1179161 - originAttributes does not have such isInBrowser member (follow-up bug 1171915). r=ferjm (a217140ae5) - Bug 1171917 - Improve about:serviceworkers tests on b2g. r=ferjm (5fd9d2f478) - Bug 1179557 - Add userContextId to originAttributes with tests. r=bholley, r=tanvi (8ddf96d921) - Bug 1179557 - Add getters for userContextId. r=bholley, r=tanvi (ebec5f7c7e) - Bug 1174110 - The service worker still remains registered when uninstalling the service-worker-enabled application. r=fabrice (c1c93b1250) - Bug 1144689 - Allow setting manually a fetch time and modified time for cache entries. r=fabrice (8e9dd47425) - Bug 1150199 - Langpacks should not have to be privileged r=ferjm (d41af25648) - Bug 1111961 - Developer mode support r=ferjm,pauljt (9b523402ac) - Bug 1168300 - notify clear-cookiejar-data. r=sicking (7d88bff29d) - Bug 1136434 - RequestSync API should delete all the timers when a task is unregistered, r=ehsan (5f92977920) - Bug 1151082 - RequestSyncAPI - avoid infinite loop when processing pending messages, r=ehsan (b5afcd55e8) - Bug 1165787 - Use origin in RequestSyncService.jsm. r=ehsan (b6fad2bd68) - Bug 1182347 - Migrate existing code away from .cookieJar. r=sicking,r=allstars.chh (304cbfd660) - Bug 1118946 - API to provide localized properties r=ferjm,sicking (a28aecaf19) - Bug 1077168 - Cancel in-flight Webapp install jobs from windows that change location. r=myk. (d55dc8ff6d) - Bug 1150660 - Fix sendAsyncMessage() uses to not trigger warnings in dom/apps r=fabrice (b087adcc23) - Bug 1169344 - Allow server apps to restrict access to their IAC ports. r=ferjm (82c8570555) - Bug 1068400 - Fix devtools when morphing non-e10s tab into e10s one. r=jryans (55be5ccdf5) - Bug 1145049 - Prevent caching tab actors in child processes. r=jryans (1a3ee9f278) - Bug 1145049 - Stop leaking tab actors and root actor on disconnect. r=jryans (26f259b441) - Bug 1181930 - Refactoring: move the message broadcaster out of Webapps.jsm r=ferjm (b1f8bb8b6d) - Bu 1115619 - Use a preference to guarantee app permission loading to permissions.sqlite. r=fabrice (5689c459d7) - Bug 1191579 - Remove useless getAll() implementation in Webapps.jsm (74f0d6874a) --- .gitignore | 1 + b2g/chrome/content/shell.js | 1 + b2g/components/AboutServiceWorkers.jsm | 189 +++++++ b2g/components/moz.build | 1 + b2g/components/test/mochitest/app/client.html | 17 + b2g/components/test/mochitest/app/index.html | 84 +++ .../test/mochitest/app/manifest.webapp | 5 + .../mochitest/app/manifest.webapp^headers^ | 1 + b2g/components/test/mochitest/app/sw.sjs | 28 + .../test/mochitest/app/version.html | 19 + .../test/mochitest/app/wait_for_update.html | 25 + b2g/components/test/mochitest/chrome.ini | 6 + .../mochitest/test_aboutserviceworkers.html | 278 ++++++++++ b2g/components/test/moz.build | 1 + .../test/unit/test_aboutserviceworkers.js | 142 +++++ caps/BasePrincipal.cpp | 23 + caps/BasePrincipal.h | 9 +- caps/nsIPrincipal.idl | 9 +- caps/nsIScriptSecurityManager.idl | 4 +- caps/nsNullPrincipal.h | 4 +- caps/nsPrincipal.h | 4 +- caps/tests/unit/test_origin.js | 23 + dom/apps/AppsUtils.jsm | 33 +- dom/apps/ImportExport.jsm | 26 +- dom/apps/InterAppCommService.jsm | 83 ++- dom/apps/Langpacks.jsm | 151 +++++- dom/apps/MessageBroadcaster.jsm | 132 +++++ dom/apps/OfflineCacheInstaller.jsm | 132 +++-- dom/apps/PermissionsInstaller.jsm | 3 +- dom/apps/Webapps.js | 40 +- dom/apps/Webapps.jsm | 488 +++++++++--------- dom/apps/moz.build | 3 +- dom/apps/tests/file_hosted_certified.webapp | 6 + .../file_hosted_certified.webapp^headers^ | 1 + dom/apps/tests/langpack/fr/manifest.json | 8 + dom/apps/tests/langpack/lang1.webapp | 4 +- dom/apps/tests/langpack/lang2.webapp | 8 +- dom/apps/tests/langpack/localizedvalues.html | 74 +++ dom/apps/tests/langpack/manifest.webapp | 8 +- .../tests/langpack/manifest_no_version.webapp | 8 + .../langpack/manifest_version_xyz.webapp | 9 + dom/apps/tests/mochitest.ini | 5 + dom/apps/tests/test_bug_1168300.html | 123 +++++ dom/apps/tests/test_install_dev_mode.html | 122 +++++ dom/apps/tests/test_langpacks.html | 95 ++++ dom/apps/tests/unit/test_moziapplication.js | 2 +- .../mozIApplicationClearPrivateDataParams.idl | 1 + dom/requestsync/RequestSyncService.jsm | 40 +- dom/requestsync/tests/mochitest.ini | 1 + dom/requestsync/tests/test_bug1151082.html | 79 +++ dom/tests/mochitest/webapps/head.js | 32 ++ .../mochitest/webapps/test_bug_771294.xul | 42 +- dom/webidl/Apps.webidl | 6 + dom/webidl/ChromeUtils.webidl | 2 + modules/libpref/init/all.js | 3 + netwerk/protocol/http/nsCORSListenerProxy.cpp | 83 +-- toolkit/devtools/server/actors/childtab.js | 48 +- .../server/actors/director-registry.js | 4 +- toolkit/devtools/server/actors/root.js | 5 + toolkit/devtools/server/actors/webapps.js | 42 +- toolkit/devtools/server/actors/webbrowser.js | 59 ++- toolkit/devtools/server/child.js | 17 +- .../server/docs/lazy-actor-modules.md | 10 +- toolkit/devtools/server/main.js | 121 +++-- 64 files changed, 2432 insertions(+), 601 deletions(-) create mode 100644 b2g/components/AboutServiceWorkers.jsm create mode 100644 b2g/components/test/mochitest/app/client.html create mode 100644 b2g/components/test/mochitest/app/index.html create mode 100644 b2g/components/test/mochitest/app/manifest.webapp create mode 100644 b2g/components/test/mochitest/app/manifest.webapp^headers^ create mode 100644 b2g/components/test/mochitest/app/sw.sjs create mode 100644 b2g/components/test/mochitest/app/version.html create mode 100644 b2g/components/test/mochitest/app/wait_for_update.html create mode 100644 b2g/components/test/mochitest/chrome.ini create mode 100644 b2g/components/test/mochitest/test_aboutserviceworkers.html create mode 100644 b2g/components/test/unit/test_aboutserviceworkers.js create mode 100644 dom/apps/MessageBroadcaster.jsm create mode 100644 dom/apps/tests/file_hosted_certified.webapp create mode 100644 dom/apps/tests/file_hosted_certified.webapp^headers^ create mode 100644 dom/apps/tests/langpack/fr/manifest.json create mode 100644 dom/apps/tests/langpack/localizedvalues.html create mode 100644 dom/apps/tests/langpack/manifest_no_version.webapp create mode 100644 dom/apps/tests/langpack/manifest_version_xyz.webapp create mode 100644 dom/apps/tests/test_bug_1168300.html create mode 100644 dom/apps/tests/test_install_dev_mode.html create mode 100644 dom/requestsync/tests/test_bug1151082.html diff --git a/.gitignore b/.gitignore index 3ded48f0ae..279b77924b 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ ID # Vim swap files. .*.sw[a-z] +.sw[a-z] # Emacs directory variable files. **/.dir-locals.el diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index 42eb4f4954..a410c1be05 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -30,6 +30,7 @@ Cu.import('resource://gre/modules/FxAccountsMgmtService.jsm'); Cu.import('resource://gre/modules/DownloadsAPI.jsm'); Cu.import('resource://gre/modules/MobileIdentityManager.jsm'); Cu.import('resource://gre/modules/PresentationDeviceInfoManager.jsm'); +Cu.import('resource://gre/modules/AboutServiceWorkers.jsm'); XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm"); diff --git a/b2g/components/AboutServiceWorkers.jsm b/b2g/components/AboutServiceWorkers.jsm new file mode 100644 index 0000000000..350e20143b --- /dev/null +++ b/b2g/components/AboutServiceWorkers.jsm @@ -0,0 +1,189 @@ +/* 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" + +this.EXPORTED_SYMBOLS = ["AboutServiceWorkers"]; + +const { interfaces: Ci, utils: Cu } = Components; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", + "resource://gre/modules/SystemAppProxy.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager", + "@mozilla.org/serviceworkers/manager;1", + "nsIServiceWorkerManager"); + +function debug(aMsg) { + dump("AboutServiceWorkers - " + aMsg + "\n"); +} + +function serializeServiceWorkerInfo(aServiceWorkerInfo) { + if (!aServiceWorkerInfo) { + throw new Error("Invalid service worker information"); + } + + let result = {}; + + Object.keys(aServiceWorkerInfo).forEach(property => { + if (typeof aServiceWorkerInfo[property] == "function") { + return; + } + if (property === "principal") { + result.principal = { + origin: aServiceWorkerInfo.principal.origin, + originAttributes: aServiceWorkerInfo.principal.originAttributes + }; + return; + } + result[property] = aServiceWorkerInfo[property]; + }); + + return result; +} + + +this.AboutServiceWorkers = { + get enabled() { + if (this._enabled) { + return this._enabled; + } + this._enabled = false; + try { + this._enabled = Services.prefs.getBoolPref("dom.serviceWorkers.enabled"); + } catch(e) {} + return this._enabled; + }, + + init: function() { + SystemAppProxy.addEventListener("mozAboutServiceWorkersContentEvent", + AboutServiceWorkers); + }, + + sendResult: function(aId, aResult) { + SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", { + id: aId, + result: aResult + }); + }, + + sendError: function(aId, aError) { + SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", { + id: aId, + error: aError + }); + }, + + handleEvent: function(aEvent) { + let message = aEvent.detail; + + debug("Got content event " + JSON.stringify(message)); + + if (!message.id || !message.name) { + dump("Invalid event " + JSON.stringify(message) + "\n"); + return; + } + + let self = AboutServiceWorkers; + + switch(message.name) { + case "init": + if (!self.enabled) { + self.sendResult(message.id, { + enabled: false, + registrations: [] + }); + return; + }; + + let data = gServiceWorkerManager.getAllRegistrations(); + if (!data) { + self.sendError(message.id, "NoServiceWorkersRegistrations"); + return; + } + + let registrations = []; + + for (let i = 0; i < data.length; i++) { + let info = data.queryElementAt(i, Ci.nsIServiceWorkerInfo); + if (!info) { + dump("AboutServiceWorkers: Invalid nsIServiceWorkerInfo " + + "interface.\n"); + continue; + } + registrations.push(serializeServiceWorkerInfo(info)); + } + + self.sendResult(message.id, { + enabled: self.enabled, + registrations: registrations + }); + break; + + case "update": + if (!message.scope) { + self.sendError(message.id, "MissingScope"); + return; + } + + if (!message.principal || + !message.principal.originAttributes) { + self.sendError(message.id, "MissingOriginAttributes"); + return; + } + + gServiceWorkerManager.propagateSoftUpdate( + message.principal.originAttributes, + message.scope + ); + + self.sendResult(message.id, true); + break; + + case "unregister": + if (!message.principal || + !message.principal.origin || + !message.principal.originAttributes || + !message.principal.originAttributes.appId || + (message.principal.originAttributes.inBrowser == null)) { + self.sendError(message.id, "MissingPrincipal"); + return; + } + + let principal = Services.scriptSecurityManager.getAppCodebasePrincipal( + Services.io.newURI(message.principal.origin, null, null), + message.principal.originAttributes.appId, + message.principal.originAttributes.inBrowser + ); + + if (!message.scope) { + self.sendError(message.id, "MissingScope"); + return; + } + + let serviceWorkerUnregisterCallback = { + unregisterSucceeded: function() { + self.sendResult(message.id, true); + }, + + unregisterFailed: function() { + self.sendError(message.id, "UnregisterError"); + }, + + QueryInterface: XPCOMUtils.generateQI([ + Ci.nsIServiceWorkerUnregisterCallback + ]) + }; + gServiceWorkerManager.propagateUnregister(principal, + serviceWorkerUnregisterCallback, + message.scope); + break; + } + } +}; + +AboutServiceWorkers.init(); diff --git a/b2g/components/moz.build b/b2g/components/moz.build index 6c82860ab8..07a7943708 100644 --- a/b2g/components/moz.build +++ b/b2g/components/moz.build @@ -50,6 +50,7 @@ if CONFIG['MOZ_UPDATER']: ] EXTRA_JS_MODULES += [ + 'AboutServiceWorkers.jsm', 'AlertsHelper.jsm', 'Bootstraper.jsm', 'ContentRequestHelper.jsm', diff --git a/b2g/components/test/mochitest/app/client.html b/b2g/components/test/mochitest/app/client.html new file mode 100644 index 0000000000..ffc93a4c2c --- /dev/null +++ b/b2g/components/test/mochitest/app/client.html @@ -0,0 +1,17 @@ + + + + Test app for bug 1171917 + + + + + diff --git a/b2g/components/test/mochitest/app/index.html b/b2g/components/test/mochitest/app/index.html new file mode 100644 index 0000000000..91433092fb --- /dev/null +++ b/b2g/components/test/mochitest/app/index.html @@ -0,0 +1,84 @@ + + + + Test app for bug 1171917 + + + + + diff --git a/b2g/components/test/mochitest/app/manifest.webapp b/b2g/components/test/mochitest/app/manifest.webapp new file mode 100644 index 0000000000..b7edb2b95f --- /dev/null +++ b/b2g/components/test/mochitest/app/manifest.webapp @@ -0,0 +1,5 @@ +{ + "name": "App", + "launch_path": "/index.html", + "description": "Test app for bug 1171917" +} diff --git a/b2g/components/test/mochitest/app/manifest.webapp^headers^ b/b2g/components/test/mochitest/app/manifest.webapp^headers^ new file mode 100644 index 0000000000..90818c6398 --- /dev/null +++ b/b2g/components/test/mochitest/app/manifest.webapp^headers^ @@ -0,0 +1 @@ +Content-Type: application/manifest+json diff --git a/b2g/components/test/mochitest/app/sw.sjs b/b2g/components/test/mochitest/app/sw.sjs new file mode 100644 index 0000000000..67b6b2d8d8 --- /dev/null +++ b/b2g/components/test/mochitest/app/sw.sjs @@ -0,0 +1,28 @@ +// The update process does not complete unless the service worker script changes. +// The service worker script is a server-side JS file which allows us to get a +// slightly different service worker script file each time the file is fetched. +// Everytime there is either a registration or an update the script will be +// fetched and a slightly different version of the script will be returned. + +function handleRequest(request, response) { + var stateName = request.scheme + "counter"; + if (!getState(stateName)) { + setState(stateName, "1"); + } else { + // Make sure that we pass a string value to setState! + setState(stateName, "" + (parseInt(getState(stateName)) + 1)); + } + response.setHeader("Content-Type", "application/javascript", false); + response.write(getScript(stateName)); +} + +function getScript(stateName) { + return "oninstall = function(evt) {" + + "evt.waitUntil(self.skipWaiting());" + + "}; " + + "onfetch = function(evt) {" + + "if (evt.request.url.indexOf('get-sw-version') > -1) {" + + "evt.respondWith(new Response('" + getState(stateName) + "'));" + + "}" + + "};"; +} diff --git a/b2g/components/test/mochitest/app/version.html b/b2g/components/test/mochitest/app/version.html new file mode 100644 index 0000000000..6121ddce6d --- /dev/null +++ b/b2g/components/test/mochitest/app/version.html @@ -0,0 +1,19 @@ + + + + Test app for bug 1171917 + + + + + diff --git a/b2g/components/test/mochitest/app/wait_for_update.html b/b2g/components/test/mochitest/app/wait_for_update.html new file mode 100644 index 0000000000..e5818a05a3 --- /dev/null +++ b/b2g/components/test/mochitest/app/wait_for_update.html @@ -0,0 +1,25 @@ + + + + Test app for bug 1171917 + + + + + diff --git a/b2g/components/test/mochitest/chrome.ini b/b2g/components/test/mochitest/chrome.ini new file mode 100644 index 0000000000..0662e40bc2 --- /dev/null +++ b/b2g/components/test/mochitest/chrome.ini @@ -0,0 +1,6 @@ +[DEFAULT] +skip-if = toolkit != "gonk" +support-files = + app/* + +[test_aboutserviceworkers.html] diff --git a/b2g/components/test/mochitest/test_aboutserviceworkers.html b/b2g/components/test/mochitest/test_aboutserviceworkers.html new file mode 100644 index 0000000000..b239bf41c8 --- /dev/null +++ b/b2g/components/test/mochitest/test_aboutserviceworkers.html @@ -0,0 +1,278 @@ + + + + + + Test for Bug 1171917 + + + + + +Mozilla Bug 1171917 +

+ +
+
+
+ + diff --git a/b2g/components/test/moz.build b/b2g/components/test/moz.build index b985130de0..00b6f1720f 100644 --- a/b2g/components/test/moz.build +++ b/b2g/components/test/moz.build @@ -6,3 +6,4 @@ XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini'] MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini'] +MOCHITEST_CHROME_MANIFESTS += ['mochitest/chrome.ini'] diff --git a/b2g/components/test/unit/test_aboutserviceworkers.js b/b2g/components/test/unit/test_aboutserviceworkers.js new file mode 100644 index 0000000000..56273f1ce2 --- /dev/null +++ b/b2g/components/test/unit/test_aboutserviceworkers.js @@ -0,0 +1,142 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "AboutServiceWorkers", + "resource://gre/modules/AboutServiceWorkers.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager", + "@mozilla.org/serviceworkers/manager;1", + "nsIServiceWorkerManager"); + +const CHROME_MSG = "mozAboutServiceWorkersChromeEvent"; + +const ORIGINAL_SENDRESULT = AboutServiceWorkers.sendResult; +const ORIGINAL_SENDERROR = AboutServiceWorkers.sendError; + +do_get_profile(); + +let mockSendResult = (aId, aResult) => { + let msg = { + id: aId, + result: aResult + }; + Services.obs.notifyObservers({wrappedJSObject: msg}, CHROME_MSG, null); +}; + +let mockSendError = (aId, aError) => { + let msg = { + id: aId, + result: aError + }; + Services.obs.notifyObservers({wrappedJSObject: msg}, CHROME_MSG, null); +}; + +function attachMocks() { + AboutServiceWorkers.sendResult = mockSendResult; + AboutServiceWorkers.sendError = mockSendError; +} + +function restoreMocks() { + AboutServiceWorkers.sendResult = ORIGINAL_SENDRESULT; + AboutServiceWorkers.sendError = ORIGINAL_SENDERROR; +} + +do_register_cleanup(restoreMocks); + +function run_test() { + run_next_test(); +} + +/** + * "init" tests + */ +[ +// Pref disabled, no registrations +{ + prefEnabled: false, + expectedMessage: { + id: Date.now(), + result: { + enabled: false, + registrations: [] + } + } +}, +// Pref enabled, no registrations +{ + prefEnabled: true, + expectedMessage: { + id: Date.now(), + result: { + enabled: true, + registrations: [] + } + } +}].forEach(test => { + add_test(function() { + Services.prefs.setBoolPref("dom.serviceWorkers.enabled", test.prefEnabled); + + let id = test.expectedMessage.id; + + function onMessage(subject, topic, data) { + let message = subject.wrappedJSObject; + let expected = test.expectedMessage; + + do_check_true(message.id, "Message should have id"); + do_check_eq(message.id, test.expectedMessage.id, + "Id should be the expected one"); + do_check_eq(message.result.enabled, expected.result.enabled, + "Pref should be disabled"); + do_check_true(message.result.registrations, "Registrations should exist"); + do_check_eq(message.result.registrations.length, + expected.result.registrations.length, + "Registrations length should be the expected one"); + + Services.obs.removeObserver(onMessage, CHROME_MSG); + + run_next_test(); + } + + Services.obs.addObserver(onMessage, CHROME_MSG, false); + + attachMocks(); + + AboutServiceWorkers.handleEvent({ detail: { + id: id, + name: "init" + }}); + }); +}); + +/** + * ServiceWorkerManager tests. + */ + +// We cannot register a sw via ServiceWorkerManager cause chrome +// registrations are not allowed. +// All we can do for now is to test the interface of the swm. +add_test(function test_swm() { + do_check_true(gServiceWorkerManager, "SWM exists"); + do_check_true(gServiceWorkerManager.getAllRegistrations, + "SWM.getAllRegistrations exists"); + do_check_true(typeof gServiceWorkerManager.getAllRegistrations == "function", + "SWM.getAllRegistrations is a function"); + do_check_true(gServiceWorkerManager.propagateSoftUpdate, + "SWM.propagateSoftUpdate exists"); + do_check_true(typeof gServiceWorkerManager.propagateSoftUpdate == "function", + + "SWM.propagateSoftUpdate is a function"); + do_check_true(gServiceWorkerManager.propagateUnregister, + "SWM.propagateUnregister exists"); + do_check_true(typeof gServiceWorkerManager.propagateUnregister == "function", + "SWM.propagateUnregister exists"); + + run_next_test(); +}); diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp index cc77bcb9b5..210ac1ee6d 100644 --- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -47,6 +47,12 @@ OriginAttributes::CreateSuffix(nsACString& aStr) const params->Set(NS_LITERAL_STRING("addonId"), mAddonId); } + if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) { + value.Truncate(); + value.AppendInt(mUserContextId); + params->Set(NS_LITERAL_STRING("userContextId"), value); + } + aStr.Truncate(); params->Serialize(value); @@ -100,6 +106,16 @@ public: return true; } + if (aName.EqualsLiteral("userContextId")) { + nsresult rv; + mOriginAttributes->mUserContextId = aValue.ToInteger(&rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + + return true; + } + // No other attributes are supported. return false; } @@ -288,6 +304,13 @@ BasePrincipal::GetAppId(uint32_t* aAppId) return NS_OK; } +NS_IMETHODIMP +BasePrincipal::GetUserContextId(uint32_t* aUserContextId) +{ + *aUserContextId = UserContextId(); + return NS_OK; +} + NS_IMETHODIMP BasePrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement) { diff --git a/caps/BasePrincipal.h b/caps/BasePrincipal.h index 659b3508a2..988b84191b 100644 --- a/caps/BasePrincipal.h +++ b/caps/BasePrincipal.h @@ -35,7 +35,8 @@ public: { return mAppId == aOther.mAppId && mInBrowser == aOther.mInBrowser && - mAddonId == aOther.mAddonId; + mAddonId == aOther.mAddonId && + mUserContextId == aOther.mUserContextId; } bool operator!=(const OriginAttributes& aOther) const { @@ -83,6 +84,10 @@ public: return false; } + if (mUserContextId.WasPassed() && mUserContextId.Value() != aAttrs.mUserContextId) { + return false; + } + return true; } }; @@ -118,6 +123,7 @@ public: NS_IMETHOD GetAppId(uint32_t* aAppStatus) final; NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement) final; NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final; + NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final; virtual bool IsOnCSSUnprefixingWhitelist() override { return false; } @@ -128,6 +134,7 @@ public: const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; } uint32_t AppId() const { return mOriginAttributes.mAppId; } + uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; } bool IsInBrowserElement() const { return mOriginAttributes.mInBrowser; } protected: diff --git a/caps/nsIPrincipal.idl b/caps/nsIPrincipal.idl index 98bfff2f03..28c75eb1df 100644 --- a/caps/nsIPrincipal.idl +++ b/caps/nsIPrincipal.idl @@ -20,7 +20,7 @@ interface nsIContentSecurityPolicy; [ptr] native JSPrincipals(JSPrincipals); [ptr] native PrincipalArray(nsTArray >); -[scriptable, builtinclass, uuid(7a9aa074-7565-4567-af2f-9e3704c7af9e)] +[scriptable, builtinclass, uuid(a083acd0-1ebf-4585-85ab-08cfdd9c96bd)] interface nsIPrincipal : nsISerializable { /** @@ -250,6 +250,13 @@ interface nsIPrincipal : nsISerializable */ [infallible] readonly attribute unsigned long appId; + /** + * Gets the id of the user context this principal is inside. If this + * principal is inside the default userContext, this returns + * nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID. + */ + [infallible] readonly attribute unsigned long userContextId; + /** * Returns true iff the principal is inside a browser element. (