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.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | "use strict"; |
michael@0 | 6 | |
michael@0 | 7 | module.metadata = { |
michael@0 | 8 | "stability": "experimental" |
michael@0 | 9 | }; |
michael@0 | 10 | |
michael@0 | 11 | const {Cc,Ci,Cr} = require("chrome"); |
michael@0 | 12 | const byteStreams = require("./byte-streams"); |
michael@0 | 13 | const textStreams = require("./text-streams"); |
michael@0 | 14 | |
michael@0 | 15 | // Flags passed when opening a file. See nsprpub/pr/include/prio.h. |
michael@0 | 16 | const OPEN_FLAGS = { |
michael@0 | 17 | RDONLY: parseInt("0x01"), |
michael@0 | 18 | WRONLY: parseInt("0x02"), |
michael@0 | 19 | CREATE_FILE: parseInt("0x08"), |
michael@0 | 20 | APPEND: parseInt("0x10"), |
michael@0 | 21 | TRUNCATE: parseInt("0x20"), |
michael@0 | 22 | EXCL: parseInt("0x80") |
michael@0 | 23 | }; |
michael@0 | 24 | |
michael@0 | 25 | var dirsvc = Cc["@mozilla.org/file/directory_service;1"] |
michael@0 | 26 | .getService(Ci.nsIProperties); |
michael@0 | 27 | |
michael@0 | 28 | function MozFile(path) { |
michael@0 | 29 | var file = Cc['@mozilla.org/file/local;1'] |
michael@0 | 30 | .createInstance(Ci.nsILocalFile); |
michael@0 | 31 | file.initWithPath(path); |
michael@0 | 32 | return file; |
michael@0 | 33 | } |
michael@0 | 34 | |
michael@0 | 35 | function ensureReadable(file) { |
michael@0 | 36 | if (!file.isReadable()) |
michael@0 | 37 | throw new Error("path is not readable: " + file.path); |
michael@0 | 38 | } |
michael@0 | 39 | |
michael@0 | 40 | function ensureDir(file) { |
michael@0 | 41 | ensureExists(file); |
michael@0 | 42 | if (!file.isDirectory()) |
michael@0 | 43 | throw new Error("path is not a directory: " + file.path); |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | function ensureFile(file) { |
michael@0 | 47 | ensureExists(file); |
michael@0 | 48 | if (!file.isFile()) |
michael@0 | 49 | throw new Error("path is not a file: " + file.path); |
michael@0 | 50 | } |
michael@0 | 51 | |
michael@0 | 52 | function ensureExists(file) { |
michael@0 | 53 | if (!file.exists()) |
michael@0 | 54 | throw friendlyError(Cr.NS_ERROR_FILE_NOT_FOUND, file.path); |
michael@0 | 55 | } |
michael@0 | 56 | |
michael@0 | 57 | function friendlyError(errOrResult, filename) { |
michael@0 | 58 | var isResult = typeof(errOrResult) === "number"; |
michael@0 | 59 | var result = isResult ? errOrResult : errOrResult.result; |
michael@0 | 60 | switch (result) { |
michael@0 | 61 | case Cr.NS_ERROR_FILE_NOT_FOUND: |
michael@0 | 62 | return new Error("path does not exist: " + filename); |
michael@0 | 63 | } |
michael@0 | 64 | return isResult ? new Error("XPCOM error code: " + errOrResult) : errOrResult; |
michael@0 | 65 | } |
michael@0 | 66 | |
michael@0 | 67 | exports.exists = function exists(filename) { |
michael@0 | 68 | return MozFile(filename).exists(); |
michael@0 | 69 | }; |
michael@0 | 70 | |
michael@0 | 71 | exports.isFile = function isFile(filename) { |
michael@0 | 72 | return MozFile(filename).isFile(); |
michael@0 | 73 | }; |
michael@0 | 74 | |
michael@0 | 75 | exports.read = function read(filename, mode) { |
michael@0 | 76 | if (typeof(mode) !== "string") |
michael@0 | 77 | mode = ""; |
michael@0 | 78 | |
michael@0 | 79 | // Ensure mode is read-only. |
michael@0 | 80 | mode = /b/.test(mode) ? "b" : ""; |
michael@0 | 81 | |
michael@0 | 82 | var stream = exports.open(filename, mode); |
michael@0 | 83 | try { |
michael@0 | 84 | var str = stream.read(); |
michael@0 | 85 | } |
michael@0 | 86 | finally { |
michael@0 | 87 | stream.close(); |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | return str; |
michael@0 | 91 | }; |
michael@0 | 92 | |
michael@0 | 93 | exports.join = function join(base) { |
michael@0 | 94 | if (arguments.length < 2) |
michael@0 | 95 | throw new Error("need at least 2 args"); |
michael@0 | 96 | base = MozFile(base); |
michael@0 | 97 | for (var i = 1; i < arguments.length; i++) |
michael@0 | 98 | base.append(arguments[i]); |
michael@0 | 99 | return base.path; |
michael@0 | 100 | }; |
michael@0 | 101 | |
michael@0 | 102 | exports.dirname = function dirname(path) { |
michael@0 | 103 | var parent = MozFile(path).parent; |
michael@0 | 104 | return parent ? parent.path : ""; |
michael@0 | 105 | }; |
michael@0 | 106 | |
michael@0 | 107 | exports.basename = function basename(path) { |
michael@0 | 108 | var leafName = MozFile(path).leafName; |
michael@0 | 109 | |
michael@0 | 110 | // On Windows, leafName when the path is a volume letter and colon ("c:") is |
michael@0 | 111 | // the path itself. But such a path has no basename, so we want the empty |
michael@0 | 112 | // string. |
michael@0 | 113 | return leafName == path ? "" : leafName; |
michael@0 | 114 | }; |
michael@0 | 115 | |
michael@0 | 116 | exports.list = function list(path) { |
michael@0 | 117 | var file = MozFile(path); |
michael@0 | 118 | ensureDir(file); |
michael@0 | 119 | ensureReadable(file); |
michael@0 | 120 | |
michael@0 | 121 | var entries = file.directoryEntries; |
michael@0 | 122 | var entryNames = []; |
michael@0 | 123 | while(entries.hasMoreElements()) { |
michael@0 | 124 | var entry = entries.getNext(); |
michael@0 | 125 | entry.QueryInterface(Ci.nsIFile); |
michael@0 | 126 | entryNames.push(entry.leafName); |
michael@0 | 127 | } |
michael@0 | 128 | return entryNames; |
michael@0 | 129 | }; |
michael@0 | 130 | |
michael@0 | 131 | exports.open = function open(filename, mode) { |
michael@0 | 132 | var file = MozFile(filename); |
michael@0 | 133 | if (typeof(mode) !== "string") |
michael@0 | 134 | mode = ""; |
michael@0 | 135 | |
michael@0 | 136 | // File opened for write only. |
michael@0 | 137 | if (/w/.test(mode)) { |
michael@0 | 138 | if (file.exists()) |
michael@0 | 139 | ensureFile(file); |
michael@0 | 140 | var stream = Cc['@mozilla.org/network/file-output-stream;1']. |
michael@0 | 141 | createInstance(Ci.nsIFileOutputStream); |
michael@0 | 142 | var openFlags = OPEN_FLAGS.WRONLY | |
michael@0 | 143 | OPEN_FLAGS.CREATE_FILE | |
michael@0 | 144 | OPEN_FLAGS.TRUNCATE; |
michael@0 | 145 | var permFlags = parseInt("0644", 8); // u+rw go+r |
michael@0 | 146 | try { |
michael@0 | 147 | stream.init(file, openFlags, permFlags, 0); |
michael@0 | 148 | } |
michael@0 | 149 | catch (err) { |
michael@0 | 150 | throw friendlyError(err, filename); |
michael@0 | 151 | } |
michael@0 | 152 | return /b/.test(mode) ? |
michael@0 | 153 | new byteStreams.ByteWriter(stream) : |
michael@0 | 154 | new textStreams.TextWriter(stream); |
michael@0 | 155 | } |
michael@0 | 156 | |
michael@0 | 157 | // File opened for read only, the default. |
michael@0 | 158 | ensureFile(file); |
michael@0 | 159 | stream = Cc['@mozilla.org/network/file-input-stream;1']. |
michael@0 | 160 | createInstance(Ci.nsIFileInputStream); |
michael@0 | 161 | try { |
michael@0 | 162 | stream.init(file, OPEN_FLAGS.RDONLY, 0, 0); |
michael@0 | 163 | } |
michael@0 | 164 | catch (err) { |
michael@0 | 165 | throw friendlyError(err, filename); |
michael@0 | 166 | } |
michael@0 | 167 | return /b/.test(mode) ? |
michael@0 | 168 | new byteStreams.ByteReader(stream) : |
michael@0 | 169 | new textStreams.TextReader(stream); |
michael@0 | 170 | }; |
michael@0 | 171 | |
michael@0 | 172 | exports.remove = function remove(path) { |
michael@0 | 173 | var file = MozFile(path); |
michael@0 | 174 | ensureFile(file); |
michael@0 | 175 | file.remove(false); |
michael@0 | 176 | }; |
michael@0 | 177 | |
michael@0 | 178 | exports.mkpath = function mkpath(path) { |
michael@0 | 179 | var file = MozFile(path); |
michael@0 | 180 | if (!file.exists()) |
michael@0 | 181 | file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8)); // u+rwx go+rx |
michael@0 | 182 | else if (!file.isDirectory()) |
michael@0 | 183 | throw new Error("The path already exists and is not a directory: " + path); |
michael@0 | 184 | }; |
michael@0 | 185 | |
michael@0 | 186 | exports.rmdir = function rmdir(path) { |
michael@0 | 187 | var file = MozFile(path); |
michael@0 | 188 | ensureDir(file); |
michael@0 | 189 | try { |
michael@0 | 190 | file.remove(false); |
michael@0 | 191 | } |
michael@0 | 192 | catch (err) { |
michael@0 | 193 | // Bug 566950 explains why we're not catching a specific exception here. |
michael@0 | 194 | throw new Error("The directory is not empty: " + path); |
michael@0 | 195 | } |
michael@0 | 196 | }; |