Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 module.metadata = {
8 "stability": "unstable"
9 };
11 // The minimum and maximum integers that can be set as preferences.
12 // The range of valid values is narrower than the range of valid JS values
13 // because the native preferences code treats integers as NSPR PRInt32s,
14 // which are 32-bit signed integers on all platforms.
15 const MAX_INT = 0x7FFFFFFF;
16 const MIN_INT = -0x80000000;
18 const {Cc,Ci,Cr} = require("chrome");
20 const prefService = Cc["@mozilla.org/preferences-service;1"].
21 getService(Ci.nsIPrefService);
22 const prefSvc = prefService.getBranch(null);
23 const defaultBranch = prefService.getDefaultBranch(null);
25 function Branch(branchName) {
26 function getPrefKeys() {
27 return keys(branchName).map(function(key) {
28 return key.replace(branchName, "");
29 });
30 }
32 return Proxy.create({
33 get: function(receiver, pref) {
34 return get(branchName + pref);
35 },
36 set: function(receiver, pref, val) {
37 set(branchName + pref, val);
38 },
39 delete: function(pref) {
40 reset(branchName + pref);
41 return true;
42 },
43 has: function hasPrefKey(pref) {
44 return has(branchName + pref)
45 },
46 getPropertyDescriptor: function(name) {
47 return {
48 value: get(branchName + name)
49 };
50 },
51 enumerate: getPrefKeys,
52 keys: getPrefKeys
53 }, Branch.prototype);
54 }
56 function get(name, defaultValue) {
57 switch (prefSvc.getPrefType(name)) {
58 case Ci.nsIPrefBranch.PREF_STRING:
59 return prefSvc.getComplexValue(name, Ci.nsISupportsString).data;
61 case Ci.nsIPrefBranch.PREF_INT:
62 return prefSvc.getIntPref(name);
64 case Ci.nsIPrefBranch.PREF_BOOL:
65 return prefSvc.getBoolPref(name);
67 case Ci.nsIPrefBranch.PREF_INVALID:
68 return defaultValue;
70 default:
71 // This should never happen.
72 throw new Error("Error getting pref " + name +
73 "; its value's type is " +
74 prefSvc.getPrefType(name) +
75 ", which I don't know " +
76 "how to handle.");
77 }
78 }
79 exports.get = get;
81 function set(name, value) {
82 var prefType;
83 if (typeof value != "undefined" && value != null)
84 prefType = value.constructor.name;
86 switch (prefType) {
87 case "String":
88 {
89 var string = Cc["@mozilla.org/supports-string;1"].
90 createInstance(Ci.nsISupportsString);
91 string.data = value;
92 prefSvc.setComplexValue(name, Ci.nsISupportsString, string);
93 }
94 break;
96 case "Number":
97 // We throw if the number is outside the range or not an integer, since
98 // the result will not be what the consumer wanted to store.
99 if (value > MAX_INT || value < MIN_INT)
100 throw new Error("you cannot set the " + name +
101 " pref to the number " + value +
102 ", as number pref values must be in the signed " +
103 "32-bit integer range -(2^31) to 2^31-1. " +
104 "To store numbers outside that range, store " +
105 "them as strings.");
106 if (value % 1 != 0)
107 throw new Error("cannot store non-integer number: " + value);
108 prefSvc.setIntPref(name, value);
109 break;
111 case "Boolean":
112 prefSvc.setBoolPref(name, value);
113 break;
115 default:
116 throw new Error("can't set pref " + name + " to value '" + value +
117 "'; it isn't a string, integer, or boolean");
118 }
119 }
120 exports.set = set;
122 function has(name) {
123 return (prefSvc.getPrefType(name) != Ci.nsIPrefBranch.PREF_INVALID);
124 }
125 exports.has = has;
127 function keys(root) {
128 return prefSvc.getChildList(root);
129 }
130 exports.keys = keys;
132 function isSet(name) {
133 return (has(name) && prefSvc.prefHasUserValue(name));
134 }
135 exports.isSet = isSet;
137 function reset(name) {
138 try {
139 prefSvc.clearUserPref(name);
140 }
141 catch (e) {
142 // The pref service throws NS_ERROR_UNEXPECTED when the caller tries
143 // to reset a pref that doesn't exist or is already set to its default
144 // value. This interface fails silently in those cases, so callers
145 // can unconditionally reset a pref without having to check if it needs
146 // resetting first or trap exceptions after the fact. It passes through
147 // other exceptions, however, so callers know about them, since we don't
148 // know what other exceptions might be thrown and what they might mean.
149 if (e.result != Cr.NS_ERROR_UNEXPECTED) {
150 throw e;
151 }
152 }
153 }
154 exports.reset = reset;
156 function getLocalized(name, defaultValue) {
157 let value = null;
158 try {
159 value = prefSvc.getComplexValue(name, Ci.nsIPrefLocalizedString).data;
160 }
161 finally {
162 return value || defaultValue;
163 }
164 }
165 exports.getLocalized = getLocalized;
167 function setLocalized(name, value) {
168 // We can't use `prefs.set` here as we have to use `getDefaultBranch`
169 // (instead of `getBranch`) in order to have `mIsDefault` set to true, here:
170 // http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/nsPrefBranch.cpp#233
171 // Otherwise, we do not enter into this expected condition:
172 // http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/nsPrefBranch.cpp#244
173 defaultBranch.setCharPref(name, value);
174 }
175 exports.setLocalized = setLocalized;
177 exports.Branch = Branch;