merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2017-03-07 15:13:31 +01:00
commit 087da3f0d9
291 changed files with 8245 additions and 4092 deletions

View File

@ -1,3 +1,4 @@
/* 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/. */
@ -473,11 +474,15 @@ var ctrlTab = {
this._initRecentlyUsedTabs();
break;
case "TabAttrModified":
// tab attribute modified (e.g. label, busy, image, selected)
for (let i = this.previews.length - 1; i >= 0; i--) {
if (this.previews[i]._tab && this.previews[i]._tab == event.target) {
this.updatePreview(this.previews[i], event.target);
break;
// tab attribute modified (i.e. label, busy, image, selected)
// update preview only if tab attribute modified in the list
if (event.detail.changed.some(
(elem, ind, arr) => ["label", "busy", "image", "selected"].includes(elem))) {
for (let i = this.previews.length - 1; i >= 0; i--) {
if (this.previews[i]._tab && this.previews[i]._tab == event.target) {
this.updatePreview(this.previews[i], event.target);
break;
}
}
}
break;

View File

@ -74,7 +74,14 @@ var SessionStorageInternal = {
// Get the origin of the current history entry
// and use that as a key for the per-principal storage data.
let origin = principal.origin;
let origin;
try {
// The origin getter may throw for about:blank iframes as of bug 1340710,
// but we should ignore them anyway.
origin = principal.origin;
} catch (e) {
return;
}
if (visitedOrigins.has(origin)) {
// Don't read a host twice.
return;

View File

@ -3051,6 +3051,59 @@ dump(`callFromJSON: < ${JSON.stringify(call)}\n`);
//return [new PP_Var(), { exception: PP_Var.fromJSValue(e) }];
},
/**
* PP_Resource Create([in] PP_Instance instance,
* [in] PP_InputEvent_Type type,
* [in] PP_TimeTicks time_stamp,
* [in] uint32_t modifiers,
* [in] uint32_t key_code,
* [in] PP_Var character_text,
* [in] PP_Var code);
*/
PPB_KeyboardInputEvent_Create: function(json) {
let instance = this.instances[json.instance];
let charCode = 0;
if (PP_VarType[json.character_text.type] ==
PP_VarType.PP_VARTYPE_STRING) {
charCode = String_PP_Var.getAsJSValue(json.character_text).charCodeAt(0);
}
let location = instance.window.KeyboardEvent.DOM_KEY_LOCATION_STANDARD;
if (PP_InputEvent_Modifier.PP_INPUTEVENT_MODIFIER_ISLEFT &
json.modifiers) {
location = instance.window.KeyboardEvent.DOM_KEY_LOCATION_LEFT;
} else if (PP_InputEvent_Modifier.PP_INPUTEVENT_MODIFIER_ISRIGHT &
json.modifiers) {
location = instance.window.KeyboardEvent.DOM_KEY_LOCATION_RIGHT;
} else if(PP_InputEvent_Modifier.PP_INPUTEVENT_MODIFIER_ISKEYPAD &
json.modifiers) {
location = instance.window.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD;
}
// FIXME I skipped to put |PP_Var code| into keyboardEventInit here
// because I neither find any useful |code| value passing into here
// nor have any PPB APIs which gets access to |code| now.
let keyboardEventInit = {
altKey: PP_InputEvent_Modifier.PP_INPUTEVENT_MODIFIER_ALTKEY &
json.modifiers,
charCode: charCode,
ctrlKey: PP_InputEvent_Modifier.PP_INPUTEVENT_MODIFIER_CONTROLKEY &
json.modifiers,
keyCode: json.key_code,
location: location,
metaKey: PP_InputEvent_Modifier.PP_INPUTEVENT_MODIFIER_METAKEY &
json.modifiers,
repeat: PP_InputEvent_Modifier.PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT &
json.modifiers,
shiftKey: PP_InputEvent_Modifier.PP_INPUTEVENT_MODIFIER_SHIFTKEY &
json.modifiers,
};
let eventName = EventByTypes.get(PP_InputEvent_Type[json.type]);
let event = new instance.window.KeyboardEvent(eventName,
keyboardEventInit);
let resource = new KeyboardInputEvent(instance, event);
resource.timeStamp = json.time_stamp;
return resource;
},
/**
* PP_Bool IsKeyboardInputEvent([in] PP_Resource resource);

View File

@ -12,58 +12,67 @@ function sandboxScript(sandbox)
Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader).loadSubScript("resource://ppapipdf.js/ppapi-content-sandbox.js", sandbox);
}
let plugins;
function startup(data) {
dump(">>>STARTED!!!\n");
const handlerURI = "chrome://ppapipdf.js/content/viewer.html";
let pdfium = {
init(bootstrapData) {
let root = bootstrapData.installPath.parent.parent;
let rpclib = root.clone();
let pluginlib = root.clone();
let os = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
if (os == "Darwin") {
rpclib.appendRelativePath("ppapi/out/rpc.dylib");
pluginlib.appendRelativePath("plugin/libpepperpdfium.dylib");
} else if (os == "Linux") {
rpclib.appendRelativePath("ppapi/out/rpc.so");
pluginlib.appendRelativePath("plugin/libpepperpdfium.so");
} else if (os == "WINNT") {
rpclib.appendRelativePath("ppapi\\out\\rpc.dll");
pluginlib.appendRelativePath("plugin\\pepperpdfium.dll");
} else {
throw("Don't know the path to the libraries for this OS!");
}
rpclib = rpclib.path;
pluginlib = pluginlib.path;
let root = data.installPath.parent.parent;
let rpclib = root.clone();
let pluginlib = root.clone();
let os = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
if (os == "Darwin") {
rpclib.appendRelativePath("ppapi/out/rpc.dylib");
pluginlib.appendRelativePath("plugin/libpepperpdfium.dylib");
} else if (os == "Linux") {
rpclib.appendRelativePath("ppapi/out/rpc.so");
pluginlib.appendRelativePath("plugin/libpepperpdfium.so");
} else if (os == "WINNT") {
rpclib.appendRelativePath("ppapi\\out\\rpc.dll");
pluginlib.appendRelativePath("plugin\\pepperpdfium.dll");
} else {
throw("Don't know the path to the libraries for this OS!");
}
rpclib = rpclib.path;
pluginlib = pluginlib.path;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let plugin = pluginHost.registerFakePlugin({
handlerURI: "chrome://ppapipdf.js/content/viewer.html",
mimeEntries: [
{ type: "application/pdf", extension: "pdf" },
{ type: "application/vnd.adobe.pdf", extension: "pdf" },
{ type: "application/vnd.adobe.pdfxml", extension: "pdfxml" },
{ type: "application/vnd.adobe.x-mars", extension: "mars" },
{ type: "application/vnd.adobe.xdp+xml", extension: "xdp" },
{ type: "application/vnd.adobe.xfdf", extension: "xfdf" },
{ type: "application/vnd.adobe.xfd+xml", extension: "xfd" },
{ type: "application/vnd.fdf", extension: "fdf" },
],
name: "PPAPI PDF plugin",
niceName: "PPAPI PDF plugin",
version: "1.0",
sandboxScript : `(${sandboxScript.toSource()})(this);`,
ppapiProcessArgs: [ rpclib, pluginlib ],
});
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
let rng = Cc["@mozilla.org/security/random-generator;1"].createInstance(Ci.nsIRandomGenerator);
Services.ppmm.addMessageListener("ppapi.js:generateRandomBytes", ({ data }) => {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let plugin = pluginHost.registerFakePlugin({
handlerURI: handlerURI,
mimeEntries: [
{ type: "application/pdf", extension: "pdf" },
{ type: "application/vnd.adobe.pdf", extension: "pdf" },
{ type: "application/vnd.adobe.pdfxml", extension: "pdfxml" },
{ type: "application/vnd.adobe.x-mars", extension: "mars" },
{ type: "application/vnd.adobe.xdp+xml", extension: "xdp" },
{ type: "application/vnd.adobe.xfdf", extension: "xfdf" },
{ type: "application/vnd.adobe.xfd+xml", extension: "xfd" },
{ type: "application/vnd.fdf", extension: "fdf" },
],
name: "PPAPI PDF plugin",
niceName: "PPAPI PDF plugin",
version: "1.0",
sandboxScript : `(${sandboxScript.toSource()})(this);`,
ppapiProcessArgs: [ rpclib, pluginlib ],
});
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
Services.ppmm.addMessageListener("ppapi.js:generateRandomBytes", this.generateRandomBytesListener);
},
uninit() {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
pluginHost.unregisterFakePlugin(handlerURI);
Services.ppmm.removeMessageListener("ppapi.js:generateRandomBytes", this.generateRandomBytesListener);
},
generateRandomBytesListener(data) {
let rng = Cc["@mozilla.org/security/random-generator;1"].createInstance(Ci.nsIRandomGenerator);
return rng.generateRandomBytes(data);
});
},
}
function startup(aData) {
dump(">>>STARTED!!!\n");
pdfium.init(aData);
dump("<<<STARTED!!!\n");
}
function shutdown() {
dump("SHUTDOWN!!!\n");
pdfium.uninit();
}

View File

@ -474,11 +474,17 @@ static void FromJSON_str_t(JSONIterator& iterator, OutParam<str_t>::type& value)
case 'u':
if (tokenValue.cend() - next >= 5) {
if (*(next + 1) == '0' &&
*(next + 2) == '0' &&
*(next + 3) == '0' &&
*(next + 4) == '0') {
tokenValue.replace(it, next + 5, 1, '\0');
break;
*(next + 2) == '0') {
unsigned int v;
std::stringstream x;
x << *(next + 3) << *(next + 4);
x >> std::hex >> v;
// Handle Control characters code units
// from U+0000 to U+001F.
if ( v < 0x0020) {
tokenValue.replace(it, next + 5, 1, v);
break;
}
}
Fail("Need to handle unicode escapes in strings: %s.",
tokenValue.c_str());

View File

@ -81,7 +81,7 @@ add_task(function* test_context_menu() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "contextmenu", null, {engine: "other-MozSearch"}]]);
contextMenu.hidePopup();
@ -117,7 +117,7 @@ add_task(function* test_about_newtab() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "about_newtab", "enter", {engine: "other-MozSearch"}]]);
yield BrowserTestUtils.removeTab(tab);

View File

@ -81,7 +81,7 @@ add_task(function* test_abouthome_simpleQuery() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "about_home", "enter", {engine: "other-MozSearch"}]]);
yield BrowserTestUtils.removeTab(tab);

View File

@ -107,7 +107,7 @@ add_task(function* test_plainQuery() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "searchbar", "enter", {engine: "other-MozSearch"}]]);
yield BrowserTestUtils.removeTab(tab);
@ -141,7 +141,7 @@ add_task(function* test_oneOff() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "searchbar", "oneoff", {engine: "other-MozSearch2"}]]);
yield BrowserTestUtils.removeTab(tab);
@ -187,7 +187,7 @@ add_task(function* test_suggestion() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "searchbar", "suggestion", {engine: searchEngineId}]]);
Services.search.currentEngine = previousEngine;

View File

@ -126,7 +126,7 @@ add_task(function* test_simpleQuery() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "urlbar", "enter", {engine: "other-MozSearch"}]]);
// Check the histograms as well.
@ -171,7 +171,7 @@ add_task(function* test_searchAlias() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "urlbar", "alias", {engine: "other-MozSearch"}]]);
// Check the histograms as well.
@ -219,7 +219,7 @@ add_task(function* test_oneOff() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "urlbar", "oneoff", {engine: "other-MozSearch"}]]);
// Check the histograms as well.
@ -279,7 +279,7 @@ add_task(function* test_suggestion() {
// Also check events.
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
events = events.filter(e => e[1] == "navigation" && e[2] == "search");
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
checkEvents(events, [["navigation", "search", "urlbar", "suggestion", {engine: searchEngineId}]]);
// Check the histograms as well.

View File

@ -56,7 +56,6 @@ OriginAttributes::Inherit(const OriginAttributes& aAttrs)
mAppId = aAttrs.mAppId;
mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
StripAttributes(STRIP_ADDON_ID);
mUserContextId = aAttrs.mUserContextId;
@ -96,7 +95,7 @@ OriginAttributes::CreateSuffix(nsACString& aStr) const
// Important: While serializing any string-valued attributes, perform a
// release-mode assertion to make sure that they don't contain characters that
// will break the quota manager when it uses the serialization for file
// naming (see addonId below).
// naming.
//
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
@ -108,17 +107,6 @@ OriginAttributes::CreateSuffix(nsACString& aStr) const
params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
}
if (!mAddonId.IsEmpty()) {
if (mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) != kNotFound) {
#ifdef MOZ_CRASHREPORTER
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Crash_AddonId"),
NS_ConvertUTF16toUTF8(mAddonId));
#endif
MOZ_CRASH();
}
params->Set(NS_LITERAL_STRING("addonId"), mAddonId);
}
if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
value.Truncate();
value.AppendInt(mUserContextId);
@ -204,8 +192,8 @@ public:
}
if (aName.EqualsLiteral("addonId")) {
MOZ_RELEASE_ASSERT(mOriginAttributes->mAddonId.IsEmpty());
mOriginAttributes->mAddonId.Assign(aValue);
// No longer supported. Silently ignore so that legacy origin strings
// don't cause failures.
return true;
}
@ -299,7 +287,9 @@ OriginAttributes::IsPrivateBrowsing(const nsACString& aOrigin)
return !!attrs.mPrivateBrowsingId;
}
BasePrincipal::BasePrincipal()
BasePrincipal::BasePrincipal(PrincipalKind aKind)
: mKind(aKind)
, mDomainSet(false)
{}
BasePrincipal::~BasePrincipal()
@ -308,11 +298,12 @@ BasePrincipal::~BasePrincipal()
NS_IMETHODIMP
BasePrincipal::GetOrigin(nsACString& aOrigin)
{
nsresult rv = GetOriginInternal(aOrigin);
nsresult rv = GetOriginNoSuffix(aOrigin);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString suffix;
mOriginAttributes.CreateSuffix(suffix);
rv = GetOriginSuffix(suffix);
NS_ENSURE_SUCCESS(rv, rv);
aOrigin.Append(suffix);
return NS_OK;
}
@ -320,6 +311,9 @@ BasePrincipal::GetOrigin(nsACString& aOrigin)
NS_IMETHODIMP
BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
{
if (mOriginNoSuffix) {
return mOriginNoSuffix->ToUTF8String(aOrigin);
}
return GetOriginInternal(aOrigin);
}
@ -327,13 +321,14 @@ bool
BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
{
MOZ_ASSERT(aOther);
MOZ_ASSERT_IF(Kind() == eCodebasePrincipal, mOriginSuffix);
// Expanded principals handle origin attributes for each of their
// sub-principals individually, null principals do only simple checks for
// pointer equality, and system principals are immune to origin attributes
// checks, so only do this check for codebase principals.
if (Kind() == eCodebasePrincipal &&
OriginAttributesRef() != Cast(aOther)->OriginAttributesRef()) {
mOriginSuffix != Cast(aOther)->mOriginSuffix) {
return false;
}
@ -344,8 +339,9 @@ NS_IMETHODIMP
BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
{
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
*aResult = Subsumes(aOther, DontConsiderDocumentDomain) &&
Cast(aOther)->Subsumes(this, DontConsiderDocumentDomain);
*aResult = FastEquals(aOther);
return NS_OK;
}
@ -353,32 +349,19 @@ NS_IMETHODIMP
BasePrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
{
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
*aResult = Subsumes(aOther, ConsiderDocumentDomain) &&
Cast(aOther)->Subsumes(this, ConsiderDocumentDomain);
*aResult = FastEqualsConsideringDomain(aOther);
return NS_OK;
}
bool
BasePrincipal::EqualsIgnoringAddonId(nsIPrincipal *aOther)
{
MOZ_ASSERT(aOther);
// Note that this will not work for expanded principals, nor is it intended
// to.
if (!dom::ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(
OriginAttributesRef(), Cast(aOther)->OriginAttributesRef())) {
return false;
}
return SubsumesInternal(aOther, DontConsiderDocumentDomain) &&
Cast(aOther)->SubsumesInternal(this, DontConsiderDocumentDomain);
}
NS_IMETHODIMP
BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
{
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
*aResult = Subsumes(aOther, DontConsiderDocumentDomain);
*aResult = FastSubsumes(aOther);
return NS_OK;
}
@ -386,7 +369,9 @@ NS_IMETHODIMP
BasePrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult)
{
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
*aResult = Subsumes(aOther, ConsiderDocumentDomain);
*aResult = FastSubsumesConsideringDomain(aOther);
return NS_OK;
}
@ -396,14 +381,7 @@ BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal *aOther,
{
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
if (Kind() == eCodebasePrincipal &&
!dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
OriginAttributesRef(), aOther->OriginAttributesRef())) {
*aResult = false;
return NS_OK;
}
*aResult = SubsumesInternal(aOther, ConsiderDocumentDomain);
*aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
return NS_OK;
}
@ -559,8 +537,8 @@ BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value>
NS_IMETHODIMP
BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
{
mOriginAttributes.CreateSuffix(aOriginAttributes);
return NS_OK;
MOZ_ASSERT(mOriginSuffix);
return mOriginSuffix->ToUTF8String(aOriginAttributes);
}
NS_IMETHODIMP
@ -584,13 +562,6 @@ BasePrincipal::GetAppId(uint32_t* aAppId)
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetAddonId(nsAString& aAddonId)
{
aAddonId.Assign(mOriginAttributes.mAddonId);
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetUserContextId(uint32_t* aUserContextId)
{
@ -622,15 +593,19 @@ BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
bool
BasePrincipal::AddonHasPermission(const nsAString& aPerm)
{
if (mOriginAttributes.mAddonId.IsEmpty()) {
nsAutoString addonId;
NS_ENSURE_SUCCESS(GetAddonId(addonId), false);
if (addonId.IsEmpty()) {
return false;
}
nsCOMPtr<nsIAddonPolicyService> aps =
do_GetService("@mozilla.org/addons/policy-service;1");
NS_ENSURE_TRUE(aps, false);
bool retval = false;
nsresult rv = aps->AddonHasPermission(mOriginAttributes.mAddonId, aPerm, &retval);
nsresult rv = aps->AddonHasPermission(addonId, aPerm, &retval);
NS_ENSURE_SUCCESS(rv, false);
return retval;
}
@ -709,7 +684,10 @@ BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain()
bool
BasePrincipal::AddonAllowsLoad(nsIURI* aURI, bool aExplicit /* = false */)
{
if (mOriginAttributes.mAddonId.IsEmpty()) {
nsAutoString addonId;
NS_ENSURE_SUCCESS(GetAddonId(addonId), false);
if (addonId.IsEmpty()) {
return false;
}
@ -717,8 +695,29 @@ BasePrincipal::AddonAllowsLoad(nsIURI* aURI, bool aExplicit /* = false */)
NS_ENSURE_TRUE(aps, false);
bool allowed = false;
nsresult rv = aps->AddonMayLoadURI(mOriginAttributes.mAddonId, aURI, aExplicit, &allowed);
nsresult rv = aps->AddonMayLoadURI(addonId, aURI, aExplicit, &allowed);
return NS_SUCCEEDED(rv) && allowed;
}
void
BasePrincipal::FinishInit()
{
// First compute the origin suffix since it's infallible.
nsAutoCString originSuffix;
mOriginAttributes.CreateSuffix(originSuffix);
mOriginSuffix = NS_Atomize(originSuffix);
// Then compute the origin without the suffix.
nsAutoCString originNoSuffix;
nsresult rv = GetOriginInternal(originNoSuffix);
if (NS_FAILED(rv)) {
// If GetOriginInternal fails, we will get a null atom for mOriginNoSuffix,
// which we deal with anywhere mOriginNoSuffix is used.
// Once this is made infallible we can remove those null checks.
mOriginNoSuffix = nullptr;
return;
}
mOriginNoSuffix = NS_Atomize(originNoSuffix);
}
} // namespace mozilla

View File

@ -10,6 +10,7 @@
#include "nsJSPrincipals.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/ChromeUtilsBinding.h"
#include "nsIScriptSecurityManager.h"
@ -47,8 +48,7 @@ public:
enum {
STRIP_FIRST_PARTY_DOMAIN = 0x01,
STRIP_ADDON_ID = 0x02,
STRIP_USER_CONTEXT_ID = 0x04,
STRIP_USER_CONTEXT_ID = 0x02,
};
inline void StripAttributes(uint32_t aFlags)
@ -57,10 +57,6 @@ public:
mFirstPartyDomain.Truncate();
}
if (aFlags & STRIP_ADDON_ID) {
mAddonId.Truncate();
}
if (aFlags & STRIP_USER_CONTEXT_ID) {
mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID;
}
@ -70,7 +66,6 @@ public:
{
return mAppId == aOther.mAppId &&
mInIsolatedMozBrowser == aOther.mInIsolatedMozBrowser &&
mAddonId == aOther.mAddonId &&
mUserContextId == aOther.mUserContextId &&
mPrivateBrowsingId == aOther.mPrivateBrowsingId &&
mFirstPartyDomain == aOther.mFirstPartyDomain;
@ -152,10 +147,6 @@ public:
return false;
}
if (mAddonId.WasPassed() && mAddonId.Value() != aAttrs.mAddonId) {
return false;
}
if (mUserContextId.WasPassed() && mUserContextId.Value() != aAttrs.mUserContextId) {
return false;
}
@ -184,11 +175,6 @@ public:
return false;
}
if (mAddonId.WasPassed() && aOther.mAddonId.WasPassed() &&
mAddonId.Value() != aOther.mAddonId.Value()) {
return false;
}
if (mUserContextId.WasPassed() && aOther.mUserContextId.WasPassed() &&
mUserContextId.Value() != aOther.mUserContextId.Value()) {
return false;
@ -218,7 +204,14 @@ public:
class BasePrincipal : public nsJSPrincipals
{
public:
BasePrincipal();
enum PrincipalKind {
eNullPrincipal,
eCodebasePrincipal,
eExpandedPrincipal,
eSystemPrincipal
};
explicit BasePrincipal(PrincipalKind aKind);
enum DocumentDomainConsideration { DontConsiderDocumentDomain, ConsiderDocumentDomain};
bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration);
@ -244,14 +237,11 @@ public:
NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) final;
NS_IMETHOD GetAppId(uint32_t* aAppStatus) final;
NS_IMETHOD GetAddonId(nsAString& aAddonId) final;
NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement) final;
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final;
NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
bool EqualsIgnoringAddonId(nsIPrincipal *aOther);
virtual bool AddonHasPermission(const nsAString& aPerm);
virtual bool IsCodebasePrincipal() const { return false; };
@ -261,20 +251,13 @@ public:
CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs);
static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(const nsACString& aOrigin);
const OriginAttributes& OriginAttributesRef() override { return mOriginAttributes; }
const OriginAttributes& OriginAttributesRef() final { return mOriginAttributes; }
uint32_t AppId() const { return mOriginAttributes.mAppId; }
uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; }
bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; }
enum PrincipalKind {
eNullPrincipal,
eCodebasePrincipal,
eExpandedPrincipal,
eSystemPrincipal
};
virtual PrincipalKind Kind() = 0;
PrincipalKind Kind() const { return mKind; }
already_AddRefed<BasePrincipal> CloneStrippingUserContextIdAndFirstPartyDomain();
@ -283,6 +266,13 @@ public:
// use of all_urls permission, requiring the domain in its permissions.
bool AddonAllowsLoad(nsIURI* aURI, bool aExplicit = false);
// Call these to avoid the cost of virtual dispatch.
inline bool FastEquals(nsIPrincipal* aOther);
inline bool FastEqualsConsideringDomain(nsIPrincipal* aOther);
inline bool FastSubsumes(nsIPrincipal* aOther);
inline bool FastSubsumesConsideringDomain(nsIPrincipal* aOther);
inline bool FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther);
protected:
virtual ~BasePrincipal();
@ -297,11 +287,115 @@ protected:
virtual bool MayLoadInternal(nsIURI* aURI) = 0;
friend class ::nsExpandedPrincipal;
// This function should be called as the last step of the initialization of the
// principal objects. It's typically called as the last step from the Init()
// method of the child classes.
void FinishInit();
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
nsCOMPtr<nsIAtom> mOriginNoSuffix;
nsCOMPtr<nsIAtom> mOriginSuffix;
OriginAttributes mOriginAttributes;
PrincipalKind mKind;
bool mDomainSet;
};
inline bool
BasePrincipal::FastEquals(nsIPrincipal* aOther)
{
auto other = Cast(aOther);
if (Kind() != other->Kind()) {
// Principals of different kinds can't be equal.
return false;
}
// Two principals are considered to be equal if their origins are the same.
// If the two principals are codebase principals, their origin attributes
// (aka the origin suffix) must also match.
// If the two principals are null principals, they're only equal if they're
// the same object.
if (Kind() == eNullPrincipal || Kind() == eSystemPrincipal) {
return this == other;
}
if (mOriginNoSuffix) {
if (Kind() == eCodebasePrincipal) {
return mOriginNoSuffix == other->mOriginNoSuffix &&
mOriginSuffix == other->mOriginSuffix;
}
MOZ_ASSERT(Kind() == eExpandedPrincipal);
return mOriginNoSuffix == other->mOriginNoSuffix;
}
// If mOriginNoSuffix is null on one of our principals, we must fall back
// to the slow path.
return Subsumes(aOther, DontConsiderDocumentDomain) &&
other->Subsumes(this, DontConsiderDocumentDomain);
}
inline bool
BasePrincipal::FastEqualsConsideringDomain(nsIPrincipal* aOther)
{
// If neither of the principals have document.domain set, we use the fast path
// in Equals(). Otherwise, we fall back to the slow path below.
auto other = Cast(aOther);
if (!mDomainSet && !other->mDomainSet) {
return FastEquals(aOther);
}
return Subsumes(aOther, ConsiderDocumentDomain) &&
other->Subsumes(this, ConsiderDocumentDomain);
}
inline bool
BasePrincipal::FastSubsumes(nsIPrincipal* aOther)
{
// If two principals are equal, then they both subsume each other.
// We deal with two special cases first:
// Null principals only subsume each other if they are equal, and are only
// equal if they're the same object.
// Also, if mOriginNoSuffix is null, FastEquals falls back to the slow path
// using Subsumes, so we don't want to use it in that case to avoid an
// infinite recursion.
auto other = Cast(aOther);
if (Kind() == eNullPrincipal && other->Kind() == eNullPrincipal) {
return this == other;
}
if (mOriginNoSuffix && FastEquals(aOther)) {
return true;
}
// Otherwise, fall back to the slow path.
return Subsumes(aOther, DontConsiderDocumentDomain);
}
inline bool
BasePrincipal::FastSubsumesConsideringDomain(nsIPrincipal* aOther)
{
// If neither of the principals have document.domain set, we hand off to
// FastSubsumes() which has fast paths for some special cases. Otherwise, we fall
// back to the slow path below.
if (!mDomainSet && !Cast(aOther)->mDomainSet) {
return FastSubsumes(aOther);
}
return Subsumes(aOther, ConsiderDocumentDomain);
}
inline bool
BasePrincipal::FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther)
{
if (Kind() == eCodebasePrincipal &&
!dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
return false;
}
return SubsumesInternal(aOther, ConsiderDocumentDomain);
}
} // namespace mozilla
#endif /* mozilla_BasePrincipal_h */

