mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 835352 - Forward content preference change notifications to child processes. r=mak
This commit is contained in:
parent
2d6f3e7bea
commit
2852357eff
@ -195,7 +195,7 @@ ContentPrefService2.prototype = {
|
||||
if (context && context.usePrivateBrowsing) {
|
||||
this._pbStore.set(group, name, value);
|
||||
this._schedule(function () {
|
||||
this._cps._notifyPrefSet(group, name, value);
|
||||
this._cps._broadcastPrefSet(group, name, value);
|
||||
cbHandleCompletion(callback, Ci.nsIContentPrefCallback2.COMPLETE_OK);
|
||||
});
|
||||
return;
|
||||
@ -260,7 +260,7 @@ ContentPrefService2.prototype = {
|
||||
onDone: function onDone(reason, ok) {
|
||||
if (ok) {
|
||||
this._cache.setWithCast(group, name, value);
|
||||
this._cps._notifyPrefSet(group, name, value);
|
||||
this._cps._broadcastPrefSet(group, name, value);
|
||||
}
|
||||
cbHandleCompletion(callback, reason);
|
||||
},
|
||||
@ -343,7 +343,7 @@ ContentPrefService2.prototype = {
|
||||
}
|
||||
}
|
||||
for (let [sgroup, , ] in prefs) {
|
||||
this._cps._notifyPrefRemoved(sgroup, name);
|
||||
this._cps._broadcastPrefRemoved(sgroup, name);
|
||||
}
|
||||
}
|
||||
cbHandleCompletion(callback, reason);
|
||||
@ -429,7 +429,7 @@ ContentPrefService2.prototype = {
|
||||
}
|
||||
}
|
||||
for (let [sgroup, sname, ] in prefs) {
|
||||
this._cps._notifyPrefRemoved(sgroup, sname);
|
||||
this._cps._broadcastPrefRemoved(sgroup, sname);
|
||||
}
|
||||
}
|
||||
cbHandleCompletion(callback, reason);
|
||||
@ -481,7 +481,7 @@ ContentPrefService2.prototype = {
|
||||
this._pbStore.removeGrouped();
|
||||
}
|
||||
for (let [sgroup, sname, ] in prefs) {
|
||||
this._cps._notifyPrefRemoved(sgroup, sname);
|
||||
this._cps._broadcastPrefRemoved(sgroup, sname);
|
||||
}
|
||||
}
|
||||
cbHandleCompletion(callback, reason);
|
||||
@ -554,7 +554,7 @@ ContentPrefService2.prototype = {
|
||||
}
|
||||
}
|
||||
for (let [sgroup, , ] in prefs) {
|
||||
this._cps._notifyPrefRemoved(sgroup, name);
|
||||
this._cps._broadcastPrefRemoved(sgroup, name);
|
||||
}
|
||||
}
|
||||
cbHandleCompletion(callback, reason);
|
||||
|
@ -9,6 +9,25 @@ const Cu = Components.utils;
|
||||
|
||||
const CACHE_MAX_GROUP_ENTRIES = 100;
|
||||
|
||||
|
||||
// We have a whitelist for getting/setting. This is because
|
||||
// there are potential privacy issues with a compromised
|
||||
// content process checking the user's content preferences
|
||||
// and using that to discover all the websites visited, etc.
|
||||
// Also there are both potential race conditions (if two processes
|
||||
// set more than one value in succession, and the values
|
||||
// only make sense together), as well as security issues, if
|
||||
// a compromised content process can send arbitrary setPref
|
||||
// messages. The whitelist contains only those settings that
|
||||
// are not at risk for either.
|
||||
// We currently whitelist saving/reading the last directory of file
|
||||
// uploads, and the last current spellchecker dictionary which are so far
|
||||
// the only need we have identified.
|
||||
const REMOTE_WHITELIST = [
|
||||
"browser.upload.lastDir",
|
||||
"spellcheck.lang",
|
||||
];
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
/**
|
||||
@ -26,25 +45,15 @@ function electrolify(service) {
|
||||
Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
|
||||
// Parent process
|
||||
|
||||
service.messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"].
|
||||
getService(Ci.nsIMessageBroadcaster);
|
||||
|
||||
// Setup listener for child messages. We don't need to call
|
||||
// addMessageListener as the wakeup service will do that for us.
|
||||
service.receiveMessage = function(aMessage) {
|
||||
var json = aMessage.json;
|
||||
// We have a whitelist for getting/setting. This is because
|
||||
// there are potential privacy issues with a compromised
|
||||
// content process checking the user's content preferences
|
||||
// and using that to discover all the websites visited, etc.
|
||||
// Also there are both potential race conditions (if two processes
|
||||
// set more than one value in succession, and the values
|
||||
// only make sense together), as well as security issues, if
|
||||
// a compromised content process can send arbitrary setPref
|
||||
// messages. The whitelist contains only those settings that
|
||||
// are not at risk for either.
|
||||
// We currently whitelist saving/reading the last directory of file
|
||||
// uploads, and the last current spellchecker dictionary which are so far
|
||||
// the only need we have identified.
|
||||
const NAME_WHITELIST = ["browser.upload.lastDir", "spellcheck.lang"];
|
||||
if (NAME_WHITELIST.indexOf(json.name) == -1)
|
||||
|
||||
if (REMOTE_WHITELIST.indexOf(json.name) == -1)
|
||||
return { succeeded: false };
|
||||
|
||||
switch (aMessage.name) {
|
||||
@ -88,6 +97,19 @@ function electrolify(service) {
|
||||
return ret.value;
|
||||
};
|
||||
});
|
||||
|
||||
// Listen to preference change notifications from the parent and notify
|
||||
// observers in the child process according to the change
|
||||
service.messageManager.addMessageListener("ContentPref:notifyPrefSet",
|
||||
function(aMessage) {
|
||||
var json = aMessage.json;
|
||||
service._notifyPrefSet(json.group, json.name, json.value);
|
||||
});
|
||||
service.messageManager.addMessageListener("ContentPref:notifyPrefRemoved",
|
||||
function(aMessage) {
|
||||
var json = aMessage.json;
|
||||
service._notifyPrefRemoved(json.group, json.name);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,7 +350,7 @@ ContentPrefService.prototype = {
|
||||
|
||||
if (aContext && aContext.usePrivateBrowsing) {
|
||||
this._privModeStorage.setWithCast(group, aName, aValue);
|
||||
this._notifyPrefSet(group, aName, aValue);
|
||||
this._broadcastPrefSet(group, aName, aValue);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -350,8 +372,7 @@ ContentPrefService.prototype = {
|
||||
this._insertPref(groupID, settingID, aValue);
|
||||
|
||||
this._cache.setWithCast(group, aName, aValue);
|
||||
|
||||
this._notifyPrefSet(group, aName, aValue);
|
||||
this._broadcastPrefSet(group, aName, aValue);
|
||||
},
|
||||
|
||||
hasPref: function ContentPrefService_hasPref(aGroup, aName, aContext) {
|
||||
@ -379,7 +400,7 @@ ContentPrefService.prototype = {
|
||||
|
||||
if (aContext && aContext.usePrivateBrowsing) {
|
||||
this._privModeStorage.remove(group, aName);
|
||||
this._notifyPrefRemoved(group, aName);
|
||||
this._broadcastPrefRemoved(group, aName);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -402,7 +423,7 @@ ContentPrefService.prototype = {
|
||||
this._deleteGroupIfUnused(groupID);
|
||||
|
||||
this._cache.remove(group, aName);
|
||||
this._notifyPrefRemoved(group, aName);
|
||||
this._broadcastPrefRemoved(group, aName);
|
||||
},
|
||||
|
||||
removeGroupedPrefs: function ContentPrefService_removeGroupedPrefs(aContext) {
|
||||
@ -437,7 +458,7 @@ ContentPrefService.prototype = {
|
||||
for (let [group, name, ] in this._privModeStorage) {
|
||||
if (name === aName) {
|
||||
this._privModeStorage.remove(group, aName);
|
||||
this._notifyPrefRemoved(group, aName);
|
||||
this._broadcastPrefRemoved(group, aName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -479,7 +500,7 @@ ContentPrefService.prototype = {
|
||||
if (groupNames[i]) // ie. not null, which will be last (and i == groupIDs.length)
|
||||
this._deleteGroupIfUnused(groupIDs[i]);
|
||||
if (!aContext || !aContext.usePrivateBrowsing) {
|
||||
this._notifyPrefRemoved(groupNames[i], aName);
|
||||
this._broadcastPrefRemoved(groupNames[i], aName);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -570,6 +591,9 @@ ContentPrefService.prototype = {
|
||||
return observers;
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify all observers about the removal of a preference.
|
||||
*/
|
||||
_notifyPrefRemoved: function ContentPrefService__notifyPrefRemoved(aGroup, aName) {
|
||||
for each (var observer in this._getObservers(aName)) {
|
||||
try {
|
||||
@ -581,6 +605,9 @@ ContentPrefService.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify all observers about a preference change.
|
||||
*/
|
||||
_notifyPrefSet: function ContentPrefService__notifyPrefSet(aGroup, aName, aValue) {
|
||||
for each (var observer in this._getObservers(aName)) {
|
||||
try {
|
||||
@ -592,6 +619,38 @@ ContentPrefService.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify all observers in the current process about the removal of a
|
||||
* preference and send a message to all other processes so that they can in
|
||||
* turn notify their observers about the change. This is meant to be called
|
||||
* only in the parent process. Only whitelisted preferences are broadcast to
|
||||
* the child processes.
|
||||
*/
|
||||
_broadcastPrefRemoved: function ContentPrefService__broadcastPrefRemoved(aGroup, aName) {
|
||||
this._notifyPrefRemoved(aGroup, aName);
|
||||
|
||||
if (REMOTE_WHITELIST.indexOf(aName) != -1) {
|
||||
this.messageManager.broadcastAsyncMessage('ContentPref:notifyPrefRemoved',
|
||||
{ "group": aGroup, "name": aName } );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify all observers in the current process about a preference change and
|
||||
* send a message to all other processes so that they can in turn notify
|
||||
* their observers about the change. This is meant to be called only in the
|
||||
* parent process. Only whitelisted preferences are broadcast to the child
|
||||
* processes.
|
||||
*/
|
||||
_broadcastPrefSet: function ContentPrefService__broadcastPrefSet(aGroup, aName, aValue) {
|
||||
this._notifyPrefSet(aGroup, aName, aValue);
|
||||
|
||||
if (REMOTE_WHITELIST.indexOf(aName) != -1) {
|
||||
this.messageManager.broadcastAsyncMessage('ContentPref:notifyPrefSet',
|
||||
{ "group": aGroup, "name": aName, "value": aValue } );
|
||||
}
|
||||
},
|
||||
|
||||
_grouper: null,
|
||||
get grouper() {
|
||||
if (!this._grouper)
|
||||
|
Loading…
Reference in New Issue
Block a user