tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

head.js (8143B)


      1 /**
      2 * Any copyright is dedicated to the Public Domain.
      3 * http://creativecommons.org/publicdomain/zero/1.0/
      4 */
      5 
      6 // Tests are expected to define testSteps.
      7 /* globals testSteps */
      8 
      9 const NS_ERROR_DOM_QUOTA_EXCEEDED_ERR = 22;
     10 
     11 function is(a, b, msg) {
     12  Assert.equal(a, b, msg);
     13 }
     14 
     15 function ok(cond, msg) {
     16  Assert.ok(!!cond, msg);
     17 }
     18 
     19 add_setup(function () {
     20  do_get_profile();
     21 
     22  const { ProcessUtils } = ChromeUtils.importESModule(
     23    "resource://testing-common/dom/quota/test/modules/ProcessUtils.sys.mjs"
     24  );
     25 
     26  if (ProcessUtils.isInParentProcess()) {
     27    enableTesting();
     28 
     29    registerCleanupFunction(resetTesting);
     30  }
     31 });
     32 
     33 function returnToEventLoop() {
     34  return new Promise(function (resolve) {
     35    executeSoon(resolve);
     36  });
     37 }
     38 
     39 function enableTesting() {
     40  Services.prefs.setBoolPref("dom.simpleDB.enabled", true);
     41  Services.prefs.setBoolPref("dom.storage.testing", true);
     42 
     43  // xpcshell globals don't have associated clients in the Clients API sense, so
     44  // we need to disable client validation so that the unit tests are allowed to
     45  // use LocalStorage.
     46  Services.prefs.setBoolPref("dom.storage.client_validation", false);
     47 
     48  Services.prefs.setBoolPref("dom.quotaManager.testing", true);
     49 }
     50 
     51 function resetTesting() {
     52  Services.prefs.clearUserPref("dom.quotaManager.testing");
     53  Services.prefs.clearUserPref("dom.storage.client_validation");
     54  Services.prefs.clearUserPref("dom.storage.testing");
     55  Services.prefs.clearUserPref("dom.simpleDB.enabled");
     56 }
     57 
     58 function setGlobalLimit(globalLimit) {
     59  Services.prefs.setIntPref(
     60    "dom.quotaManager.temporaryStorage.fixedLimit",
     61    globalLimit
     62  );
     63 }
     64 
     65 function resetGlobalLimit() {
     66  Services.prefs.clearUserPref("dom.quotaManager.temporaryStorage.fixedLimit");
     67 }
     68 
     69 function setOriginLimit(originLimit) {
     70  Services.prefs.setIntPref("dom.storage.default_quota", originLimit);
     71 }
     72 
     73 function resetOriginLimit() {
     74  Services.prefs.clearUserPref("dom.storage.default_quota");
     75 }
     76 
     77 function setTimeout(callback, timeout) {
     78  let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
     79 
     80  timer.initWithCallback(
     81    {
     82      notify() {
     83        callback();
     84      },
     85    },
     86    timeout,
     87    Ci.nsITimer.TYPE_ONE_SHOT
     88  );
     89 
     90  return timer;
     91 }
     92 
     93 function initStorage() {
     94  return Services.qms.init();
     95 }
     96 
     97 function initTemporaryStorage() {
     98  return Services.qms.initTemporaryStorage();
     99 }
    100 
    101 function initPersistentOrigin(principal) {
    102  return Services.qms.initializePersistentOrigin(principal);
    103 }
    104 
    105 function initTemporaryOrigin(
    106  persistence,
    107  principal,
    108  createIfNonExistent = true
    109 ) {
    110  return Services.qms.initializeTemporaryOrigin(
    111    persistence,
    112    principal,
    113    createIfNonExistent
    114  );
    115 }
    116 
    117 function getOriginUsage(principal) {
    118  let request = Services.qms.getUsageForPrincipal(principal, function () {});
    119 
    120  return request;
    121 }
    122 
    123 function getCachedOriginUsage(principal) {
    124  let request = Services.qms.getCachedUsageForPrincipal(
    125    principal,
    126    function () {}
    127  );
    128 
    129  return request;
    130 }
    131 
    132 function clear() {
    133  let request = Services.qms.clear();
    134 
    135  return request;
    136 }
    137 
    138 function clearOriginsByPattern(pattern) {
    139  let request = Services.qms.clearStoragesForOriginAttributesPattern(pattern);
    140 
    141  return request;
    142 }
    143 
    144 function clearOriginsByPrefix(principal, persistence) {
    145  let request = Services.qms.clearStoragesForOriginPrefix(
    146    principal,
    147    persistence
    148  );
    149 
    150  return request;
    151 }
    152 
    153 function clearOrigin(principal, persistence) {
    154  let request = Services.qms.clearStoragesForPrincipal(principal, persistence);
    155 
    156  return request;
    157 }
    158 
    159 function reset() {
    160  let request = Services.qms.reset();
    161 
    162  return request;
    163 }
    164 
    165 function resetClient(principal) {
    166  let request = Services.qms.resetStoragesForClient(principal, "ls", "default");
    167 
    168  return request;
    169 }
    170 
    171 function installPackage(packageName) {
    172  let currentDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
    173 
    174  let packageFile = currentDir.clone();
    175  packageFile.append(packageName + ".zip");
    176 
    177  let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(
    178    Ci.nsIZipReader
    179  );
    180  zipReader.open(packageFile);
    181 
    182  let entryNames = [];
    183  let entries = zipReader.findEntries(null);
    184  while (entries.hasMore()) {
    185    let entry = entries.getNext();
    186    entryNames.push(entry);
    187  }
    188  entryNames.sort();
    189 
    190  for (let entryName of entryNames) {
    191    let zipentry = zipReader.getEntry(entryName);
    192 
    193    let file = getRelativeFile(entryName);
    194 
    195    if (zipentry.isDirectory) {
    196      file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8));
    197    } else {
    198      let istream = zipReader.getInputStream(entryName);
    199 
    200      var ostream = Cc[
    201        "@mozilla.org/network/file-output-stream;1"
    202      ].createInstance(Ci.nsIFileOutputStream);
    203      ostream.init(file, -1, parseInt("0644", 8), 0);
    204 
    205      let bostream = Cc[
    206        "@mozilla.org/network/buffered-output-stream;1"
    207      ].createInstance(Ci.nsIBufferedOutputStream);
    208      bostream.init(ostream, 32768);
    209 
    210      bostream.writeFrom(istream, istream.available());
    211 
    212      istream.close();
    213      bostream.close();
    214    }
    215  }
    216 
    217  zipReader.close();
    218 }
    219 
    220 function getProfileDir() {
    221  return Services.dirsvc.get("ProfD", Ci.nsIFile);
    222 }
    223 
    224 // Given a "/"-delimited path relative to the profile directory,
    225 // return an nsIFile representing the path.  This does not test
    226 // for the existence of the file or parent directories.
    227 // It is safe even on Windows where the directory separator is not "/",
    228 // but make sure you're not passing in a "\"-delimited path.
    229 function getRelativeFile(relativePath) {
    230  let profileDir = getProfileDir();
    231 
    232  let file = profileDir.clone();
    233  relativePath.split("/").forEach(function (component) {
    234    file.append(component);
    235  });
    236 
    237  return file;
    238 }
    239 
    240 function repeatChar(count, ch) {
    241  if (count == 0) {
    242    return "";
    243  }
    244 
    245  let result = ch;
    246  let count2 = count / 2;
    247 
    248  // Double the input until it is long enough.
    249  while (result.length <= count2) {
    250    result += result;
    251  }
    252 
    253  // Use substring to hit the precise length target without using extra memory.
    254  return result + result.substring(0, count - result.length);
    255 }
    256 
    257 function getPrincipal(url, attrs) {
    258  let uri = Services.io.newURI(url);
    259  if (!attrs) {
    260    attrs = {};
    261  }
    262  return Services.scriptSecurityManager.createContentPrincipal(uri, attrs);
    263 }
    264 
    265 function getCurrentPrincipal() {
    266  return Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
    267 }
    268 
    269 function getDefaultPrincipal() {
    270  return getPrincipal("http://example.com");
    271 }
    272 
    273 function getSimpleDatabase(principal, persistence) {
    274  let connection = Cc["@mozilla.org/dom/sdb-connection;1"].createInstance(
    275    Ci.nsISDBConnection
    276  );
    277 
    278  if (!principal) {
    279    principal = getDefaultPrincipal();
    280  }
    281 
    282  connection.init(principal, persistence);
    283 
    284  return connection;
    285 }
    286 
    287 function getLocalStorage(principal) {
    288  if (!principal) {
    289    principal = getDefaultPrincipal();
    290  }
    291 
    292  return Services.domStorageManager.createStorage(
    293    null,
    294    principal,
    295    principal,
    296    ""
    297  );
    298 }
    299 
    300 class RequestError extends Error {
    301  constructor(resultCode, resultName) {
    302    super(`Request failed (code: ${resultCode}, name: ${resultName})`);
    303    this.name = "RequestError";
    304    this.resultCode = resultCode;
    305    this.resultName = resultName;
    306  }
    307 }
    308 
    309 async function requestFinished(request) {
    310  await new Promise(function (resolve) {
    311    request.callback = function () {
    312      resolve();
    313    };
    314  });
    315 
    316  if (request.resultCode !== Cr.NS_OK) {
    317    throw new RequestError(request.resultCode, request.resultName);
    318  }
    319 
    320  return request.result;
    321 }
    322 
    323 function loadSubscript(path) {
    324  let file = do_get_file(path, false);
    325  let uri = Services.io.newFileURI(file);
    326  Services.scriptloader.loadSubScript(uri.spec);
    327 }
    328 
    329 async function readUsageFromUsageFile(usageFile) {
    330  let file = await File.createFromNsIFile(usageFile);
    331 
    332  let buffer = await new Promise(resolve => {
    333    let reader = new FileReader();
    334    reader.onloadend = () => resolve(reader.result);
    335    reader.readAsArrayBuffer(file);
    336  });
    337 
    338  // Manually getting the lower 32-bits because of the lack of support for
    339  // 64-bit values currently from DataView/JS (other than the BigInt support
    340  // that's currently behind a flag).
    341  let view = new DataView(buffer, 8, 4);
    342  return view.getUint32();
    343 }