View File

@ -45,6 +45,7 @@ struct OriginComparator
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
const OriginAttributes& aAttrs)
: BasePrincipal(eExpandedPrincipal)
{
// We force the principals to be sorted by origin so that nsExpandedPrincipal
// origins can have a canonical form.
@ -58,6 +59,15 @@ nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhit
nsExpandedPrincipal::~nsExpandedPrincipal()
{ }
already_AddRefed<nsExpandedPrincipal>
nsExpandedPrincipal::Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
const OriginAttributes& aAttrs)
{
RefPtr<nsExpandedPrincipal> ep = new nsExpandedPrincipal(aWhiteList, aAttrs);
ep->FinishInit();
return ep.forget();
}
NS_IMETHODIMP
nsExpandedPrincipal::GetDomain(nsIURI** aDomain)
{
@ -160,6 +170,13 @@ nsExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsExpandedPrincipal::GetAddonId(nsAString& aAddonId)
{
aAddonId.Truncate();
return NS_OK;
};
bool
nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
{

View File

@ -15,10 +15,14 @@
class nsExpandedPrincipal : public nsIExpandedPrincipal
, public mozilla::BasePrincipal
{
public:
nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
const mozilla::OriginAttributes& aAttrs);
public:
static already_AddRefed<nsExpandedPrincipal>
Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
const mozilla::OriginAttributes& aAttrs);
NS_DECL_NSIEXPANDEDPRINCIPAL
NS_DECL_NSISERIALIZABLE
NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return nsJSPrincipals::AddRef(); };
@ -29,12 +33,11 @@ public:
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
virtual bool AddonHasPermission(const nsAString& aPerm) override;
virtual nsresult GetScriptLocation(nsACString &aStr) override;
nsresult GetOriginInternal(nsACString& aOrigin) override;
PrincipalKind Kind() override { return eExpandedPrincipal; }
protected:
virtual ~nsExpandedPrincipal();

View File

@ -86,6 +86,8 @@ nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE);
}
FinishInit();
return NS_OK;
}
@ -156,6 +158,13 @@ nsNullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
return mURI->GetPath(aBaseDomain);
}
NS_IMETHODIMP
nsNullPrincipal::GetAddonId(nsAString& aAddonId)
{
aAddonId.Truncate();
return NS_OK;
};
/**
* nsISerializable implementation
*/

View File

@ -36,7 +36,10 @@ public:
// This should only be used by deserialization, and the factory constructor.
// Other consumers should use the Create and CreateWithInheritedAttributes
// methods.
nsNullPrincipal() {}
nsNullPrincipal()
: BasePrincipal(eNullPrincipal)
{
}
NS_DECL_NSISERIALIZABLE
@ -46,6 +49,7 @@ public:
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
nsresult GetOriginInternal(nsACString& aOrigin) override;
static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom);
@ -61,8 +65,6 @@ public:
virtual nsresult GetScriptLocation(nsACString &aStr) override;
PrincipalKind Kind() override { return eNullPrincipal; }
protected:
virtual ~nsNullPrincipal() {}

View File

