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 file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /**
6 * This module defines the thread-agnostic components of the Unix version
7 * of OS.File. It depends on the thread-agnostic cross-platform components
8 * of OS.File.
9 *
10 * It serves the following purposes:
11 * - open libc;
12 * - define OS.Unix.Error;
13 * - define a few constants and types that need to be defined on all platforms.
14 *
15 * This module can be:
16 * - opened from the main thread as a jsm module;
17 * - opened from a chrome worker through require().
18 */
20 "use strict";
22 let SharedAll;
23 if (typeof Components != "undefined") {
24 let Cu = Components.utils;
25 // Module is opened as a jsm module
26 Cu.import("resource://gre/modules/ctypes.jsm", this);
28 SharedAll = {};
29 Cu.import("resource://gre/modules/osfile/osfile_shared_allthreads.jsm", SharedAll);
30 this.exports = {};
31 } else if (typeof "module" != "undefined" && typeof "require" != "undefined") {
32 // Module is loaded with require()
33 SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
34 } else {
35 throw new Error("Please open this module with Component.utils.import or with require()");
36 }
38 let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "allthreads");
39 let Const = SharedAll.Constants.libc;
41 // Open libc
42 let libc = new SharedAll.Library("libc",
43 "libc.so", "libSystem.B.dylib", "a.out");
44 exports.libc = libc;
46 // Define declareFFI
47 let declareFFI = SharedAll.declareFFI.bind(null, libc);
48 exports.declareFFI = declareFFI;
50 // Define lazy binding
51 let LazyBindings = {};
52 libc.declareLazy(LazyBindings, "strerror",
53 "strerror", ctypes.default_abi,
54 /*return*/ ctypes.char.ptr,
55 /*errnum*/ ctypes.int);
57 /**
58 * A File-related error.
59 *
60 * To obtain a human-readable error message, use method |toString|.
61 * To determine the cause of the error, use the various |becauseX|
62 * getters. To determine the operation that failed, use field
63 * |operation|.
64 *
65 * Additionally, this implementation offers a field
66 * |unixErrno|, which holds the OS-specific error
67 * constant. If you need this level of detail, you may match the value
68 * of this field against the error constants of |OS.Constants.libc|.
69 *
70 * @param {string=} operation The operation that failed. If unspecified,
71 * the name of the calling function is taken to be the operation that
72 * failed.
73 * @param {number=} lastError The OS-specific constant detailing the
74 * reason of the error. If unspecified, this is fetched from the system
75 * status.
76 * @param {string=} path The file path that manipulated. If unspecified,
77 * assign the empty string.
78 *
79 * @constructor
80 * @extends {OS.Shared.Error}
81 */
82 let OSError = function OSError(operation = "unknown operation",
83 errno = ctypes.errno, path = "") {
84 operation = operation;
85 SharedAll.OSError.call(this, operation, path);
86 this.unixErrno = errno;
87 };
88 OSError.prototype = Object.create(SharedAll.OSError.prototype);
89 OSError.prototype.toString = function toString() {
90 return "Unix error " + this.unixErrno +
91 " during operation " + this.operation +
92 (this.path? " on file " + this.path : "") +
93 " (" + LazyBindings.strerror(this.unixErrno).readString() + ")";
94 };
96 /**
97 * |true| if the error was raised because a file or directory
98 * already exists, |false| otherwise.
99 */
100 Object.defineProperty(OSError.prototype, "becauseExists", {
101 get: function becauseExists() {
102 return this.unixErrno == Const.EEXIST;
103 }
104 });
105 /**
106 * |true| if the error was raised because a file or directory
107 * does not exist, |false| otherwise.
108 */
109 Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
110 get: function becauseNoSuchFile() {
111 return this.unixErrno == Const.ENOENT;
112 }
113 });
115 /**
116 * |true| if the error was raised because a directory is not empty
117 * does not exist, |false| otherwise.
118 */
119 Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
120 get: function becauseNotEmpty() {
121 return this.unixErrno == Const.ENOTEMPTY;
122 }
123 });
124 /**
125 * |true| if the error was raised because a file or directory
126 * is closed, |false| otherwise.
127 */
128 Object.defineProperty(OSError.prototype, "becauseClosed", {
129 get: function becauseClosed() {
130 return this.unixErrno == Const.EBADF;
131 }
132 });
133 /**
134 * |true| if the error was raised because permission is denied to
135 * access a file or directory, |false| otherwise.
136 */
137 Object.defineProperty(OSError.prototype, "becauseAccessDenied", {
138 get: function becauseAccessDenied() {
139 return this.unixErrno == Const.EACCES;
140 }
141 });
142 /**
143 * |true| if the error was raised because some invalid argument was passed,
144 * |false| otherwise.
145 */
146 Object.defineProperty(OSError.prototype, "becauseInvalidArgument", {
147 get: function becauseInvalidArgument() {
148 return this.unixErrno == Const.EINVAL;
149 }
150 });
152 /**
153 * Serialize an instance of OSError to something that can be
154 * transmitted across threads (not necessarily a string).
155 */
156 OSError.toMsg = function toMsg(error) {
157 return {
158 operation: error.operation,
159 unixErrno: error.unixErrno,
160 path: error.path
161 };
162 };
164 /**
165 * Deserialize a message back to an instance of OSError
166 */
167 OSError.fromMsg = function fromMsg(msg) {
168 return new OSError(msg.operation, msg.unixErrno, msg.path);
169 };
170 exports.Error = OSError;
172 /**
173 * Code shared by implementations of File.Info on Unix
174 *
175 * @constructor
176 */
177 let AbstractInfo = function AbstractInfo(path, isDir, isSymLink, size, lastAccessDate,
178 lastModificationDate, unixLastStatusChangeDate,
179 unixOwner, unixGroup, unixMode) {
180 this._path = path;
181 this._isDir = isDir;
182 this._isSymlLink = isSymLink;
183 this._size = size;
184 this._lastAccessDate = lastAccessDate;
185 this._lastModificationDate = lastModificationDate;
186 this._unixLastStatusChangeDate = unixLastStatusChangeDate;
187 this._unixOwner = unixOwner;
188 this._unixGroup = unixGroup;
189 this._unixMode = unixMode;
190 };
192 AbstractInfo.prototype = {
193 /**
194 * The path of the file, used for error-reporting.
195 *
196 * @type {string}
197 */
198 get path() {
199 return this._path;
200 },
201 /**
202 * |true| if this file is a directory, |false| otherwise
203 */
204 get isDir() {
205 return this._isDir;
206 },
207 /**
208 * |true| if this file is a symbolink link, |false| otherwise
209 */
210 get isSymLink() {
211 return this._isSymlLink;
212 },
213 /**
214 * The size of the file, in bytes.
215 *
216 * Note that the result may be |NaN| if the size of the file cannot be
217 * represented in JavaScript.
218 *
219 * @type {number}
220 */
221 get size() {
222 return this._size;
223 },
224 /**
225 * The date of last access to this file.
226 *
227 * Note that the definition of last access may depend on the
228 * underlying operating system and file system.
229 *
230 * @type {Date}
231 */
232 get lastAccessDate() {
233 return this._lastAccessDate;
234 },
235 /**
236 * Return the date of last modification of this file.
237 */
238 get lastModificationDate() {
239 return this._lastModificationDate;
240 },
241 /**
242 * Return the date at which the status of this file was last modified
243 * (this is the date of the latest write/renaming/mode change/...
244 * of the file)
245 */
246 get unixLastStatusChangeDate() {
247 return this._unixLastStatusChangeDate;
248 },
249 /*
250 * Return the Unix owner of this file
251 */
252 get unixOwner() {
253 return this._unixOwner;
254 },
255 /*
256 * Return the Unix group of this file
257 */
258 get unixGroup() {
259 return this._unixGroup;
260 },
261 /*
262 * Return the Unix group of this file
263 */
264 get unixMode() {
265 return this._unixMode;
266 }
267 };
268 exports.AbstractInfo = AbstractInfo;
270 /**
271 * Code shared by implementations of File.DirectoryIterator.Entry on Unix
272 *
273 * @constructor
274 */
275 let AbstractEntry = function AbstractEntry(isDir, isSymLink, name, path) {
276 this._isDir = isDir;
277 this._isSymlLink = isSymLink;
278 this._name = name;
279 this._path = path;
280 };
282 AbstractEntry.prototype = {
283 /**
284 * |true| if the entry is a directory, |false| otherwise
285 */
286 get isDir() {
287 return this._isDir;
288 },
289 /**
290 * |true| if the entry is a directory, |false| otherwise
291 */
292 get isSymLink() {
293 return this._isSymlLink;
294 },
295 /**
296 * The name of the entry
297 * @type {string}
298 */
299 get name() {
300 return this._name;
301 },
302 /**
303 * The full path to the entry
304 */
305 get path() {
306 return this._path;
307 }
308 };
309 exports.AbstractEntry = AbstractEntry;
311 // Special constants that need to be defined on all platforms
313 exports.POS_START = Const.SEEK_SET;
314 exports.POS_CURRENT = Const.SEEK_CUR;
315 exports.POS_END = Const.SEEK_END;
317 // Special types that need to be defined for communication
318 // between threads
319 let Type = Object.create(SharedAll.Type);
320 exports.Type = Type;
322 /**
323 * Native paths
324 *
325 * Under Unix, expressed as C strings
326 */
327 Type.path = Type.cstring.withName("[in] path");
328 Type.out_path = Type.out_cstring.withName("[out] path");
330 // Special constructors that need to be defined on all threads
331 OSError.closed = function closed(operation, path) {
332 return new OSError(operation, Const.EBADF, path);
333 };
335 OSError.exists = function exists(operation, path) {
336 return new OSError(operation, Const.EEXIST, path);
337 };
339 OSError.noSuchFile = function noSuchFile(operation, path) {
340 return new OSError(operation, Const.ENOENT, path);
341 };
343 OSError.invalidArgument = function invalidArgument(operation) {
344 return new OSError(operation, Const.EINVAL);
345 };
347 let EXPORTED_SYMBOLS = [
348 "declareFFI",
349 "libc",
350 "Error",
351 "AbstractInfo",
352 "AbstractEntry",
353 "Type",
354 "POS_START",
355 "POS_CURRENT",
356 "POS_END"
357 ];
359 //////////// Boilerplate
360 if (typeof Components != "undefined") {
361 this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
362 for (let symbol of EXPORTED_SYMBOLS) {
363 this[symbol] = exports[symbol];
364 }
365 }