@ -27,6 +27,7 @@
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Preferences.h"
#include "mozilla/HashFunctions.h"
@ -44,6 +45,19 @@ static bool URIIsImmutable(nsIURI* aURI)
!isMutable;
}
static nsIAddonPolicyService*
GetAddonPolicyService(nsresult* aRv)
{
static nsCOMPtr<nsIAddonPolicyService> addonPolicyService;
*aRv = NS_OK;
if (!addonPolicyService) {
addonPolicyService = do_GetService("@mozilla.org/addons/policy-service;1", aRv);
ClearOnShutdown(&addonPolicyService);
}
return addonPolicyService;
}
NS_IMPL_CLASSINFO(nsPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
NS_PRINCIPAL_CID)
NS_IMPL_QUERY_INTERFACE_CI(nsPrincipal,
@ -63,10 +77,12 @@ nsPrincipal::InitializeStatics()
}
nsPrincipal::nsPrincipal()
: mCodebaseImmutable(false)
: BasePrincipal(eCodebasePrincipal)
, mCodebaseImmutable(false)
, mDomainImmutable(false)
, mInitialized(false)
{ }
{
}
nsPrincipal::~nsPrincipal()
{
@ -84,10 +100,25 @@ nsPrincipal::Init(nsIURI *aCodebase, const OriginAttributes& aOriginAttributes)
mInitialized = true;
// Assert that the URI we get here isn't any of the schemes that we know we
// should not get here. These schemes always either inherit their principal
// or fall back to a null principal. These are schemes which return
// URI_INHERITS_SECURITY_CONTEXT from their protocol handler's
// GetProtocolFlags function.
bool hasFlag;
Unused << hasFlag; // silence possible compiler warnings.
MOZ_DIAGNOSTIC_ASSERT(
NS_SUCCEEDED(NS_URIChainHasFlags(aCodebase,
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
&hasFlag)) &&
!hasFlag);
mCodebase = NS_TryToMakeImmutable(aCodebase);
mCodebaseImmutable = URIIsImmutable(mCodebase);
mOriginAttributes = aOriginAttributes;
FinishInit();
return NS_OK;
}
@ -109,6 +140,17 @@ nsPrincipal::GetOriginInternal(nsACString& aOrigin)
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(!NS_IsAboutBlank(origin),
"The inner URI for about:blank must be moz-safe-about:blank");
if (!nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
NS_URIIsLocalFile(origin)) {
// If strict file origin policy is not in effect, all local files are
// considered to be same-origin, so return a known dummy origin here.
aOrigin.AssignLiteral("file://UNIVERSAL_FILE_URI_ORIGIN");
return NS_OK;
}
nsAutoCString hostPort;
// chrome: URLs don't have a meaningful origin, so make
@ -139,7 +181,11 @@ nsPrincipal::GetOriginInternal(nsACString& aOrigin)
// to handle.
bool isBehaved;
if ((NS_SUCCEEDED(origin->SchemeIs("about", &isBehaved)) && isBehaved) ||
(NS_SUCCEEDED(origin->SchemeIs("moz-safe-about", &isBehaved)) && isBehaved) ||
(NS_SUCCEEDED(origin->SchemeIs("moz-safe-about", &isBehaved)) && isBehaved &&
// We generally consider two about:foo origins to be same-origin, but
// about:blank is special since it can be generated from different sources.
// We check for moz-safe-about:blank since origin is an innermost URI.
!origin->GetSpecOrDefault().EqualsLiteral("moz-safe-about:blank")) ||
(NS_SUCCEEDED(origin->SchemeIs("indexeddb", &isBehaved)) && isBehaved)) {
rv = origin->GetAsciiSpec(aOrigin);
NS_ENSURE_SUCCESS(rv, rv);
@ -291,13 +337,6 @@ nsPrincipal::MayLoadInternal(nsIURI* aURI)
return false;
}
void
nsPrincipal::SetURI(nsIURI* aURI)
{
mCodebase = NS_TryToMakeImmutable(aURI);
mCodebaseImmutable = URIIsImmutable(mCodebase);
}
NS_IMETHODIMP
nsPrincipal::GetHashValue(uint32_t* aValue)
{
@ -328,6 +367,7 @@ nsPrincipal::SetDomain(nsIURI* aDomain)
{
mDomain = NS_TryToMakeImmutable(aDomain);
mDomainImmutable = URIIsImmutable(mDomain);
mDomainSet = true;
// Recompute all wrappers between compartments using this principal and other
// non-chrome compartments.
@ -378,6 +418,35 @@ nsPrincipal::GetBaseDomain(nsACString& aBaseDomain)
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::GetAddonId(nsAString& aAddonId)
{
if (mAddonIdCache.isSome()) {
aAddonId.Assign(mAddonIdCache.ref());
return NS_OK;
}
NS_ENSURE_TRUE(mCodebase, NS_ERROR_FAILURE);
nsresult rv;
bool isMozExt;
if (NS_SUCCEEDED(mCodebase->SchemeIs("moz-extension", &isMozExt)) && isMozExt) {
nsIAddonPolicyService* addonPolicyService = GetAddonPolicyService(&rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString addonId;
rv = addonPolicyService->ExtensionURIToAddonId(mCodebase, addonId);
NS_ENSURE_SUCCESS(rv, rv);
mAddonIdCache.emplace(addonId);
} else {
mAddonIdCache.emplace();
}
aAddonId.Assign(mAddonIdCache.ref());
return NS_OK;
};
NS_IMETHODIMP
nsPrincipal::Read(nsIObjectInputStream* aStream)
{

View File

@ -25,6 +25,7 @@ public:
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
bool IsCodebasePrincipal() const override { return true; }
nsresult GetOriginInternal(nsACString& aOrigin) override;
@ -35,15 +36,12 @@ public:
const mozilla::OriginAttributes& aOriginAttributes);
virtual nsresult GetScriptLocation(nsACString& aStr) override;
void SetURI(nsIURI* aURI);
/**
* Called at startup to setup static data, e.g. about:config pref-observers.
*/
static void InitializeStatics();
PrincipalKind Kind() override { return eCodebasePrincipal; }
nsCOMPtr<nsIURI> mDomain;
nsCOMPtr<nsIURI> mCodebase;
// If mCodebaseImmutable is true, mCodebase is non-null and immutable
@ -56,6 +54,9 @@ protected:
bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
bool MayLoadInternal(nsIURI* aURI) override;
private:
mozilla::Maybe<nsString> mAddonIdCache;
};
#define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"

View File

@ -344,20 +344,6 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel,
return GetChannelURIPrincipal(aChannel, aPrincipal);
}
nsresult
nsScriptSecurityManager::MaybeSetAddonIdFromURI(OriginAttributes& aAttrs, nsIURI* aURI)
{
nsAutoCString scheme;
nsresult rv = aURI->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
if (scheme.EqualsLiteral("moz-extension") && GetAddonPolicyService()) {
rv = GetAddonPolicyService()->ExtensionURIToAddonId(aURI, aAttrs.mAddonId);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
/* The principal of the URI that this channel is loading. This is never
* affected by things like sandboxed loads, or loads where we forcefully
* inherit the principal. Think of this as the principal of the server
@ -395,8 +381,6 @@ nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel,
if (loadInfo) {
attrs.Inherit(loadInfo->GetOriginAttributes());
}
rv = MaybeSetAddonIdFromURI(attrs, uri);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
prin.forget(aPrincipal);
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
@ -1165,8 +1149,6 @@ nsScriptSecurityManager::
OriginAttributes attrs;
attrs.Inherit(docShellAttrs);
nsresult rv = MaybeSetAddonIdFromURI(attrs, aURI);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
prin.forget(aPrincipal);
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
@ -1180,8 +1162,6 @@ nsScriptSecurityManager::GetDocShellCodebasePrincipal(nsIURI* aURI,
OriginAttributes attrs;
attrs.Inherit(nsDocShell::Cast(aDocShell)->GetOriginAttributes());
nsresult rv = MaybeSetAddonIdFromURI(attrs, aURI);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
prin.forget(aPrincipal);
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
@ -1333,7 +1313,7 @@ nsresult nsScriptSecurityManager::Init()
NS_ENSURE_SUCCESS(rv, rv);
// Create our system principal singleton
RefPtr<nsSystemPrincipal> system = new nsSystemPrincipal();
RefPtr<nsSystemPrincipal> system = nsSystemPrincipal::Create();
mSystemPrincipal = system;

View File

@ -111,9 +111,6 @@ private:
inline void
AddSitesToFileURIWhitelist(const nsCString& aSiteList);
// If aURI is a moz-extension:// URI, set mAddonId to the associated addon.
nsresult MaybeSetAddonIdFromURI(mozilla::OriginAttributes& aAttrs, nsIURI* aURI);
nsresult GetChannelResultPrincipal(nsIChannel* aChannel,
nsIPrincipal** aPrincipal,
bool aIgnoreSandboxing);

View File

@ -31,6 +31,14 @@ NS_IMPL_CI_INTERFACE_GETTER(nsSystemPrincipal,
#define SYSTEM_PRINCIPAL_SPEC "[System Principal]"
already_AddRefed<nsSystemPrincipal>
nsSystemPrincipal::Create()
{
RefPtr<nsSystemPrincipal> sp = new nsSystemPrincipal();
sp->FinishInit();
return sp.forget();
}
nsresult
nsSystemPrincipal::GetScriptLocation(nsACString &aStr)
{
@ -113,6 +121,13 @@ nsSystemPrincipal::GetBaseDomain(nsACString& aBaseDomain)
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::GetAddonId(nsAString& aAddonId)
{
aAddonId.Truncate();
return NS_OK;
};
//////////////////////////////////////////
// Methods implementing nsISerializable //
//////////////////////////////////////////

View File

@ -22,7 +22,14 @@
class nsSystemPrincipal final : public mozilla::BasePrincipal
{
nsSystemPrincipal()
: BasePrincipal(eSystemPrincipal)
{
}
public:
static already_AddRefed<nsSystemPrincipal> Create();
NS_DECL_NSISERIALIZABLE
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
@ -34,10 +41,9 @@ public:
NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
nsresult GetOriginInternal(nsACString& aOrigin) override;
nsSystemPrincipal() {}
virtual nsresult GetScriptLocation(nsACString &aStr) override;
protected:
@ -52,8 +58,6 @@ protected:
{
return true;
}
PrincipalKind Kind() override { return eSystemPrincipal; }
};
#endif // nsSystemPrincipal_h__

View File

@ -20,9 +20,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1180921
let aps = Cc["@mozilla.org/addons/policy-service;1"].getService(Ci.nsIAddonPolicyService).wrappedJSObject;
SimpleTest.waitForExplicitFinish();
let oldAddonIdCallback = aps.setExtensionURIToAddonIdCallback(uri => uri.host);
SimpleTest.registerCleanupFunction(function() {
aps.setAddonLoadURICallback('addonA', null);
aps.setAddonLoadURICallback('addonB', null);
aps.setAddonLoadURICallback('addona', null);
aps.setAddonLoadURICallback('addonb', null);
aps.setExtensionURIToAddonIdCallback(oldAddonIdCallback);
});
function tryLoad(sb, uri) {
@ -39,42 +41,28 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1180921
return p;
}
let exampleCom_addonA = new Cu.Sandbox(ssm.createCodebasePrincipal(Services.io.newURI('http://example.com'), {addonId: 'addonA'}),
{wantGlobalProperties: ['XMLHttpRequest']});
let nullPrin_addonA = new Cu.Sandbox(ssm.createNullPrincipal({addonId: 'addonA'}),
{wantGlobalProperties: ['XMLHttpRequest']});
let exampleCom_addonB = new Cu.Sandbox(ssm.createCodebasePrincipal(Services.io.newURI('http://example.com'), {addonId: 'addonB'}),
{wantGlobalProperties: ['XMLHttpRequest']});
let addonA = new Cu.Sandbox(ssm.createCodebasePrincipal(Services.io.newURI('moz-extension://addonA/'), {}),
{wantGlobalProperties: ['XMLHttpRequest']});
let addonB = new Cu.Sandbox(ssm.createCodebasePrincipal(Services.io.newURI('moz-extension://addonB/'), {}),
{wantGlobalProperties: ['XMLHttpRequest']});
function uriForDomain(d) { return d + '/tests/caps/tests/mochitest/file_data.txt' }
tryLoad(exampleCom_addonA, uriForDomain('http://example.com'))
tryLoad(addonA, uriForDomain('http://test1.example.org'))
.then(function(success) {
ok(success, "same-origin load should succeed for addon A");
return tryLoad(nullPrin_addonA, uriForDomain('http://example.com'));
}).then(function(success) {
ok(!success, "null-principal load should fail for addon A");
return tryLoad(exampleCom_addonB, uriForDomain('http://example.com'));
}).then(function(success) {
ok(success, "same-origin load should succeed for addon B");
return tryLoad(exampleCom_addonA, uriForDomain('http://test1.example.org'));
}).then(function(success) {
ok(!success, "cross-origin load should fail for addon A");
aps.setAddonLoadURICallback('addonA', function(uri) { return /test1/.test(uri.host); });
aps.setAddonLoadURICallback('addonB', function(uri) { return /test2/.test(uri.host); });
return tryLoad(exampleCom_addonA, uriForDomain('http://test1.example.org'));
aps.setAddonLoadURICallback('addona', function(uri) { return /test1/.test(uri.host); });
aps.setAddonLoadURICallback('addonb', function(uri) { return /test2/.test(uri.host); });
return tryLoad(addonA, uriForDomain('http://test1.example.org'));
}).then(function(success) {
ok(success, "whitelisted cross-origin load of test1 should succeed for addon A");
return tryLoad(nullPrin_addonA, uriForDomain('http://test1.example.org'));
}).then(function(success) {
ok(!success, "whitelisted null principal load of test1 should still fail for addon A");
return tryLoad(exampleCom_addonB, uriForDomain('http://test1.example.org'));
return tryLoad(addonB, uriForDomain('http://test1.example.org'));
}).then(function(success) {
ok(!success, "non-whitelisted cross-origin load of test1 should fail for addon B");
return tryLoad(exampleCom_addonB, uriForDomain('http://test2.example.org'));
return tryLoad(addonB, uriForDomain('http://test2.example.org'));
}).then(function(success) {
ok(success, "whitelisted cross-origin load of test2 should succeed for addon B");
return tryLoad(exampleCom_addonA, uriForDomain('http://test2.example.org'));
return tryLoad(addonA, uriForDomain('http://test2.example.org'));
}).then(function(success) {
ok(!success, "non-whitelisted cross-origin load of test2 should fail for addon A");
SimpleTest.finish();

View File

@ -93,7 +93,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
is(stripTrailingSlash(prin.URI.spec), url, 'Principal uri is correct: ' + url);
function stripPath(s) { return s.replace(/(.*\/\/.+)\/.*/, '$1'); };
is(prin.originNoSuffix, stripPath(url), 'Principal origin is correct: ' + prin.originNoSuffix);
is(prin.originAttributes.addonId, 'imaginaryaddon-' + url[url.indexOf('/') + 2], 'addonId is correct');
is(prin.addonId, 'imaginaryaddon-' + url[url.indexOf('/') + 2], 'addonId is correct');
if (/_blank/.test(url)) {
is(SpecialPowers.wrap(ifr.contentWindow).document.documentElement.innerHTML,
'<head></head><body></body>', 'blank document looks right');

View File

@ -48,7 +48,6 @@ function printAttrs(name, attrs) {
"\tappId: " + attrs.appId + ",\n" +
"\tuserContextId: " + attrs.userContextId + ",\n" +
"\tinIsolatedMozBrowser: " + attrs.inIsolatedMozBrowser + ",\n" +
"\taddonId: '" + attrs.addonId + "',\n" +
"\tprivateBrowsingId: '" + attrs.privateBrowsingId + "',\n" +
"\tfirstPartyDomain: '" + attrs.firstPartyDomain + "'\n}");
}
@ -61,7 +60,6 @@ function checkValues(attrs, values) {
do_check_eq(attrs.appId, values.appId || 0);
do_check_eq(attrs.userContextId, values.userContextId || 0);
do_check_eq(attrs.inIsolatedMozBrowser, values.inIsolatedMozBrowser || false);
do_check_eq(attrs.addonId, values.addonId || '');
do_check_eq(attrs.privateBrowsingId, values.privateBrowsingId || '');
do_check_eq(attrs.firstPartyDomain, values.firstPartyDomain || '');
}
@ -126,11 +124,6 @@ function run_test() {
checkOriginAttributes(exampleCom_appBrowser, {appId: 42, inIsolatedMozBrowser: true}, '^appId=42&inBrowser=1');
do_check_eq(exampleCom_appBrowser.origin, 'https://www.example.com:123^appId=42&inBrowser=1');
// Addon.
var exampleOrg_addon = ssm.createCodebasePrincipal(makeURI('http://example.org'), {addonId: 'dummy'});
checkOriginAttributes(exampleOrg_addon, { addonId: "dummy" }, '^addonId=dummy');
do_check_eq(exampleOrg_addon.origin, 'http://example.org^addonId=dummy');
// First party Uri
var exampleOrg_firstPartyDomain = ssm.createCodebasePrincipal(makeURI('http://example.org'), {firstPartyDomain: 'example.org'});
checkOriginAttributes(exampleOrg_firstPartyDomain, { firstPartyDomain: "example.org" }, '^firstPartyDomain=example.org');
@ -155,13 +148,6 @@ function run_test() {
checkOriginAttributes(exampleOrg_userContext, { userContextId: 42 }, '^userContextId=42');
do_check_eq(exampleOrg_userContext.origin, 'http://example.org^userContextId=42');
// UserContext and Addon.
var exampleOrg_userContextAddon = ssm.createCodebasePrincipal(makeURI('http://example.org'), {addonId: 'dummy', userContextId: 42});
var nullPrin_userContextAddon = ssm.createNullPrincipal({addonId: 'dummy', userContextId: 42});
checkOriginAttributes(exampleOrg_userContextAddon, {addonId: 'dummy', userContextId: 42}, '^addonId=dummy&userContextId=42');
checkOriginAttributes(nullPrin_userContextAddon, {addonId: 'dummy', userContextId: 42}, '^addonId=dummy&userContextId=42');
do_check_eq(exampleOrg_userContextAddon.origin, 'http://example.org^addonId=dummy&userContextId=42');
// UserContext and App.
var exampleOrg_userContextApp = ssm.createCodebasePrincipal(makeURI('http://example.org'), {appId: 24, userContextId: 42});
var nullPrin_userContextApp = ssm.createNullPrincipal({appId: 24, userContextId: 42});
@ -185,11 +171,8 @@ function run_test() {
checkCrossOrigin(exampleOrg_appBrowser, exampleOrg_app);
checkCrossOrigin(exampleOrg_appBrowser, nullPrin_appBrowser);
checkCrossOrigin(exampleOrg_appBrowser, exampleCom_appBrowser);
checkCrossOrigin(exampleOrg_addon, exampleOrg);
checkCrossOrigin(exampleOrg_firstPartyDomain, exampleOrg);
checkCrossOrigin(exampleOrg_userContext, exampleOrg);
checkCrossOrigin(exampleOrg_userContextAddon, exampleOrg);
checkCrossOrigin(exampleOrg_userContext, exampleOrg_userContextAddon);
checkCrossOrigin(exampleOrg_userContext, exampleOrg_userContextApp);
// Check Principal kinds.
@ -218,7 +201,6 @@ function run_test() {
[ "", {} ],
[ "^appId=5", {appId: 5} ],
[ "^userContextId=3", {userContextId: 3} ],
[ "^addonId=fooBar", {addonId: "fooBar"} ],
[ "^inBrowser=1", {inIsolatedMozBrowser: true} ],
[ "^firstPartyDomain=example.org", {firstPartyDomain: "example.org"} ],
[ "^appId=3&inBrowser=1&userContextId=6",
@ -304,4 +286,26 @@ function run_test() {
do_check_eq(ChromeUtils.originAttributesToSuffix(mod), t[3]);
});
var fileURI = makeURI('file:///foo/bar').QueryInterface(Ci.nsIFileURL);
var fileTests = [
[true, fileURI.spec],
[false, "file://UNIVERSAL_FILE_URI_ORIGIN"],
];
fileTests.forEach(t => {
Services.prefs.setBoolPref("security.fileuri.strict_origin_policy", t[0]);
var filePrin = ssm.createCodebasePrincipal(fileURI, {});
do_check_eq(filePrin.origin, t[1]);
});
Services.prefs.clearUserPref("security.fileuri.strict_origin_policy");
var aboutBlankURI = makeURI('about:blank');
var aboutBlankPrin = ssm.createCodebasePrincipal(aboutBlankURI, {});
var thrown = false;
try {
aboutBlankPrin.origin;
} catch (e) {
thrown = true;
}
do_check_true(thrown);
}

View File

@ -28,8 +28,7 @@ add_task(function* testWebExtensionsToolboxWebConsole() {
let onCustomMessage = new Promise(done => {
Services.obs.addObserver(function listener(message, topic) {
let apiMessage = message.wrappedJSObject;
if (!apiMessage.originAttributes ||
apiMessage.originAttributes.addonId != ADDON_ID) {
if (apiMessage.addonId != ADDON_ID) {
return;
}
Services.obs.removeObserver(listener, "console-api-log-event");

View File

@ -44,8 +44,7 @@ add_task(function* testWebExtensionsToolboxSwitchToPopup() {
let onReadyForOpenPopup = new Promise(done => {
Services.obs.addObserver(function listener(message, topic) {
let apiMessage = message.wrappedJSObject;
if (!apiMessage.originAttributes ||
apiMessage.originAttributes.addonId != ADDON_ID) {
if (apiMessage.addonId != ADDON_ID) {
return;
}
@ -149,8 +148,7 @@ add_task(function* testWebExtensionsToolboxSwitchToPopup() {
let onPopupCustomMessage = new Promise(done => {
Services.obs.addObserver(function listener(message, topic) {
let apiMessage = message.wrappedJSObject;
if (!apiMessage.originAttributes ||
apiMessage.originAttributes.addonId != ADDON_ID) {
if (apiMessage.addonId != ADDON_ID) {
return;
}

View File

@ -36,15 +36,11 @@ add_task(function* () {
is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
// Cut/Copy items are enabled in context menu even if there
// is no selection. See also Bug 1303033
// Cut/Copy/Paste items are enabled in context menu even if there
// is no selection. See also Bug 1303033, and 1317322
is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
if (isWindows()) {
// emptyClipboard only works on Windows (666254), assert paste only for this OS.
is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
}
is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
yield cleanup(toolbox);
});

View File

@ -45,15 +45,11 @@ add_task(function* () {
is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
// Cut/Copy items are enabled in context menu even if there
// is no selection. See also Bug 1303033
// Cut/Copy/Paste items are enabled in context menu even if there is no
// selection. See also Bug 1303033, and 1317322
is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
if (isWindows()) {
// emptyClipboard only works on Windows (666254), assert paste only for this OS.
is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
}
is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
info("Closing context menu");
let onContextMenuHidden = once(searchContextMenu, "popuphidden");

View File

@ -44,15 +44,11 @@ add_task(function* () {
is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
// Cut/Copy items are enabled in context menu even if there
// is no selection. See also Bug 1303033
// Cut/Copy/Paste items are enabled in context menu even if there is no
// selection. See also Bug 1303033, and 1317322
is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
if (isWindows()) {
// emptyClipboard only works on Windows (666254), assert paste only for this OS.
is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
}
is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
info("Closing context menu");
let onContextMenuHidden = once(searchContextMenu, "popuphidden");

View File

@ -43,14 +43,10 @@ add_task(function* () {
is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
// Cut/Copy items are enabled in context menu even if there
// is no selection. See also Bug 1303033
// is no selection. See also Bug 1303033, and 1317322
is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
if (isWindows()) {
// emptyClipboard only works on Windows (666254), assert paste only for this OS.
is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
}
is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
info("Closing context menu");
let onContextMenuHidden = once(searchContextMenu, "popuphidden");

View File

@ -688,6 +688,7 @@ stubPackets.set("console.log('foobar', 'test')", {
"from": "server1.conn0.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"foobar",
"test"
@ -712,6 +713,7 @@ stubPackets.set("console.log(undefined)", {
"from": "server1.conn1.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
{
"type": "undefined"
@ -737,6 +739,7 @@ stubPackets.set("console.warn('danger, will robinson!')", {
"from": "server1.conn2.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"danger, will robinson!"
],
@ -760,6 +763,7 @@ stubPackets.set("console.log(NaN)", {
"from": "server1.conn3.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
{
"type": "NaN"
@ -785,6 +789,7 @@ stubPackets.set("console.log(null)", {
"from": "server1.conn4.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
{
"type": "null"
@ -810,6 +815,7 @@ stubPackets.set("console.log('鼬')", {
"from": "server1.conn5.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"鼬"
],
@ -833,6 +839,7 @@ stubPackets.set("console.clear()", {
"from": "server1.conn6.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [],
"columnNumber": 27,
"counter": null,
@ -854,6 +861,7 @@ stubPackets.set("console.count('bar')", {
"from": "server1.conn7.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"bar"
],
@ -880,6 +888,7 @@ stubPackets.set("console.assert(false, {message: 'foobar'})", {
"from": "server1.conn8.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
{
"type": "object",
@ -933,6 +942,7 @@ stubPackets.set("console.log('hello \nfrom \rthe \"string world!')", {
"from": "server1.conn9.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"hello \nfrom \rthe \"string world!"
],
@ -956,6 +966,7 @@ stubPackets.set("console.log('úṇĩçödê țĕșť')", {
"from": "server1.conn10.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"úṇĩçödê țĕșť"
],
@ -979,6 +990,7 @@ stubPackets.set("console.dirxml(window)", {
"from": "server1.conn11.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
{
"type": "object",
@ -1014,6 +1026,7 @@ stubPackets.set("console.trace()", {
"from": "server1.conn12.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [],
"columnNumber": 3,
"counter": null,
@ -1058,6 +1071,7 @@ stubPackets.set("console.time('bar')", {
"from": "server1.conn13.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"bar"
],
@ -1083,6 +1097,7 @@ stubPackets.set("console.timeEnd('bar')", {
"from": "server1.conn13.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"bar"
],
@ -1109,6 +1124,7 @@ stubPackets.set("console.table('bar')", {
"from": "server1.conn14.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"bar"
],
@ -1132,6 +1148,7 @@ stubPackets.set("console.table(['a', 'b', 'c'])", {
"from": "server1.conn15.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
{
"type": "object",
@ -1172,6 +1189,7 @@ stubPackets.set("console.group('bar')", {
"from": "server1.conn16.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"bar"
],
@ -1195,6 +1213,7 @@ stubPackets.set("console.groupEnd('bar')", {
"from": "server1.conn16.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"bar"
],
@ -1218,6 +1237,7 @@ stubPackets.set("console.groupCollapsed('foo')", {
"from": "server1.conn17.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"foo"
],
@ -1241,6 +1261,7 @@ stubPackets.set("console.groupEnd('foo')", {
"from": "server1.conn17.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"foo"
],
@ -1264,6 +1285,7 @@ stubPackets.set("console.group()", {
"from": "server1.conn18.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [],
"columnNumber": 1,
"counter": null,
@ -1285,6 +1307,7 @@ stubPackets.set("console.groupEnd()", {
"from": "server1.conn18.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [],
"columnNumber": 1,
"counter": null,
@ -1306,6 +1329,7 @@ stubPackets.set("console.log(%cfoobar)", {
"from": "server1.conn19.child1/consoleActor2",
"type": "consoleAPICall",
"message": {
"addonId": "",
"arguments": [
"foo",
"bar"

View File

@ -161,14 +161,14 @@ stubPackets.set("GET request", {
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 7,
"columnNumber": 9,
"functionName": null,
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null,
@ -216,14 +216,14 @@ stubPackets.set("GET request eventTimings", {
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 7,
"columnNumber": 9,
"functionName": null,
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null,
@ -280,14 +280,14 @@ stubPackets.set("XHR GET request", {
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 7,
"columnNumber": 9,
"functionName": null,
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null,
@ -335,14 +335,14 @@ stubPackets.set("XHR GET request eventTimings", {
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 7,
"columnNumber": 9,
"functionName": null,
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null,
@ -399,14 +399,14 @@ stubPackets.set("XHR POST request", {
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 7,
"columnNumber": 9,
"functionName": null,
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null,
@ -454,14 +454,14 @@ stubPackets.set("XHR POST request eventTimings", {
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 7,
"columnNumber": 9,
"functionName": null,
"asyncCause": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null,

View File

@ -23,7 +23,7 @@ stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessa
"messageText": "ReferenceError: asdf is not defined",
"parameters": null,
"repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"timeStamp\":1476573167137,\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null},{\"filename\":\"chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval\",\"lineNumber\":6,\"columnNumber\":9,\"functionName\":null},{\"filename\":\"chrome://mochikit/content/tests/BrowserTestUtils/content-task.js\",\"lineNumber\":53,\"columnNumber\":20,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":5},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null,\"notes\":null}",
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"timeStamp\":1476573167137,\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js line 52 > eval\",\"lineNumber\":6,\"columnNumber\":9,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"lineNumber\":53,\"columnNumber\":20,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":5},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null,\"notes\":null}",
"stacktrace": [
{
"filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html",
@ -44,13 +44,13 @@ stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessa
"functionName": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 6,
"columnNumber": 9,
"functionName": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null
@ -77,16 +77,16 @@ stubPreparedMessages.set("SyntaxError: redeclaration of let a", new ConsoleMessa
"messageText": "SyntaxError: redeclaration of let a",
"parameters": null,
"repeat": 1,
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"timeStamp\":1487992945524,\"type\":\"log\",\"level\":\"error\",\"messageText\":\"SyntaxError: redeclaration of let a\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval\",\"lineNumber\":6,\"columnNumber\":9,\"functionName\":null},{\"filename\":\"chrome://mochikit/content/tests/BrowserTestUtils/content-task.js\",\"lineNumber\":53,\"columnNumber\":20,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"userProvidedStyles\":null,\"notes\":[{\"messageBody\":\"Previously declared at line 2, column 6\",\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":6}}]}",
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"timeStamp\":1487992945524,\"type\":\"log\",\"level\":\"error\",\"messageText\":\"SyntaxError: redeclaration of let a\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"resource://testing-common/content-task.js line 52 > eval\",\"lineNumber\":6,\"columnNumber\":9,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"lineNumber\":53,\"columnNumber\":20,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"userProvidedStyles\":null,\"notes\":[{\"messageBody\":\"Previously declared at line 2, column 6\",\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":6}}]}",
"stacktrace": [
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 6,
"columnNumber": 9,
"functionName": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null
@ -150,13 +150,13 @@ stubPackets.set("ReferenceError: asdf is not defined", {
"functionName": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 6,
"columnNumber": 9,
"functionName": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null
@ -186,13 +186,13 @@ stubPackets.set("SyntaxError: redeclaration of let a", {
"private": false,
"stacktrace": [
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval",
"filename": "resource://testing-common/content-task.js line 52 > eval",
"lineNumber": 6,
"columnNumber": 9,
"functionName": null
},
{
"filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js",
"filename": "resource://testing-common/content-task.js",
"lineNumber": 53,
"columnNumber": 20,
"functionName": null

View File

@ -733,7 +733,7 @@ TabActor.prototype = {
}
// Collect the addonID from the document origin attributes.
let addonID = window.document.nodePrincipal.originAttributes.addonId;
let addonID = window.document.nodePrincipal.addonId;
return {
id,

View File

@ -301,8 +301,7 @@ ConsoleAPIListener.prototype =
// Filtering based on the originAttributes used by
// the Console API object.
if (message.originAttributes &&
message.originAttributes.addonId == this.addonId) {
if (message.addonId == this.addonId) {
return true;
}

View File

@ -309,7 +309,7 @@ WebExtensionActor.prototype._shouldAddNewGlobalAsDebuggee = function (newGlobal)
const global = unwrapDebuggerObjectGlobal(newGlobal);
if (global instanceof Ci.nsIDOMWindow) {
return global.document.nodePrincipal.originAttributes.addonId == this.id;
return global.document.nodePrincipal.addonId == this.id;
}
try {

View File

@ -7,6 +7,9 @@ const { console, ConsoleAPI } = require("resource://gre/modules/Console.jsm");
const { ConsoleAPIListener } = require("devtools/server/actors/utils/webconsole-listeners");
const Services = require("Services");
// FIXME: This test shouldn't need to rely on low-level internals.
const {Service} = Cu.import("resource://gre/modules/ExtensionManagement.jsm", {});
var seenMessages = 0;
var seenTypes = 0;
@ -16,8 +19,7 @@ var callback = {
do_check_eq(message.level, "warn");
do_check_eq(message.arguments[0], "Warning from foo");
seenTypes |= 1;
} else if (message.originAttributes &&
message.originAttributes.addonId == "bar") {
} else if (message.addonId == "bar") {
do_check_eq(message.level, "error");
do_check_eq(message.arguments[0], "Error from bar");
seenTypes |= 2;
@ -31,10 +33,15 @@ var callback = {
};
function createFakeAddonWindow({addonId} = {}) {
let baseURI = Services.io.newURI("about:blank");
let originAttributes = {addonId};
const uuidGen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
const uuid = uuidGen.generateUUID().number.slice(1, -1);
const url = `moz-extension://${uuid}/`;
Service.uuidMap.set(uuid, {id: addonId});
let baseURI = Services.io.newURI(url);
let principal = Services.scriptSecurityManager
.createCodebasePrincipal(baseURI, originAttributes);
.createCodebasePrincipal(baseURI, {});
let chromeWebNav = Services.appShell.createWindowlessBrowser(true);
let docShell = chromeWebNav.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell);
@ -49,6 +56,8 @@ function createFakeAddonWindow({addonId} = {}) {
* through to console messages.
*/
function run_test() {
Service.init();
// console1 Test Console.jsm messages tagged by the Addon SDK
// are still filtered correctly.
let console1 = new ConsoleAPI({

View File

@ -14,7 +14,6 @@
#include "mozilla/BasePrincipal.h"
#include "mozilla/Casting.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/PendingGlobalHistoryEntry.h"
#include "mozilla/dom/TabChild.h"
@ -8037,9 +8036,7 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
if (aPrincipal && !nsContentUtils::IsSystemPrincipal(aPrincipal) &&
mItemType != typeChrome) {
MOZ_ASSERT(ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(
aPrincipal->OriginAttributesRef(),
mOriginAttributes));
MOZ_ASSERT(aPrincipal->OriginAttributesRef() == mOriginAttributes);
}
// Make sure timing is created. But first record whether we had it
@ -12375,7 +12372,6 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
// get the OriginAttributes
OriginAttributes attrs;
loadInfo->GetOriginAttributes(&attrs);
attrs.StripAttributes(OriginAttributes::STRIP_ADDON_ID);
principalToInherit = nsNullPrincipal::Create(attrs);
}
} else {

View File

@ -31,7 +31,6 @@
#include "nsIAtom.h"
#include "nsIFile.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
#include "nsIPermissionManager.h"
#include "nsIPrincipal.h"
#include "nsIRunnable.h"
#include "nsISimpleEnumerator.h"
@ -350,11 +349,9 @@ public:
mPrincipalInfo(aPrincipalInfo),
mOpenMode(aOpenMode),
mWriteParams(aWriteParams),
mPersistence(quota::PERSISTENCE_TYPE_INVALID),
mState(eInitial),
mResult(JS::AsmJSCache_InternalError),
mIsApp(false),
mEnforcingQuota(true),
mDeleteReceived(false),
mActorDestroyed(false),
mOpened(false)
{
@ -393,31 +390,6 @@ private:
MOZ_ASSERT(!IsOnOwningThread());
}
// This method is called on the owning thread when no cache entry was found
// to open. If we just tried a lookup in persistent storage then we might
// still get a hit in temporary storage (for an asm.js module that wasn't
// compiled at install-time).
void
CacheMiss()
{
AssertIsOnOwningThread();
MOZ_ASSERT(mState == eFailedToReadMetadata ||
mState == eWaitingToOpenCacheFileForRead);
MOZ_ASSERT(mOpenMode == eOpenForRead);
if (mPersistence == quota::PERSISTENCE_TYPE_TEMPORARY) {
Fail();
return;
}
// Try again with a clean slate. InitOnMainThread will see that mPersistence
// is initialized and switch to temporary storage.
MOZ_ASSERT(mPersistence == quota::PERSISTENCE_TYPE_PERSISTENT);
FinishOnOwningThread();
mState = eInitial;
NS_DispatchToMainThread(this);
}
// This method is called on the owning thread when the JS engine is finished
// reading/writing the cache entry.
void
@ -447,7 +419,7 @@ private:
FinishOnOwningThread();
if (!mActorDestroyed) {
if (!mDeleteReceived && !mActorDestroyed) {
Unused << Send__delete__(this, mResult);
}
}
@ -466,9 +438,6 @@ private:
MOZ_ALWAYS_SUCCEEDS(mOwningThread->Dispatch(this, NS_DISPATCH_NORMAL));
}
void
InitPersistenceType();
nsresult
InitOnMainThread();
@ -519,6 +488,9 @@ private:
{
AssertIsOnOwningThread();
MOZ_ASSERT(mState != eFinished);
MOZ_ASSERT(!mDeleteReceived);
mDeleteReceived = true;
if (mOpened) {
Close();
@ -571,23 +543,12 @@ private:
return IPC_OK();
}
mozilla::ipc::IPCResult
RecvCacheMiss() override
{
AssertIsOnOwningThread();
CacheMiss();
return IPC_OK();
}
nsCOMPtr<nsIEventTarget> mOwningThread;
const PrincipalInfo mPrincipalInfo;
const OpenMode mOpenMode;
const WriteParams mWriteParams;
// State initialized during eInitial:
quota::PersistenceType mPersistence;
nsCString mSuffix;
nsCString mGroup;
nsCString mOrigin;
@ -607,7 +568,6 @@ private:
eWaitingToOpenDirectory, // Waiting to open directory
eWaitingToOpenMetadata, // Waiting to be called back from OpenDirectory
eReadyToReadMetadata, // Waiting to read the metadata file on the IO thread
eFailedToReadMetadata, // Waiting to be dispatched to owning thread after fail
eSendingMetadataForRead, // Waiting to send OnOpenMetadataForRead
eWaitingToOpenCacheFileForRead, // Waiting to hear back from child
eReadyToOpenCacheFileForRead, // Waiting to open cache file for read
@ -619,58 +579,11 @@ private:
State mState;
JS::AsmJSCacheResult mResult;
bool mIsApp;
bool mEnforcingQuota;
bool mDeleteReceived;
bool mActorDestroyed;
bool mOpened;
};
void
ParentRunnable::InitPersistenceType()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mState == eInitial);
if (mOpenMode == eOpenForWrite) {
MOZ_ASSERT(mPersistence == quota::PERSISTENCE_TYPE_INVALID);
// If we are performing install-time caching of an app, we'd like to store
// the cache entry in persistent storage so the entry is never evicted,
// but we need to check that quota is not enforced for the app.
// That justifies us in skipping all quota checks when storing the cache
// entry and avoids all the issues around the persistent quota prompt.
// If quota is enforced for the app, then we can still cache in temporary
// for a likely good first-run experience.
MOZ_ASSERT_IF(mWriteParams.mInstalled, mIsApp);
if (mWriteParams.mInstalled &&
!QuotaManager::IsQuotaEnforced(quota::PERSISTENCE_TYPE_PERSISTENT,
mOrigin, mIsApp)) {
mPersistence = quota::PERSISTENCE_TYPE_PERSISTENT;
} else {
mPersistence = quota::PERSISTENCE_TYPE_TEMPORARY;
}
return;
}
// For the reasons described above, apps may have cache entries in both
// persistent and temporary storage. At lookup time we don't know how and
// where the given script was cached, so start the search in persistent
// storage and, if that fails, search in temporary storage. (Non-apps can
// only be stored in temporary storage.)
MOZ_ASSERT_IF(mPersistence != quota::PERSISTENCE_TYPE_INVALID,
mIsApp && mPersistence == quota::PERSISTENCE_TYPE_PERSISTENT);
if (mPersistence == quota::PERSISTENCE_TYPE_INVALID && mIsApp) {
mPersistence = quota::PERSISTENCE_TYPE_PERSISTENT;
} else {
mPersistence = quota::PERSISTENCE_TYPE_TEMPORARY;
}
}
nsresult
ParentRunnable::InitOnMainThread()
{
@ -686,14 +599,9 @@ ParentRunnable::InitOnMainThread()
}
rv = QuotaManager::GetInfoFromPrincipal(principal, &mSuffix, &mGroup,
&mOrigin, &mIsApp);
&mOrigin);
NS_ENSURE_SUCCESS(rv, rv);
InitPersistenceType();
mEnforcingQuota =
QuotaManager::IsQuotaEnforced(mPersistence, mOrigin, mIsApp);
return NS_OK;
}
@ -708,10 +616,9 @@ ParentRunnable::OpenDirectory()
mState = eWaitingToOpenMetadata;
// XXX The exclusive lock shouldn't be needed for read operations.
QuotaManager::Get()->OpenDirectory(mPersistence,
QuotaManager::Get()->OpenDirectory(quota::PERSISTENCE_TYPE_TEMPORARY,
mGroup,
mOrigin,
mIsApp,
quota::Client::ASMJS,
/* aExclusive */ true,
this);
@ -727,8 +634,8 @@ ParentRunnable::ReadMetadata()
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
nsresult rv =
qm->EnsureOriginIsInitialized(mPersistence, mSuffix, mGroup, mOrigin,
mIsApp, getter_AddRefs(mDirectory));
qm->EnsureOriginIsInitialized(quota::PERSISTENCE_TYPE_TEMPORARY, mSuffix,
mGroup, mOrigin, getter_AddRefs(mDirectory));
if (NS_WARN_IF(NS_FAILED(rv))) {
mResult = JS::AsmJSCache_StorageInitFailure;
return rv;
@ -799,25 +706,24 @@ ParentRunnable::OpenCacheFileForWrite()
QuotaManager* qm = QuotaManager::Get();
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
if (mEnforcingQuota) {
// Create the QuotaObject before all file IO and keep it alive until caching
// completes to get maximum assertion coverage in QuotaManager against
// concurrent removal, etc.
mQuotaObject = qm->GetQuotaObject(mPersistence, mGroup, mOrigin, file);
NS_ENSURE_STATE(mQuotaObject);
// Create the QuotaObject before all file IO and keep it alive until caching
// completes to get maximum assertion coverage in QuotaManager against
// concurrent removal, etc.
mQuotaObject = qm->GetQuotaObject(quota::PERSISTENCE_TYPE_TEMPORARY, mGroup,
mOrigin, file);
NS_ENSURE_STATE(mQuotaObject);
if (!mQuotaObject->MaybeUpdateSize(mWriteParams.mSize,
/* aTruncate */ false)) {
// If the request fails, it might be because mOrigin is using too much
// space (MaybeUpdateSize will not evict our own origin since it is
// active). Try to make some space by evicting LRU entries until there is
// enough space.
EvictEntries(mDirectory, mGroup, mOrigin, mWriteParams.mSize, mMetadata);
if (!mQuotaObject->MaybeUpdateSize(mWriteParams.mSize,
/* aTruncate */ false)) {
// If the request fails, it might be because mOrigin is using too much
// space (MaybeUpdateSize will not evict our own origin since it is
// active). Try to make some space by evicting LRU entries until there is
// enough space.
EvictEntries(mDirectory, mGroup, mOrigin, mWriteParams.mSize, mMetadata);
if (!mQuotaObject->MaybeUpdateSize(mWriteParams.mSize,
/* aTruncate */ false)) {
mResult = JS::AsmJSCache_QuotaExceeded;
return NS_ERROR_FAILURE;
}
mResult = JS::AsmJSCache_QuotaExceeded;
return NS_ERROR_FAILURE;
}
}
@ -853,13 +759,12 @@ ParentRunnable::OpenCacheFileForRead()
QuotaManager* qm = QuotaManager::Get();
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
if (mEnforcingQuota) {
// Even though it's not strictly necessary, create the QuotaObject before
// all file IO and keep it alive until caching completes to get maximum
// assertion coverage in QuotaManager against concurrent removal, etc.
mQuotaObject = qm->GetQuotaObject(mPersistence, mGroup, mOrigin, file);
NS_ENSURE_STATE(mQuotaObject);
}
// Even though it's not strictly necessary, create the QuotaObject before all
// file IO and keep it alive until caching completes to get maximum assertion
// coverage in QuotaManager against concurrent removal, etc.
mQuotaObject = qm->GetQuotaObject(quota::PERSISTENCE_TYPE_TEMPORARY, mGroup,
mOrigin, file);
NS_ENSURE_STATE(mQuotaObject);
rv = file->GetFileSize(&mFileSize);
NS_ENSURE_SUCCESS(rv, rv);
@ -956,8 +861,7 @@ ParentRunnable::Run()
rv = ReadMetadata();
if (NS_FAILED(rv)) {
mState = eFailedToReadMetadata;
MOZ_ALWAYS_SUCCEEDS(mOwningThread->Dispatch(this, NS_DISPATCH_NORMAL));
FailOnNonOwningThread();
return NS_OK;
}
@ -979,18 +883,6 @@ ParentRunnable::Run()
return NS_OK;
}
case eFailedToReadMetadata: {
AssertIsOnOwningThread();
if (mOpenMode == eOpenForRead) {
CacheMiss();
return NS_OK;
}
Fail();
return NS_OK;
}
case eSendingMetadataForRead: {
AssertIsOnOwningThread();
MOZ_ASSERT(mOpenMode == eOpenForRead);
@ -1289,14 +1181,13 @@ private:
MOZ_ASSERT(mState == eOpening);
uint32_t moduleIndex;
if (FindHashMatch(aMetadata, mReadParams, &moduleIndex)) {
if (!SendSelectCacheFileToRead(moduleIndex)) {
return IPC_FAIL_NO_REASON(this);
}
if (!FindHashMatch(aMetadata, mReadParams, &moduleIndex)) {
Fail(JS::AsmJSCache_InternalError);
Send__delete__(this, JS::AsmJSCache_InternalError);
return IPC_OK();
}
if (!SendCacheMiss()) {
if (!SendSelectCacheFileToRead(moduleIndex)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
@ -1651,7 +1542,6 @@ CloseEntryForRead(size_t aSize,
JS::AsmJSCacheResult
OpenEntryForWrite(nsIPrincipal* aPrincipal,
bool aInstalled,
const char16_t* aBegin,
const char16_t* aEnd,
size_t aSize,
@ -1668,7 +1558,6 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
static_assert(sNumFastHashChars < sMinCachedModuleLength, "HashString safe");
WriteParams writeParams;
writeParams.mInstalled = aInstalled;
writeParams.mSize = aSize;
writeParams.mFastHash = HashString(aBegin, sNumFastHashChars);
writeParams.mNumChars = aEnd - aBegin;
@ -1890,7 +1779,6 @@ ParamTraits<WriteParams>::Write(Message* aMsg, const paramType& aParam)
WriteParam(aMsg, aParam.mFastHash);
WriteParam(aMsg, aParam.mNumChars);
WriteParam(aMsg, aParam.mFullHash);
WriteParam(aMsg, aParam.mInstalled);
}
bool
@ -1900,8 +1788,7 @@ ParamTraits<WriteParams>::Read(const Message* aMsg, PickleIterator* aIter,
return ReadParam(aMsg, aIter, &aResult->mSize) &&
ReadParam(aMsg, aIter, &aResult->mFastHash) &&
ReadParam(aMsg, aIter, &aResult->mNumChars) &&
ReadParam(aMsg, aIter, &aResult->mFullHash) &&
ReadParam(aMsg, aIter, &aResult->mInstalled);
ReadParam(aMsg, aIter, &aResult->mFullHash);
}
void
@ -1911,7 +1798,6 @@ ParamTraits<WriteParams>::Log(const paramType& aParam, std::wstring* aLog)
LogParam(aParam.mFastHash, aLog);
LogParam(aParam.mNumChars, aLog);
LogParam(aParam.mFullHash, aLog);
LogParam(aParam.mInstalled, aLog);
}
} // namespace IPC

View File

@ -73,14 +73,12 @@ struct WriteParams
int64_t mFastHash;
int64_t mNumChars;
int64_t mFullHash;
bool mInstalled;
WriteParams()
: mSize(0),
mFastHash(0),
mNumChars(0),
mFullHash(0),
mInstalled(false)
mFullHash(0)
{ }
};
@ -121,7 +119,6 @@ CloseEntryForRead(size_t aSize,
intptr_t aHandle);
JS::AsmJSCacheResult
OpenEntryForWrite(nsIPrincipal* aPrincipal,
bool aInstalled,
const char16_t* aBegin,
const char16_t* aEnd,
size_t aSize,

View File

@ -22,7 +22,6 @@ child:
async OnOpenMetadataForRead(Metadata metadata);
parent:
async SelectCacheFileToRead(uint32_t moduleIndex);
async CacheMiss();
child:
// Once the cache file has been opened, the child is notified and sent an

View File

@ -181,17 +181,6 @@ ChromeUtils::IsOriginAttributesEqual(dom::GlobalObject& aGlobal,
/* static */ bool
ChromeUtils::IsOriginAttributesEqual(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB)
{
return aA.mAddonId == aB.mAddonId &&
aA.mAppId == aB.mAppId &&
aA.mInIsolatedMozBrowser == aB.mInIsolatedMozBrowser &&
aA.mUserContextId == aB.mUserContextId &&
aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
}
/* static */ bool
ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB)
{
return aA.mAppId == aB.mAppId &&
aA.mInIsolatedMozBrowser == aB.mInIsolatedMozBrowser &&
@ -199,16 +188,5 @@ ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(const dom::OriginAttributesD
aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
}
/* static */ bool
ChromeUtils::IsOriginAttributesEqualIgnoringFPD(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB)
{
return aA.mAddonId == aB.mAddonId &&
aA.mAppId == aB.mAppId &&
aA.mInIsolatedMozBrowser == aB.mInIsolatedMozBrowser &&
aA.mUserContextId == aB.mUserContextId &&
aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
}
} // namespace dom
} // namespace mozilla

View File

@ -92,13 +92,15 @@ public:
IsOriginAttributesEqual(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB);
static bool
IsOriginAttributesEqualIgnoringAddonId(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB);
static bool
IsOriginAttributesEqualIgnoringFPD(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB);
const dom::OriginAttributesDictionary& aB)
{
return aA.mAppId == aB.mAppId &&
aA.mInIsolatedMozBrowser == aB.mInIsolatedMozBrowser &&
aA.mUserContextId == aB.mUserContextId &&
aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
}
};
} // namespace dom

View File

@ -105,7 +105,7 @@ PostMessageEvent::Run()
// don't do that in other places it seems better to hold the line for
// now. Long-term, we want HTML5 to address this so that we can
// be compliant while being safer.
if (!BasePrincipal::Cast(targetPrin)->EqualsIgnoringAddonId(mProvidedPrincipal)) {
if (!targetPrin->Equals(mProvidedPrincipal)) {
nsAutoString providedOrigin, targetOrigin;
nsresult rv = nsContentUtils::GetUTFOrigin(targetPrin, targetOrigin);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -3192,8 +3192,8 @@ nsContentUtils::GetOriginAttributes(nsIDocument* aDocument)
mozilla::OriginAttributes attrs;
nsCOMPtr<nsIChannel> channel = aDocument->GetChannel();
if (channel && NS_GetOriginAttributes(channel, attrs)) {
attrs.StripAttributes(OriginAttributes::STRIP_ADDON_ID);
if (channel) {
NS_GetOriginAttributes(channel, attrs);
}
return attrs;
}
@ -3210,8 +3210,8 @@ nsContentUtils::GetOriginAttributes(nsILoadGroup* aLoadGroup)
aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (callbacks) {
nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(callbacks);
if (loadContext && loadContext->GetOriginAttributes(attrs)) {
attrs.StripAttributes(OriginAttributes::STRIP_ADDON_ID);
if (loadContext) {
loadContext->GetOriginAttributes(attrs);
}
}
return attrs;

View File

@ -3059,8 +3059,7 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
nsCString origin;
nsresult rv =
quota::QuotaManager::GetInfoFromWindow(window, nullptr, nullptr, &origin,
nullptr);
quota::QuotaManager::GetInfoFromWindow(window, nullptr, nullptr, &origin);
NS_ENSURE_SUCCESS(rv, rv);
IDBOpenDBOptions options;

View File

@ -3175,7 +3175,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
newInnerWindow->GetDocGroup()->GetValidAccessPtr());
}
nsJSContext::PokeGC(JS::gcreason::SET_NEW_DOCUMENT, GetWrapperPreserveColor());
kungFuDeathGrip->DidInitializeContext();
// We wait to fire the debugger hook until the window is all set up and hooked

View File

@ -1183,8 +1183,9 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
IsShrinking aShrinking,
int64_t aSliceMillis)
{
PROFILER_LABEL("nsJSContext", "GarbageCollectNow",
js::ProfileEntry::Category::GC);
PROFILER_LABEL_PRINTF("nsJSContext", "GarbageCollectNow",
js::ProfileEntry::Category::GC,
"%s", JS::gcreason::ExplainReason(aReason));
MOZ_ASSERT_IF(aSliceMillis, aIncremental == IncrementalGC);
@ -2400,7 +2401,6 @@ AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
static JS::AsmJSCacheResult
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
bool aInstalled,
const char16_t* aBegin,
const char16_t* aEnd,
size_t aSize,
@ -2409,8 +2409,8 @@ AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
{
nsIPrincipal* principal =
nsJSPrincipals::get(JS_GetCompartmentPrincipals(js::GetObjectCompartment(aGlobal)));
return asmjscache::OpenEntryForWrite(principal, aInstalled, aBegin, aEnd,
aSize, aMemory, aHandle);
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
aHandle);
}
class AsyncTaskRunnable final : public Runnable

View File

@ -260,7 +260,6 @@ Context::QuotaInitRunnable::OpenDirectory()
QuotaManager::Get()->OpenDirectory(PERSISTENCE_TYPE_DEFAULT,
mQuotaInfo.mGroup,
mQuotaInfo.mOrigin,
mQuotaInfo.mIsApp,
quota::Client::DOMCACHE,
/* aExclusive */ false,
this);
@ -377,8 +376,7 @@ Context::QuotaInitRunnable::Run()
nsresult rv = QuotaManager::GetInfoFromPrincipal(principal,
&mQuotaInfo.mSuffix,
&mQuotaInfo.mGroup,
&mQuotaInfo.mOrigin,
&mQuotaInfo.mIsApp);
&mQuotaInfo.mOrigin);
if (NS_WARN_IF(NS_FAILED(rv))) {
resolver->Resolve(rv);
break;
@ -437,7 +435,6 @@ Context::QuotaInitRunnable::Run()
mQuotaInfo.mSuffix,
mQuotaInfo.mGroup,
mQuotaInfo.mOrigin,
mQuotaInfo.mIsApp,
getter_AddRefs(mQuotaInfo.mDir));
if (NS_FAILED(rv)) {
resolver->Resolve(rv);

View File

@ -30,8 +30,7 @@ ManagerId::Create(nsIPrincipal* aPrincipal, ManagerId** aManagerIdOut)
nsresult rv = QuotaManager::GetInfoFromPrincipal(aPrincipal,
nullptr, // suffix
nullptr, // group
&quotaOrigin,
nullptr); // is app
&quotaOrigin);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
RefPtr<ManagerId> ref = new ManagerId(aPrincipal, quotaOrigin);

2
dom/cache/Types.h vendored
View File

@ -29,12 +29,10 @@ static const CacheId INVALID_CACHE_ID = -1;
struct QuotaInfo
{
QuotaInfo() : mIsApp(false) { }
nsCOMPtr<nsIFile> mDir;
nsCString mSuffix;
nsCString mGroup;
nsCString mOrigin;
bool mIsApp;
};
} // namespace cache

View File

@ -43,5 +43,6 @@ support-files =
[test_cache_shrink.html]
[test_cache_orphaned_cache.html]
[test_cache_orphaned_body.html]
scheme=https
[test_cache_untrusted.html]
[test_chrome_constructor.html]

View File

@ -157,6 +157,15 @@ public:
mOriginAttributes = aOriginAttributes;
}
void
SetAddonId(nsIPrincipal* aPrincipal)
{
nsAutoString addonId;
aPrincipal->GetAddonId(addonId);
mAddonId = addonId;
}
bool
PopulateArgumentsSequence(Sequence<JS::Value>& aSequence) const
{
@ -250,6 +259,8 @@ public:
OriginAttributes mOriginAttributes;
nsString mAddonId;
nsString mMethodString;
// Stack management is complicated, because we want to do it as
@ -1217,6 +1228,7 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
}
oa = principal->OriginAttributesRef();
callData->SetAddonId(principal);
#ifdef DEBUG
if (!nsContentUtils::IsSystemPrincipal(principal)) {
@ -1500,6 +1512,8 @@ Console::PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
event.mOriginAttributes = originAttributesValue;
}
event.mAddonId = aData->mAddonId;
event.mID.Construct();
event.mInnerID.Construct();

View File

@ -681,7 +681,7 @@ DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
// Don't allow the custom type to be assigned.
if (aFormat.EqualsLiteral(kCustomTypesMime)) {
return NS_ERROR_TYPE_ERR;
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
if (!PrincipalMaySetData(aFormat, aData, aSubjectPrincipal)) {

View File

@ -291,8 +291,13 @@ FileReader::DoReadData(uint64_t aCount)
NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
mAsyncStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
&bytesRead);
nsresult rv =
mAsyncStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
&bytesRead);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(bytesRead == aCount, "failed to read data");
}
else {
@ -314,7 +319,11 @@ FileReader::DoReadData(uint64_t aCount)
uint32_t bytesRead = 0;
MOZ_DIAGNOSTIC_ASSERT(mFileData);
mAsyncStream->Read(mFileData + mDataLen, aCount, &bytesRead);
nsresult rv = mAsyncStream->Read(mFileData + mDataLen, aCount, &bytesRead);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(bytesRead == aCount, "failed to read data");
}
@ -613,25 +622,25 @@ FileReader::OnInputStreamReady(nsIAsyncInputStream* aStream)
// be 100% sure we have a workerHolder when OnLoadEnd() is called.
FileReaderDecreaseBusyCounter RAII(this);
uint64_t aCount;
nsresult rv = aStream->Available(&aCount);
uint64_t count;
nsresult rv = aStream->Available(&count);
if (NS_SUCCEEDED(rv) && aCount) {
rv = DoReadData(aCount);
if (NS_SUCCEEDED(rv) && count) {
rv = DoReadData(count);
}
if (NS_SUCCEEDED(rv)) {
rv = DoAsyncWait();
}
if (NS_FAILED(rv) || !aCount) {
if (NS_FAILED(rv) || !count) {
if (rv == NS_BASE_STREAM_CLOSED) {
rv = NS_OK;
}
return OnLoadEnd(rv);
}
mTransferred += aCount;
mTransferred += count;
//Notify the timer is the appropriate timeframe has passed
if (mTimerIsActive) {

View File

@ -6615,14 +6615,6 @@ HTMLInputElement::GetSelectionRange(int32_t* aSelectionStart,
if (IsInComposedDoc()) {
GetComposedDoc()->FlushPendingNotifications(FlushType::Frames);
}
if (!GetPrimaryFrame()) {
// Can we return a selection range anyway here, now that it lives on our
// state? In fact, could we make this behave more like
// GetSelectionDirection, in the sense of working even when we have no
// frame, by just delegating entirely to mState? And then, do we really
// need the flush?
return NS_ERROR_FAILURE;
}
nsTextEditorState* state = GetEditorState();
if (!state) {

View File

@ -848,14 +848,6 @@ HTMLTextAreaElement::GetSelectionRange(int32_t* aSelectionStart,
if (IsInComposedDoc()) {
GetComposedDoc()->FlushPendingNotifications(FlushType::Frames);
}
if (!GetPrimaryFrame()) {
// Can we return a selection range anyway here, now that it lives on our
// state? In fact, could we make this behave more like
// GetSelectionDirection, in the sense of working even when we have no
// frame, by just delegating entirely to mState? And then, do we really
// need the flush?
return NS_ERROR_FAILURE;
}
return mState.GetSelectionRange(aSelectionStart, aSelectionEnd);
}

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<script>
document.documentElement.scrollTop = "500";
o1 = document.createRange();
o2 = document.createElement('input');
o1.selectNode(document.documentElement);
o1.surroundContents(o2);
o2.selectionStart;
</script>
</head>
<body></body>
</html>

View File

@ -0,0 +1,3 @@
<input xmlns="http://www.w3.org/1999/xhtml">
<script>document.documentElement.selectionStart</script>
</input>

View File

@ -0,0 +1,3 @@
<textarea xmlns="http://www.w3.org/1999/xhtml">
<script>document.documentElement.selectionStart</script>
</textarea>

View File

@ -78,3 +78,6 @@ load 1237633.html
load 1281972-1.html
load 1282894.html
load 1290904.html
load 1343886-1.html
load 1343886-2.xml
load 1343886-3.xml

View File

@ -1553,11 +1553,13 @@ nsresult
nsTextEditorState::GetSelectionRange(int32_t* aSelectionStart,
int32_t* aSelectionEnd)
{
MOZ_ASSERT(mBoundFrame,
"Caller didn't flush out frames and check for a frame?");
MOZ_ASSERT(aSelectionStart);
MOZ_ASSERT(aSelectionEnd);
if (!mBoundFrame) {
return NS_ERROR_FAILURE;
}
// It's not clear that all the checks here are needed, but the previous
// version of this code in nsTextControlFrame was doing them, so we keep them
// for now.

View File

@ -166,7 +166,7 @@ static_assert(JS_STRUCTURED_CLONE_VERSION == 8,
"Need to update the major schema version.");
// Major schema version. Bump for almost everything.
const uint32_t kMajorSchemaVersion = 25;
const uint32_t kMajorSchemaVersion = 26;
// Minor schema version. Should almost always be 0 (maybe bump on release
// branches if we have to).
@ -244,6 +244,7 @@ const uint32_t kFileCopyBufferSize = 32768;
#define JOURNAL_DIRECTORY_NAME "journals"
const char kFileManagerDirectoryNameSuffix[] = ".files";
const char kSQLiteSuffix[] = ".sqlite";
const char kSQLiteJournalSuffix[] = ".sqlite-journal";
const char kSQLiteSHMSuffix[] = ".sqlite-shm";
const char kSQLiteWALSuffix[] = ".sqlite-wal";
@ -4134,6 +4135,110 @@ UpgradeSchemaFrom24_0To25_0(mozIStorageConnection* aConnection)
return NS_OK;
}
class StripObsoleteOriginAttributesFunction final
: public mozIStorageFunction
{
public:
NS_DECL_ISUPPORTS
private:
~StripObsoleteOriginAttributesFunction()
{ }
NS_IMETHOD
OnFunctionCall(mozIStorageValueArray* aArguments,
nsIVariant** aResult) override
{
MOZ_ASSERT(aArguments);
MOZ_ASSERT(aResult);
PROFILER_LABEL("IndexedDB",
"StripObsoleteOriginAttributesFunction::OnFunctionCall",
js::ProfileEntry::Category::STORAGE);
#ifdef DEBUG
{
uint32_t argCount;
MOZ_ALWAYS_SUCCEEDS(aArguments->GetNumEntries(&argCount));
MOZ_ASSERT(argCount == 1);
int32_t type;
MOZ_ALWAYS_SUCCEEDS(aArguments->GetTypeOfIndex(0, &type));
MOZ_ASSERT(type == mozIStorageValueArray::VALUE_TYPE_TEXT);
}
#endif
nsCString origin;
nsresult rv = aArguments->GetUTF8String(0, origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Deserialize and re-serialize to automatically drop any obsolete origin
// attributes.
OriginAttributes oa;
nsCString originNoSuffix;
bool ok = oa.PopulateFromOrigin(origin, originNoSuffix);
if (NS_WARN_IF(!ok)) {
return NS_ERROR_FAILURE;
}
nsCString suffix;
oa.CreateSuffix(suffix);
nsCOMPtr<nsIVariant> result =
new mozilla::storage::UTF8TextVariant(originNoSuffix + suffix);
result.forget(aResult);
return NS_OK;
}
};
nsresult
UpgradeSchemaFrom25_0To26_0(mozIStorageConnection* aConnection)
{
AssertIsOnIOThread();
MOZ_ASSERT(aConnection);
PROFILER_LABEL("IndexedDB",
"UpgradeSchemaFrom25_0To26_0",
js::ProfileEntry::Category::STORAGE);
NS_NAMED_LITERAL_CSTRING(functionName, "strip_obsolete_attributes");
nsCOMPtr<mozIStorageFunction> stripObsoleteAttributes =
new StripObsoleteOriginAttributesFunction();
nsresult rv = aConnection->CreateFunction(functionName,
/* aNumArguments */ 1,
stripObsoleteAttributes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"UPDATE DATABASE "
"SET origin = strip_obsolete_attributes(origin) "
"WHERE origin LIKE '%^%';"
));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aConnection->RemoveFunction(functionName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = aConnection->SetSchemaVersion(MakeSchemaVersion(26, 0));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
GetDatabaseFileURL(nsIFile* aDatabaseFile,
PersistenceType aPersistenceType,
@ -4640,7 +4745,7 @@ CreateStorageConnection(nsIFile* aDBFile,
}
} else {
// This logic needs to change next time we change the schema!
static_assert(kSQLiteSchemaVersion == int32_t((25 << 4) + 0),
static_assert(kSQLiteSchemaVersion == int32_t((26 << 4) + 0),
"Upgrade function needed due to schema version increase.");
while (schemaVersion != kSQLiteSchemaVersion) {
@ -4688,6 +4793,8 @@ CreateStorageConnection(nsIFile* aDBFile,
rv = UpgradeSchemaFrom23_0To24_0(connection);
} else if (schemaVersion == MakeSchemaVersion(24, 0)) {
rv = UpgradeSchemaFrom24_0To25_0(connection);
} else if (schemaVersion == MakeSchemaVersion(25, 0)) {
rv = UpgradeSchemaFrom25_0To26_0(connection);
} else {
IDB_WARNING("Unable to open IndexedDB database, no upgrade path is "
"available!");
@ -7482,7 +7589,6 @@ protected:
nsCString mDatabaseId;
nsString mDatabaseFilePath;
State mState;
bool mIsApp;
bool mEnforcingQuota;
const bool mDeleting;
bool mBlockedDatabaseOpen;
@ -9234,6 +9340,9 @@ public:
mozilla::dom::quota::Client::Type
GetType() override;
nsresult
UpgradeStorageFrom1_0To2_0(nsIFile* aDirectory) override;
nsresult
InitOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup,
@ -9283,6 +9392,13 @@ private:
const nsACString& aOrigin,
nsIFile** aDirectory);
nsresult
GetDatabaseFilenames(nsIFile* aDirectory,
UsageInfo* aUsageInfo,
bool aForUpgrade,
nsTArray<nsString>& aSubdirsToProcess,
nsTHashtable<nsStringHashKey>& aDatabaseFilename);
nsresult
GetUsageForDirectoryInternal(nsIFile* aDirectory,
UsageInfo* aUsageInfo,
@ -10041,24 +10157,21 @@ DeserializeStructuredCloneFiles(FileManager* aFileManager,
}
bool
GetDatabaseBaseFilename(const nsAString& aFilename,
nsDependentSubstring& aDatabaseBaseFilename)
GetBaseFilename(const nsAString& aFilename,
const nsAString& aSuffix,
nsDependentSubstring& aBaseFilename)
{
MOZ_ASSERT(!aFilename.IsEmpty());
MOZ_ASSERT(aDatabaseBaseFilename.IsEmpty());
MOZ_ASSERT(aBaseFilename.IsEmpty());
NS_NAMED_LITERAL_STRING(sqlite, ".sqlite");
if (!StringEndsWith(aFilename, sqlite) ||
aFilename.Length() == sqlite.Length()) {
if (!StringEndsWith(aFilename, aSuffix) ||
aFilename.Length() == aSuffix.Length()) {
return false;
}
MOZ_ASSERT(aFilename.Length() > sqlite.Length());
MOZ_ASSERT(aFilename.Length() > aSuffix.Length());
aDatabaseBaseFilename.Rebind(aFilename,
0,
aFilename.Length() - sqlite.Length());
aBaseFilename.Rebind(aFilename, 0, aFilename.Length() - aSuffix.Length());
return true;
}
@ -17087,7 +17200,6 @@ Cursor::RecvContinue(const CursorRequestParams& aParams)
FileManager::FileManager(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aIsApp,
const nsAString& aDatabaseName,
bool aEnforcingQuota)
: mPersistenceType(aPersistenceType)
@ -17095,7 +17207,6 @@ FileManager::FileManager(PersistenceType aPersistenceType,
, mOrigin(aOrigin)
, mDatabaseName(aDatabaseName)
, mLastFileId(0)
, mIsApp(aIsApp)
, mEnforcingQuota(aEnforcingQuota)
, mInvalidated(false)
{ }
@ -17711,12 +17822,103 @@ QuotaClient::GetType()
return QuotaClient::IDB;
}
struct FileManagerInitInfo
nsresult
QuotaClient::UpgradeStorageFrom1_0To2_0(nsIFile* aDirectory)
{
nsCOMPtr<nsIFile> mDirectory;
nsCOMPtr<nsIFile> mDatabaseFile;
nsCOMPtr<nsIFile> mDatabaseWALFile;
};
AssertIsOnIOThread();
MOZ_ASSERT(aDirectory);
AutoTArray<nsString, 20> subdirsToProcess;
nsTHashtable<nsStringHashKey> databaseFilenames(20);
nsresult rv = GetDatabaseFilenames(aDirectory,
nullptr,
/* aForUpgrade */ true,
subdirsToProcess,
databaseFilenames);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
const NS_ConvertASCIItoUTF16 filesSuffix(
kFileManagerDirectoryNameSuffix,
LiteralStringLength(kFileManagerDirectoryNameSuffix));
for (uint32_t count = subdirsToProcess.Length(), i = 0; i < count; i++) {
const nsString& subdirName = subdirsToProcess[i];
// If the directory has the correct suffix then it should exist in
// databaseFilenames.
nsDependentSubstring subdirNameBase;
if (GetBaseFilename(subdirName, filesSuffix, subdirNameBase)) {
Unused << NS_WARN_IF(!databaseFilenames.GetEntry(subdirNameBase));
continue;
}
// The directory didn't have the right suffix but we might need to rename
// it. Check to see if we have a database that references this directory.
nsString subdirNameWithSuffix;
if (databaseFilenames.GetEntry(subdirName)) {
subdirNameWithSuffix = subdirName + filesSuffix;
} else {
// Windows doesn't allow a directory to end with a dot ('.'), so we have
// to check that possibility here too.
// We do this on all platforms, because the origin directory may have
// been created on Windows and now accessed on different OS.
nsString subdirNameWithDot = subdirName + NS_LITERAL_STRING(".");
if (NS_WARN_IF(!databaseFilenames.GetEntry(subdirNameWithDot))) {
continue;
}
subdirNameWithSuffix = subdirNameWithDot + filesSuffix;
}
// We do have a database that uses this directory so we should rename it
// now. However, first check to make sure that we're not overwriting
// something else.
nsCOMPtr<nsIFile> subdir;
rv = aDirectory->Clone(getter_AddRefs(subdir));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = subdir->Append(subdirNameWithSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool exists;
rv = subdir->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (exists) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
rv = aDirectory->Clone(getter_AddRefs(subdir));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = subdir->Append(subdirName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
DebugOnly<bool> isDirectory;
MOZ_ASSERT(NS_SUCCEEDED(subdir->IsDirectory(&isDirectory)));
MOZ_ASSERT(isDirectory);
rv = subdir->RenameTo(nullptr, subdirNameWithSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
nsresult
QuotaClient::InitOrigin(PersistenceType aPersistenceType,
@ -17738,12 +17940,12 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
// and also get the usage.
AutoTArray<nsString, 20> subdirsToProcess;
nsTArray<nsCOMPtr<nsIFile>> unknownFiles;
nsTHashtable<nsStringHashKey> validSubdirs(20);
AutoTArray<FileManagerInitInfo, 20> initInfos;
nsCOMPtr<nsISimpleEnumerator> entries;
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
nsTHashtable<nsStringHashKey> databaseFilenames(20);
rv = GetDatabaseFilenames(directory,
aUsageInfo,
/* aForUpgrade */ false,
subdirsToProcess,
databaseFilenames);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -17752,73 +17954,28 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
kFileManagerDirectoryNameSuffix,
LiteralStringLength(kFileManagerDirectoryNameSuffix));
const NS_ConvertASCIItoUTF16 journalSuffix(
kSQLiteJournalSuffix,
LiteralStringLength(kSQLiteJournalSuffix));
const NS_ConvertASCIItoUTF16 shmSuffix(kSQLiteSHMSuffix,
LiteralStringLength(kSQLiteSHMSuffix));
for (uint32_t count = subdirsToProcess.Length(), i = 0; i < count; i++) {
const nsString& subdirName = subdirsToProcess[i];
// The directory must have the correct suffix.
nsDependentSubstring subdirNameBase;
if (NS_WARN_IF(!GetBaseFilename(subdirName, filesSuffix, subdirNameBase))) {
return NS_ERROR_UNEXPECTED;
}
// The directory base must exist in databaseFilenames.
if (NS_WARN_IF(!databaseFilenames.GetEntry(subdirNameBase))) {
return NS_ERROR_UNEXPECTED;
}
}
const NS_ConvertASCIItoUTF16 sqliteSuffix(kSQLiteSuffix,
LiteralStringLength(kSQLiteSuffix));
const NS_ConvertASCIItoUTF16 walSuffix(kSQLiteWALSuffix,
LiteralStringLength(kSQLiteWALSuffix));
bool hasMore;
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
hasMore &&
(!aUsageInfo || !aUsageInfo->Canceled())) {
nsCOMPtr<nsISupports> entry;
rv = entries->GetNext(getter_AddRefs(entry));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
MOZ_ASSERT(file);
nsString leafName;
rv = file->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isDirectory;
rv = file->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDirectory) {
if (!StringEndsWith(leafName, filesSuffix) ||
!validSubdirs.GetEntry(leafName)) {
subdirsToProcess.AppendElement(leafName);
}
continue;
}
// Skip Desktop Service Store (.DS_Store) files. These files are only used
// on Mac OS X, but the profile can be shared across different operating
// systems, so we check it on all platforms.
if (leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
continue;
}
// Skip SQLite temporary files. These files take up space on disk but will
// be deleted as soon as the database is opened, so we don't count them
// towards quota.
if (StringEndsWith(leafName, journalSuffix) ||
StringEndsWith(leafName, shmSuffix)) {
continue;
}
// The SQLite WAL file does count towards quota, but it is handled below
// once we find the actual database file.
if (StringEndsWith(leafName, walSuffix)) {
continue;
}
nsDependentSubstring dbBaseFilename;
if (!GetDatabaseBaseFilename(leafName, dbBaseFilename)) {
unknownFiles.AppendElement(file);
continue;
}
for (auto iter = databaseFilenames.ConstIter(); !iter.Done(); iter.Next()) {
auto& databaseFilename = iter.Get()->GetKey();
nsCOMPtr<nsIFile> fmDirectory;
rv = directory->Clone(getter_AddRefs(fmDirectory));
@ -17826,9 +17983,18 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
return rv;
}
nsString fmDirectoryBaseName = dbBaseFilename + filesSuffix;
rv = fmDirectory->Append(databaseFilename + filesSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = fmDirectory->Append(fmDirectoryBaseName);
nsCOMPtr<nsIFile> databaseFile;
rv = directory->Clone(getter_AddRefs(databaseFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = databaseFile->Append(databaseFilename + sqliteSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -17840,115 +18006,25 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
return rv;
}
rv = walFile->Append(dbBaseFilename + walSuffix);
rv = walFile->Append(databaseFilename + walSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
FileManagerInitInfo* initInfo = initInfos.AppendElement();
initInfo->mDirectory.swap(fmDirectory);
initInfo->mDatabaseFile.swap(file);
initInfo->mDatabaseWALFile.swap(walFile);
validSubdirs.PutEntry(fmDirectoryBaseName);
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
for (uint32_t count = subdirsToProcess.Length(), i = 0; i < count; i++) {
const nsString& subdirName = subdirsToProcess[i];
// If the directory has the correct suffix then it must exist in
// validSubdirs.
if (StringEndsWith(subdirName, filesSuffix)) {
if (NS_WARN_IF(!validSubdirs.GetEntry(subdirName))) {
return NS_ERROR_UNEXPECTED;
}
continue;
}
// The directory didn't have the right suffix but we might need to rename
// it. Check to see if we have a database that references this directory.
nsString subdirNameWithSuffix = subdirName + filesSuffix;
if (!validSubdirs.GetEntry(subdirNameWithSuffix)) {
// Windows doesn't allow a directory to end with a dot ('.'), so we have
// to check that possibility here too.
// We do this on all platforms, because the origin directory may have
// been created on Windows and now accessed on different OS.
subdirNameWithSuffix = subdirName + NS_LITERAL_STRING(".") + filesSuffix;
if (NS_WARN_IF(!validSubdirs.GetEntry(subdirNameWithSuffix))) {
return NS_ERROR_UNEXPECTED;
}
}
// We do have a database that uses this directory so we should rename it
// now. However, first check to make sure that we're not overwriting
// something else.
nsCOMPtr<nsIFile> subdir;
rv = directory->Clone(getter_AddRefs(subdir));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = subdir->Append(subdirNameWithSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool exists;
rv = subdir->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (exists) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
rv = directory->Clone(getter_AddRefs(subdir));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = subdir->Append(subdirName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
DebugOnly<bool> isDirectory;
MOZ_ASSERT(NS_SUCCEEDED(subdir->IsDirectory(&isDirectory)));
MOZ_ASSERT(isDirectory);
rv = subdir->RenameTo(nullptr, subdirNameWithSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
for (uint32_t count = initInfos.Length(), i = 0; i < count; i++) {
FileManagerInitInfo& initInfo = initInfos[i];
MOZ_ASSERT(initInfo.mDirectory);
MOZ_ASSERT(initInfo.mDatabaseFile);
MOZ_ASSERT_IF(aUsageInfo, initInfo.mDatabaseWALFile);
rv = FileManager::InitDirectory(initInfo.mDirectory,
initInfo.mDatabaseFile,
rv = FileManager::InitDirectory(fmDirectory,
databaseFile,
aPersistenceType,
aGroup,
aOrigin,
TelemetryIdForFile(initInfo.mDatabaseFile));
TelemetryIdForFile(databaseFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (aUsageInfo && !aUsageInfo->Canceled()) {
int64_t fileSize;
rv = initInfo.mDatabaseFile->GetFileSize(&fileSize);
rv = databaseFile->GetFileSize(&fileSize);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -17957,7 +18033,7 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
rv = initInfo.mDatabaseWALFile->GetFileSize(&fileSize);
rv = walFile->GetFileSize(&fileSize);
if (NS_SUCCEEDED(rv)) {
MOZ_ASSERT(fileSize >= 0);
aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
@ -17967,7 +18043,7 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
}
uint64_t usage;
rv = FileManager::GetUsage(initInfo.mDirectory, &usage);
rv = FileManager::GetUsage(fmDirectory, &usage);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -17976,34 +18052,6 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
}
}
// We have to do this after file manager initialization.
if (!unknownFiles.IsEmpty()) {
#ifdef DEBUG
for (uint32_t count = unknownFiles.Length(), i = 0; i < count; i++) {
nsCOMPtr<nsIFile>& unknownFile = unknownFiles[i];
nsString leafName;
MOZ_ALWAYS_SUCCEEDS(unknownFile->GetLeafName(leafName));
MOZ_ASSERT(!StringEndsWith(leafName, journalSuffix));
MOZ_ASSERT(!StringEndsWith(leafName, shmSuffix));
MOZ_ASSERT(!StringEndsWith(leafName, walSuffix));
nsString path;
MOZ_ALWAYS_SUCCEEDS(unknownFile->GetPath(path));
MOZ_ASSERT(!path.IsEmpty());
nsPrintfCString warning(R"(Refusing to open databases for "%s" because )"
R"(an unexpected file exists in the storage )"
R"(area: "%s")",
PromiseFlatCString(aOrigin).get(),
NS_ConvertUTF16toUTF8(path).get());
NS_WARNING(warning.get());
}
#endif
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
@ -18209,6 +18257,109 @@ QuotaClient::GetDirectory(PersistenceType aPersistenceType,
return NS_OK;
}
nsresult
QuotaClient::GetDatabaseFilenames(
nsIFile* aDirectory,
UsageInfo* aUsageInfo,
bool aForUpgrade,
nsTArray<nsString>& aSubdirsToProcess,
nsTHashtable<nsStringHashKey>& aDatabaseFilenames)
{
AssertIsOnIOThread();
nsCOMPtr<nsISimpleEnumerator> entries;
nsresult rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
const NS_ConvertASCIItoUTF16 sqliteSuffix(kSQLiteSuffix,
LiteralStringLength(kSQLiteSuffix));
const NS_ConvertASCIItoUTF16 journalSuffix(
kSQLiteJournalSuffix,
LiteralStringLength(kSQLiteJournalSuffix));
const NS_ConvertASCIItoUTF16 shmSuffix(kSQLiteSHMSuffix,
LiteralStringLength(kSQLiteSHMSuffix));
const NS_ConvertASCIItoUTF16 walSuffix(kSQLiteWALSuffix,
LiteralStringLength(kSQLiteWALSuffix));
bool hasMore;
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
hasMore &&
(!aUsageInfo || !aUsageInfo->Canceled())) {
nsCOMPtr<nsISupports> entry;
rv = entries->GetNext(getter_AddRefs(entry));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
MOZ_ASSERT(file);
nsString leafName;
rv = file->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isDirectory;
rv = file->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDirectory) {
aSubdirsToProcess.AppendElement(leafName);
continue;
}
// Skip Desktop Service Store (.DS_Store) files. These files are only used
// on Mac OS X, but the profile can be shared across different operating
// systems, so we check it on all platforms.
if (leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
continue;
}
// Skip SQLite temporary files. These files take up space on disk but will
// be deleted as soon as the database is opened, so we don't count them
// towards quota.
if (StringEndsWith(leafName, journalSuffix) ||
StringEndsWith(leafName, shmSuffix)) {
continue;
}
// The SQLite WAL file does count towards quota, but it is handled below
// once we find the actual database file.
if (StringEndsWith(leafName, walSuffix)) {
continue;
}
nsDependentSubstring leafNameBase;
if (!GetBaseFilename(leafName, sqliteSuffix, leafNameBase)) {
nsString path;
MOZ_ALWAYS_SUCCEEDS(file->GetPath(path));
MOZ_ASSERT(!path.IsEmpty());
nsPrintfCString warning(R"(An unexpected file exists in the storage )"
R"(area: "%s")",
NS_ConvertUTF16toUTF8(path).get());
NS_WARNING(warning.get());
if (!aForUpgrade) {
return NS_ERROR_UNEXPECTED;
}
continue;
}
aDatabaseFilenames.PutEntry(leafNameBase);
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
QuotaClient::GetUsageForDirectoryInternal(nsIFile* aDirectory,
UsageInfo* aUsageInfo,
@ -18646,14 +18797,12 @@ Maintenance::DirectoryWork()
int64_t dummyTimeStamp;
nsCString dummySuffix;
bool dummyIsApp;
if (NS_WARN_IF(NS_FAILED(
quotaManager->GetDirectoryMetadata2(originDir,
&dummyTimeStamp,
dummySuffix,
group,
origin,
&dummyIsApp)))) {
origin)))) {
// Not much we can do here...
continue;
}
@ -19473,6 +19622,7 @@ AutoProgressHandler::OnProgress(mozIStorageConnection* aConnection,
NS_IMPL_ISUPPORTS(CompressDataBlobsFunction, mozIStorageFunction)
NS_IMPL_ISUPPORTS(EncodeKeysFunction, mozIStorageFunction)
NS_IMPL_ISUPPORTS(StripObsoleteOriginAttributesFunction, mozIStorageFunction);
#if !defined(MOZ_B2G)
@ -19486,7 +19636,6 @@ UpgradeFileIdsFunction::Init(nsIFile* aFMDirectory,
new FileManager(PERSISTENCE_TYPE_INVALID,
EmptyCString(),
EmptyCString(),
false,
EmptyString(),
false);
@ -20735,7 +20884,6 @@ FactoryOp::FactoryOp(Factory* aFactory,
, mContentParent(Move(aContentParent))
, mCommonParams(aCommonParams)
, mState(State::Initial)
, mIsApp(false)
, mEnforcingQuota(true)
, mDeleting(aDeleting)
, mBlockedDatabaseOpen(false)
@ -21084,13 +21232,12 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
}
if (State::Initial == mState) {
QuotaManager::GetInfoForChrome(&mSuffix, &mGroup, &mOrigin, &mIsApp);
QuotaManager::GetInfoForChrome(&mSuffix, &mGroup, &mOrigin);
MOZ_ASSERT(!QuotaManager::IsFirstPromptRequired(persistenceType, mOrigin,
mIsApp));
MOZ_ASSERT(
QuotaManager::IsOriginWhitelistedForPersistentStorage(mOrigin));
mEnforcingQuota =
QuotaManager::IsQuotaEnforced(persistenceType, mOrigin, mIsApp);
mEnforcingQuota = false;
}
*aPermission = PermissionRequestBase::kPermissionAllowed;
@ -21109,30 +21256,28 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
nsCString suffix;
nsCString group;
nsCString origin;
bool isApp;
rv = QuotaManager::GetInfoFromPrincipal(principal,
&suffix,
&group,
&origin,
&isApp);
&origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
#ifdef IDB_MOBILE
if (persistenceType == PERSISTENCE_TYPE_PERSISTENT &&
!QuotaManager::IsOriginWhitelistedForPersistentStorage(origin) &&
!isApp) {
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
#endif
PermissionRequestBase::PermissionValue permission;
if (QuotaManager::IsFirstPromptRequired(persistenceType, origin, isApp)) {
rv = PermissionRequestBase::GetCurrentPermission(principal, &permission);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
if (persistenceType == PERSISTENCE_TYPE_PERSISTENT) {
if (QuotaManager::IsOriginWhitelistedForPersistentStorage(origin)) {
permission = PermissionRequestBase::kPermissionAllowed;
} else {
#ifdef IDB_MOBILE
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
#else
rv = PermissionRequestBase::GetCurrentPermission(principal, &permission);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
#endif
}
} else {
permission = PermissionRequestBase::kPermissionAllowed;
@ -21143,10 +21288,8 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
mSuffix = suffix;
mGroup = group;
mOrigin = origin;
mIsApp = isApp;
mEnforcingQuota =
QuotaManager::IsQuotaEnforced(persistenceType, mOrigin, mIsApp);
mEnforcingQuota = persistenceType != PERSISTENCE_TYPE_PERSISTENT;
}
*aPermission = permission;
@ -21303,7 +21446,6 @@ FactoryOp::OpenDirectory()
quotaManager->OpenDirectory(persistenceType,
mGroup,
mOrigin,
mIsApp,
Client::IDB,
/* aExclusive */ false,
this);
@ -21558,7 +21700,6 @@ OpenDatabaseOp::DoDatabaseWork()
mSuffix,
mGroup,
mOrigin,
mIsApp,
getter_AddRefs(dbDirectory));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -21682,7 +21823,6 @@ OpenDatabaseOp::DoDatabaseWork()
fileManager = new FileManager(persistenceType,
mGroup,
mOrigin,
mIsApp,
databaseName,
mEnforcingQuota);
@ -21753,8 +21893,9 @@ OpenDatabaseOp::LoadDatabaseInformation(mozIStorageConnection* aConnection)
return rv;
}
if (mOrigin != origin) {
NS_WARNING("Origins don't match!");
// We can't just compare these strings directly. See bug 1339081 comment 69.
if (NS_WARN_IF(!QuotaManager::AreOriginsEqualOnDisk(mOrigin, origin))) {
return NS_ERROR_FILE_CORRUPTED;
}
int64_t version;

View File

@ -42,7 +42,6 @@ class FileManager final
// Protected by IndexedDatabaseManager::FileMutex()
nsDataHashtable<nsUint64HashKey, FileInfo*> mFileInfos;
const bool mIsApp;
const bool mEnforcingQuota;
bool mInvalidated;
@ -67,7 +66,6 @@ public:
FileManager(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aIsApp,
const nsAString& aDatabaseName,
bool aEnforcingQuota);
@ -89,12 +87,6 @@ public:
return mOrigin;
}
bool
IsApp() const
{
return mIsApp;
}
const nsAString&
DatabaseName() const
{

View File

@ -1092,7 +1092,7 @@ IDBDatabase::GetQuotaInfo(nsACString& aOrigin,
MOZ_CRASH("Is this needed?!");
case PrincipalInfo::TSystemPrincipalInfo:
QuotaManager::GetInfoForChrome(nullptr, nullptr, &aOrigin, nullptr);
QuotaManager::GetInfoForChrome(nullptr, nullptr, &aOrigin);
return NS_OK;
case PrincipalInfo::TContentPrincipalInfo: {
@ -1106,8 +1106,7 @@ IDBDatabase::GetQuotaInfo(nsACString& aOrigin,
rv = QuotaManager::GetInfoFromPrincipal(principal,
nullptr,
nullptr,
&aOrigin,
nullptr);
&aOrigin);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View File

@ -1366,7 +1366,6 @@ DeleteFilesRunnable::Open()
quotaManager->OpenDirectory(mFileManager->Type(),
mFileManager->Group(),
mFileManager->Origin(),
mFileManager->IsApp(),
Client::IDB,
/* aExclusive */ false,
this);

View File

@ -13,8 +13,6 @@ support-files =
file.js
helpers.js
leaving_page_iframe.html
service_worker.js
service_worker_client.html
third_party_iframe1.html
third_party_iframe2.html
unit/test_abort_deleted_index.js
@ -242,13 +240,13 @@ skip-if = e10s
[test_rename_objectStore_errors.html]
[test_request_readyState.html]
[test_sandbox.html]
[test_serviceworker.html]
[test_setVersion.html]
[test_setVersion_abort.html]
[test_setVersion_events.html]
[test_setVersion_exclusion.html]
[test_setVersion_throw.html]
[test_storage_manager_estimate.html]
scheme=https
[test_success_events_after_abort.html]
[test_table_locks.html]
[test_table_rollback.html]

View File

@ -46,10 +46,6 @@ function* testSteps()
// This one lives in storage/permanent/chrome
{ dbName: "dbL", dbVersion: 1 },
// This one lives in storage/default/1007+t+https+++developer.cdn.mozilla.net
{ appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
dbName: "dbN", dbVersion: 1 },
// This one lives in storage/default/http+++127.0.0.1
{ url: "http://127.0.0.1", dbName: "dbO", dbVersion: 1 },
@ -87,29 +83,15 @@ function* testSteps()
{ url: "http://localhost:82", dbName: "dbW",
dbOptions: { version: 1, storage: "temporary" } },
// This one lives in storage/temporary/1007+t+https+++developer.cdn.mozilla.net
{ appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
dbName: "dbY", dbOptions: { version: 1, storage: "temporary" } },
// This one lives in storage/temporary/http+++localhost
{ url: "http://localhost", dbName: "dbZ",
dbOptions: { version: 1, storage: "temporary" } }
];
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
.getService(SpecialPowers.Ci.nsIIOService);
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
function openDatabase(params) {
let request;
if ("url" in params) {
let uri = ios.newURI(params.url);
let principal =
ssm.createCodebasePrincipal(uri,
{appId: params.appId || ssm.NO_APPID,
inIsolatedMozBrowser: params.inIsolatedMozBrowser});
let principal = getPrincipal(params.url);
if ("dbVersion" in params) {
request = indexedDB.openForPrincipal(principal, params.dbName,
params.dbVersion);

View File

@ -9,30 +9,9 @@ function* testSteps()
{
const openParams = [
// This one lives in storage/default/http+++www.mozilla.org
{ url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 },
// This one lives in storage/default/1007+t+https+++developer.cdn.mozilla.net
{ appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
dbName: "dbN", dbVersion: 1 },
{ url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 }
];
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
.getService(SpecialPowers.Ci.nsIIOService);
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
function openDatabase(params) {
let uri = ios.newURI(params.url);
let principal =
ssm.createCodebasePrincipal(uri,
{appId: params.appId || ssm.NO_APPID,
inIsolatedMozBrowser: params.inIsolatedMozBrowser});
let request = indexedDB.openForPrincipal(principal, params.dbName,
params.dbVersion);
return request;
}
for (let i = 1; i <= 2; i++) {
clearAllDatabases(continueToNextStepSync);
yield undefined;
@ -40,7 +19,9 @@ function* testSteps()
installPackagedProfile("idbSubdirUpgrade" + i + "_profile");
for (let params of openParams) {
let request = openDatabase(params);
let request = indexedDB.openForPrincipal(getPrincipal(params.url),
params.dbName,
params.dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
@ -53,7 +34,9 @@ function* testSteps()
yield undefined;
for (let params of openParams) {
let request = openDatabase(params);
let request = indexedDB.openForPrincipal(getPrincipal(params.url),
params.dbName,
params.dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;

View File

@ -0,0 +1,43 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps()
{
const url = "moz-extension://8ea6d31b-917c-431f-a204-15b95e904d4f";
const dbName = "Hello.";
const dbVersion = 1;
clearAllDatabases(continueToNextStepSync);
yield;
// The origin directory contained in the package is:
// "moz-extension+++8ea6d31b-917c-431f-a204-15b95e904d4f^addonId=indexedDB-test%40kmaglione.mozilla.com"
installPackagedProfile("obsoleteOriginAttributes_profile");
let request =
indexedDB.openForPrincipal(getPrincipal(url), dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
is(event.type, "success", "Correct event type");
resetAllDatabases(continueToNextStepSync);
yield;
request = indexedDB.openForPrincipal(getPrincipal(url), dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.type, "success", "Correct event type");
finishTest();
}

View File

@ -9,37 +9,18 @@ function* testSteps()
{
const openParams = [
// This one lives in storage/default/http+++www.mozilla.org
{ url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 },
// This one lives in storage/default/1007+t+https+++developer.cdn.mozilla.net
{ appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
dbName: "dbN", dbVersion: 1 },
{ url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 }
];
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
.getService(SpecialPowers.Ci.nsIIOService);
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
function openDatabase(params) {
let uri = ios.newURI(params.url);
let principal =
ssm.createCodebasePrincipal(uri,
{appId: params.appId || ssm.NO_APPID,
inIsolatedMozBrowser: params.inIsolatedMozBrowser});
let request = indexedDB.openForPrincipal(principal, params.dbName,
params.dbVersion);
return request;
}
clearAllDatabases(continueToNextStepSync);
yield undefined;
installPackagedProfile("schema23upgrade_profile");
for (let params of openParams) {
let request = openDatabase(params);
let request = indexedDB.openForPrincipal(getPrincipal(params.url),
params.dbName,
params.dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
@ -52,7 +33,9 @@ function* testSteps()
yield undefined;
for (let params of openParams) {
let request = openDatabase(params);
let request = indexedDB.openForPrincipal(getPrincipal(params.url),
params.dbName,
params.dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;

View File

@ -9,37 +9,18 @@ function* testSteps()
{
const openParams = [
// This one lives in storage/default/http+++www.mozilla.org
{ url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 },
// This one lives in storage/default/1007+t+https+++developer.cdn.mozilla.net
{ appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
dbName: "dbN", dbVersion: 1 },
{ url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 }
];
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
.getService(SpecialPowers.Ci.nsIIOService);
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
function openDatabase(params) {
let uri = ios.newURI(params.url);
let principal =
ssm.createCodebasePrincipal(uri,
{appId: params.appId || ssm.NO_APPID,
inIsolatedMozBrowser: params.inIsolatedMozBrowser});
let request = indexedDB.openForPrincipal(principal, params.dbName,
params.dbVersion);
return request;
}
clearAllDatabases(continueToNextStepSync);
yield undefined;
installPackagedProfile("storagePersistentUpgrade_profile");
for (let params of openParams) {
let request = openDatabase(params);
let request = indexedDB.openForPrincipal(getPrincipal(params.url),
params.dbName,
params.dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
@ -52,7 +33,9 @@ function* testSteps()
yield undefined;
for (let params of openParams) {
let request = openDatabase(params);
let request = indexedDB.openForPrincipal(getPrincipal(params.url),
params.dbName,
params.dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;

View File

@ -46,13 +46,11 @@ function* testSteps()
info("Reading out contents of compiled blob");
File.createFromNsIFile(file).then(grabEventAndContinueHandler);
let domFile = yield undefined;
let fileReader = new FileReader();
fileReader.onload = continueToNextStepSync;
let domFile;
File.createFromNsIFile(file).then(file => { domFile = file; }).then(continueToNextStepSync);
yield undefined;
fileReader.readAsArrayBuffer(domFile);
yield undefined;
@ -85,12 +83,11 @@ function* testSteps()
info("Reading out contents of new compiled blob");
File.createFromNsIFile(file).then(grabEventAndContinueHandler);
domFile = yield undefined;
fileReader = new FileReader();
fileReader.onload = continueToNextStepSync;
File.createFromNsIFile(file).then(file => { domFile = file; }).then(continueToNextStepSync);
yield undefined;
fileReader.readAsArrayBuffer(domFile);
yield undefined;
@ -113,14 +110,13 @@ function* testSteps()
verifyWasmModule(request.result, wasmData.wasm);
yield undefined;
info("Reading contents of new compiled blob again");
info("Reading out contents of new compiled blob again");
File.createFromNsIFile(file).then(grabEventAndContinueHandler);
domFile = yield undefined;
fileReader = new FileReader();
fileReader.onload = continueToNextStepSync;
File.createFromNsIFile(file).then(file => { domFile = file; }).then(continueToNextStepSync);
yield undefined;
fileReader.readAsArrayBuffer(domFile);
yield undefined;

View File

@ -13,6 +13,7 @@ support-files =
idbSubdirUpgrade1_profile.zip
idbSubdirUpgrade2_profile.zip
mutableFileUpgrade_profile.zip
obsoleteOriginAttributes_profile.zip
oldDirectories_profile.zip
GlobalObjectsChild.js
GlobalObjectsComponent.js
@ -33,6 +34,7 @@ support-files =
[test_bad_origin_directory.js]
skip-if = release_or_beta
[test_obsoleteOriginAttributesUpgrade.js]
[test_blob_file_backed.js]
[test_bug1056939.js]
[test_cleanup_transaction.js]

View File

@ -5095,6 +5095,13 @@ ContentParent::RecvUpdateChildKeyedScalars(
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvRecordChildEvents(nsTArray<mozilla::Telemetry::ChildEventData>&& aEvents)
{
TelemetryIPC::RecordChildEvents(GeckoProcessType_Content, aEvents);
return IPC_OK();
}
PURLClassifierParent*
ContentParent::AllocPURLClassifierParent(const Principal& aPrincipal,
const bool& aUseTrackingProtection,

View File

@ -1125,6 +1125,8 @@ private:
InfallibleTArray<ScalarAction>&& aScalarActions) override;
virtual mozilla::ipc::IPCResult RecvUpdateChildKeyedScalars(
InfallibleTArray<KeyedScalarAction>&& aScalarActions) override;
virtual mozilla::ipc::IPCResult RecvRecordChildEvents(
nsTArray<ChildEventData>&& events) override;
public:
void SendGetFilesResponseAndForget(const nsID& aID,
const GetFilesResponseResult& aResult);

View File

@ -90,6 +90,7 @@ using mozilla::Telemetry::Accumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::ChildEventData from "mozilla/TelemetryComms.h";
union ChromeRegistryItem
{
@ -1202,6 +1203,7 @@ parent:
async AccumulateChildKeyedHistograms(KeyedAccumulation[] accumulations);
async UpdateChildScalars(ScalarAction[] updates);
async UpdateChildKeyedScalars(KeyedScalarAction[] updates);
async RecordChildEvents(ChildEventData[] events);
sync GetA11yContentId() returns (uint32_t aContentId);

View File

@ -78,7 +78,7 @@ WidevineVideoDecoder::InitDecode(const GMPVideoCodec& aCodecSettings,
return;
}
config.format = kYv12;
config.coded_size = Size(aCodecSettings.mWidth, aCodecSettings.mHeight);
config.coded_size = mCodedSize = Size(aCodecSettings.mWidth, aCodecSettings.mHeight);
nsTArray<uint8_t> extraData;
if (aCodecSpecificLength > 0) {
// The first byte is the WebRTC packetization mode, which can be ignored.
@ -128,7 +128,18 @@ WidevineVideoDecoder::Decode(GMPVideoEncodedFrame* aInputFrame,
aInputFrame->Destroy();
aInputFrame = nullptr;
if (rv == kSuccess) {
if (rv == kSuccess || rv == kNoKey) {
if (rv == kNoKey) {
CDM_LOG("NoKey for sample at time=%" PRId64 "!", sample.timestamp);
// Somehow our key became unusable. Typically this would happen when
// a stream requires output protection, and the configuration changed
// such that output protection is no longer available. For example, a
// non-compliant monitor was attached. The JS player should notice the
// key status changing to "output-restricted", and is supposed to switch
// to a stream that doesn't require OP. In order to keep the playback
// pipeline rolling, just output a black frame. See bug 1343140.
frame.InitToBlack(mCodedSize.width, mCodedSize.height, sample.timestamp);
}
if (!ReturnOutput(frame)) {
CDM_LOG("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
mCallback->Error(GMPDecodeErr);

View File

@ -73,6 +73,7 @@ private:
// If a reset is being performed. Used to track if ReturnOutput should
// dump current frame.
bool mResetInProgress;
cdm::Size mCodedSize;
};
} // namespace mozilla

View File

@ -124,4 +124,31 @@ WidevineVideoFrame::Timestamp() const
return mTimestamp;
}
void
WidevineVideoFrame::InitToBlack(uint32_t aWidth, uint32_t aHeight, int64_t aTimeStamp)
{
SetFormat(VideoFormat::kI420);
SetSize(cdm::Size(aWidth, aHeight));
size_t ySize = aWidth * aHeight;
size_t uSize = ((aWidth + 1) / 2) * ((aHeight + 1) / 2);
WidevineBuffer* buffer = new WidevineBuffer(ySize + uSize);
// Black in YCbCr is (0,128,128).
memset(buffer->Data(), 0, ySize);
memset(buffer->Data() + ySize, 128, uSize);
if (mBuffer) {
mBuffer->Destroy();
mBuffer = nullptr;
}
SetFrameBuffer(buffer);
SetPlaneOffset(VideoFrame::kYPlane, 0);
SetStride(VideoFrame::kYPlane, aWidth);
// Note: U and V planes are stored at the same place in order to
// save memory since their contents are the same.
SetPlaneOffset(VideoFrame::kUPlane, ySize);
SetStride(VideoFrame::kUPlane, (aWidth + 1) / 2);
SetPlaneOffset(VideoFrame::kVPlane, ySize);
SetStride(VideoFrame::kVPlane, (aWidth + 1) / 2);
SetTimestamp(aTimeStamp);
}
} // namespace mozilla

View File

@ -36,6 +36,8 @@ public:
void SetTimestamp(int64_t aTimestamp) override;
int64_t Timestamp() const override;
void InitToBlack(uint32_t aWidth, uint32_t aHeight, int64_t aTimeStamp);
protected:
cdm::VideoFormat mFormat;
cdm::Size mSize;

View File

@ -515,23 +515,6 @@ Performance::QueueEntry(PerformanceEntry* aEntry)
}
}
/* static */ bool
Performance::IsEnabled(JSContext* aCx, JSObject* aGlobal)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("dom.enable_user_timing", false);
}
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
RefPtr<PrefEnabledRunnable> runnable =
new PrefEnabledRunnable(workerPrivate,
NS_LITERAL_CSTRING("dom.enable_user_timing"));
return runnable->Dispatch() && runnable->IsEnabled();
}
/* static */ bool
Performance::IsObserverEnabled(JSContext* aCx, JSObject* aGlobal)
{

View File

@ -39,8 +39,6 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Performance,
DOMEventTargetHelper)
static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
static bool IsObserverEnabled(JSContext* aCx, JSObject* aGlobal);
static already_AddRefed<Performance>

View File

@ -24,8 +24,10 @@
#include "nsIObserver.h"
#ifdef XP_WIN
#include "nsWindowsHelpers.h"
#if defined(MOZ_SANDBOX)
#include "sandboxPermissions.h"
#endif
#endif
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"

View File

@ -78,6 +78,7 @@ add_task(function* test_state() {
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
dirSvc = null;
// We installed a non-restartless addon, need to restart the manager.
restartManager();

View File

@ -478,6 +478,7 @@ function filterDevice() {
}
provider.listener = null;
provider = null;
run_next_test();
},
updateDevice: function() {},
@ -835,6 +836,7 @@ function ignoreIncompatibleDevice() {
Assert.equal(listener.count(), 0);
provider.listener = null;
provider = null;
run_next_test();
});
@ -918,6 +920,7 @@ function ignoreSelfDevice() {
Assert.equal(listener.count(), 0);
provider.listener = null;
provider = null;
run_next_test();
});

View File

@ -6,6 +6,7 @@
#include "ActorsChild.h"
#include "nsVariant.h"
#include "QuotaManagerService.h"
#include "QuotaRequests.h"
@ -231,7 +232,22 @@ QuotaRequestChild::HandleResponse()
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
mRequest->SetResult();
RefPtr<nsVariant> variant = new nsVariant();
variant->SetAsVoid();
mRequest->SetResult(variant);
}
void
QuotaRequestChild::HandleResponse(bool aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
RefPtr<nsVariant> variant = new nsVariant();
variant->SetAsBool(aResponse);
mRequest->SetResult(variant);
}
void
@ -251,13 +267,18 @@ QuotaRequestChild::Recv__delete__(const RequestResponse& aResponse)
HandleResponse(aResponse.get_nsresult());
break;
case RequestResponse::TInitResponse:
case RequestResponse::TClearOriginResponse:
case RequestResponse::TClearOriginsResponse:
case RequestResponse::TClearDataResponse:
case RequestResponse::TClearAllResponse:
case RequestResponse::TResetAllResponse:
HandleResponse();
break;
case RequestResponse::TInitOriginResponse:
HandleResponse(aResponse.get_InitOriginResponse().created());
break;
default:
MOZ_CRASH("Unknown response type!");
}

View File

@ -138,6 +138,9 @@ private:
void
HandleResponse();
void
HandleResponse(bool aResponse);
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@
#include "PersistenceType.h"
class nsIFile;
class nsIRunnable;
#define IDB_DIRECTORY_NAME "idb"
@ -89,6 +90,12 @@ public:
}
// Methods which are called on the IO thred.
virtual nsresult
UpgradeStorageFrom1_0To2_0(nsIFile* aDirectory)
{
return NS_OK;
}
virtual nsresult
InitOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup,

View File

@ -17,6 +17,16 @@ namespace mozilla {
namespace dom {
namespace quota {
struct InitParams
{
};
struct InitOriginParams
{
PrincipalInfo principalInfo;
PersistenceType persistenceType;
};
struct UsageParams
{
PrincipalInfo principalInfo;
@ -36,7 +46,7 @@ struct ClearOriginParams
bool clearAll;
};
struct ClearOriginsParams
struct ClearDataParams
{
nsString pattern;
};
@ -51,8 +61,10 @@ struct ResetAllParams
union RequestParams
{
InitParams;
InitOriginParams;
ClearOriginParams;
ClearOriginsParams;
ClearDataParams;
ClearAllParams;
ResetAllParams;
};

View File

@ -8,11 +8,20 @@ namespace mozilla {
namespace dom {
namespace quota {
struct InitResponse
{
};
struct InitOriginResponse
{
bool created;
};
struct ClearOriginResponse
{
};
struct ClearOriginsResponse
struct ClearDataResponse
{
};
@ -27,8 +36,10 @@ struct ResetAllResponse
union RequestResponse
{
nsresult;
InitResponse;
InitOriginResponse;
ClearOriginResponse;
ClearOriginsResponse;
ClearDataResponse;
ClearAllResponse;
ResetAllResponse;
};

View File

@ -78,16 +78,13 @@ protected:
struct OriginParams
{
OriginParams(PersistenceType aPersistenceType,
const nsACString& aOrigin,
bool aIsApp)
const nsACString& aOrigin)
: mOrigin(aOrigin)
, mPersistenceType(aPersistenceType)
, mIsApp(aIsApp)
{ }
nsCString mOrigin;
PersistenceType mPersistenceType;
bool mIsApp;
};
class QuotaManager final
@ -149,7 +146,6 @@ public:
InitQuotaForOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aIsApp,
uint64_t aUsageBytes,
int64_t aAccessTime);
@ -206,8 +202,7 @@ public:
int64_t* aTimestamp,
nsACString& aSuffix,
nsACString& aGroup,
nsACString& aOrigin,
bool* aIsApp);
nsACString& aOrigin);
nsresult
GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
@ -215,8 +210,7 @@ public:
int64_t* aTimestamp,
nsACString& aSuffix,
nsACString& aGroup,
nsACString& aOrigin,
bool* aIsApp);
nsACString& aOrigin);
nsresult
GetDirectoryMetadata2(nsIFile* aDirectory, int64_t* aTimestamp);
@ -245,7 +239,6 @@ public:
OpenDirectory(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aIsApp,
Client::Type aClientType,
bool aExclusive,
OpenDirectoryListener* aOpenListener);
@ -263,6 +256,14 @@ public:
CollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
void
AssertStorageIsInitialized() const
#ifdef DEBUG
;
#else
{ }
#endif
nsresult
EnsureStorageIsInitialized();
@ -271,13 +272,19 @@ public:
const nsACString& aSuffix,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aIsApp,
nsIFile** aDirectory);
nsresult
EnsureOriginIsInitializedInternal(PersistenceType aPersistenceType,
const nsACString& aSuffix,
const nsACString& aGroup,
const nsACString& aOrigin,
nsIFile** aDirectory,
bool* aCreated);
void
OriginClearCompleted(PersistenceType aPersistenceType,
const nsACString& aOrigin,
bool aIsApp);
const nsACString& aOrigin);
void
ResetOrClearCompleted();
@ -363,38 +370,29 @@ public:
GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
nsACString* aSuffix,
nsACString* aGroup,
nsACString* aOrigin,
bool* aIsApp);
nsACString* aOrigin);
static nsresult
GetInfoFromWindow(nsPIDOMWindowOuter* aWindow,
nsACString* aSuffix,
nsACString* aGroup,
nsACString* aOrigin,
bool* aIsApp);
nsACString* aOrigin);
static void
GetInfoForChrome(nsACString* aSuffix,
nsACString* aGroup,
nsACString* aOrigin,
bool* aIsApp);
nsACString* aOrigin);
static bool
IsOriginWhitelistedForPersistentStorage(const nsACString& aOrigin);
static bool
IsFirstPromptRequired(PersistenceType aPersistenceType,
const nsACString& aOrigin,
bool aIsApp);
static bool
IsQuotaEnforced(PersistenceType aPersistenceType,
const nsACString& aOrigin,
bool aIsApp);
static void
ChromeOrigin(nsACString& aOrigin);
static bool
AreOriginsEqualOnDisk(nsACString& aOrigin1,
nsACString& aOrigin2);
private:
QuotaManager();
@ -410,7 +408,6 @@ private:
CreateDirectoryLock(const Nullable<PersistenceType>& aPersistenceType,
const nsACString& aGroup,
const OriginScope& aOriginScope,
const Nullable<bool>& aIsApp,
const Nullable<Client::Type>& aClientType,
bool aExclusive,
bool aInternal,
@ -419,8 +416,7 @@ private:
already_AddRefed<DirectoryLockImpl>
CreateDirectoryLockForEviction(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aIsApp);
const nsACString& aOrigin);
void
RegisterDirectoryLock(DirectoryLockImpl* aLock);
@ -453,10 +449,8 @@ private:
nsresult
UpgradeStorageFrom0_0To1_0(mozIStorageConnection* aConnection);
#if 0
nsresult
UpgradeStorageFrom1_0To2_0(mozIStorageConnection* aConnection);
#endif
nsresult
InitializeRepository(PersistenceType aPersistenceType);
@ -465,7 +459,6 @@ private:
InitializeOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aIsApp,
int64_t aAccessTime,
nsIFile* aDirectory);

View File

@ -498,6 +498,79 @@ NS_IMPL_QUERY_INTERFACE(QuotaManagerService,
nsIQuotaManagerService,
nsIObserver)
NS_IMETHODIMP
QuotaManagerService::Init(nsIQuotaRequest** _retval)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
if (NS_WARN_IF(!gTestingMode)) {
return NS_ERROR_UNEXPECTED;
}
RefPtr<Request> request = new Request();
InitParams params;
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
nsresult rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::InitStoragesForPrincipal(
nsIPrincipal* aPrincipal,
const nsACString& aPersistenceType,
nsIQuotaRequest** _retval)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
if (NS_WARN_IF(!gTestingMode)) {
return NS_ERROR_UNEXPECTED;
}
RefPtr<Request> request = new Request();
InitOriginParams params;
PrincipalInfo& principalInfo = params.principalInfo();
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
return NS_ERROR_UNEXPECTED;
}
Nullable<PersistenceType> persistenceType;
rv = NullablePersistenceTypeFromText(aPersistenceType, &persistenceType);
if (NS_WARN_IF(NS_FAILED(rv)) || persistenceType.IsNull()) {
return NS_ERROR_INVALID_ARG;
}
params.persistenceType() = persistenceType.Value();
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
nsIQuotaUsageCallback* aCallback,
@ -660,10 +733,10 @@ QuotaManagerService::Observe(nsISupports* aSubject,
if (!strcmp(aTopic, "clear-origin-attributes-data")) {
RefPtr<Request> request = new Request();
ClearOriginsParams requestParams;
requestParams.pattern() = nsDependentString(aData);
ClearDataParams params;
params.pattern() = nsDependentString(aData);
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, requestParams));
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
nsresult rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {

Some files were not shown because too many files have changed in this diff Show More