tor-browser

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

file.js (7569B)


      1 /**
      2 * Any copyright is dedicated to the Public Domain.
      3 * http://creativecommons.org/publicdomain/zero/1.0/
      4 */
      5 
      6 /* import-globals-from helpers.js */
      7 
      8 var bufferCache = [];
      9 var utils = SpecialPowers.getDOMWindowUtils(window);
     10 
     11 function getBuffer(size) {
     12  let buffer = new ArrayBuffer(size);
     13  is(buffer.byteLength, size, "Correct byte length");
     14  return buffer;
     15 }
     16 
     17 function getRandomBuffer(size) {
     18  let buffer = getBuffer(size);
     19  let view = new Uint8Array(buffer);
     20  for (let i = 0; i < size; i++) {
     21    view[i] = parseInt(Math.random() * 255);
     22  }
     23  return buffer;
     24 }
     25 
     26 function getView(size) {
     27  let buffer = new ArrayBuffer(size);
     28  let view = new Uint8Array(buffer);
     29  is(buffer.byteLength, size, "Correct byte length");
     30  return view;
     31 }
     32 
     33 function getRandomView(size) {
     34  let view = getView(size);
     35  for (let i = 0; i < size; i++) {
     36    view[i] = parseInt(Math.random() * 255);
     37  }
     38  return view;
     39 }
     40 
     41 function compareBuffers(buffer1, buffer2) {
     42  if (buffer1.byteLength != buffer2.byteLength) {
     43    return false;
     44  }
     45  let view1 = buffer1 instanceof Uint8Array ? buffer1 : new Uint8Array(buffer1);
     46  let view2 = buffer2 instanceof Uint8Array ? buffer2 : new Uint8Array(buffer2);
     47  for (let i = 0; i < buffer1.byteLength; i++) {
     48    if (view1[i] != view2[i]) {
     49      return false;
     50    }
     51  }
     52  return true;
     53 }
     54 
     55 function getBlob(type, view) {
     56  return new Blob([view], { type });
     57 }
     58 
     59 function getFile(name, type, view) {
     60  return new File([view], name, { type });
     61 }
     62 
     63 function getRandomBlob(size) {
     64  return getBlob("binary/random", getRandomView(size));
     65 }
     66 
     67 function getRandomFile(name, size) {
     68  return getFile(name, "binary/random", getRandomView(size));
     69 }
     70 
     71 function getNullBlob(size) {
     72  return getBlob("binary/null", getView(size));
     73 }
     74 
     75 function getNullFile(name, size) {
     76  return getFile(name, "binary/null", getView(size));
     77 }
     78 
     79 function getWasmModule(binary) {
     80  let module = new WebAssembly.Module(binary);
     81  return module;
     82 }
     83 
     84 function verifyBuffers(buffer1, buffer2) {
     85  ok(compareBuffers(buffer1, buffer2), "Correct buffer data");
     86 }
     87 
     88 function verifyBlobProperties(blob1, blob2, fileId) {
     89  // eslint-disable-next-line mozilla/use-cc-etc
     90  is(SpecialPowers.wrap(Blob).isInstance(blob1), true, "Instance of Blob");
     91  is(blob1 instanceof File, blob2 instanceof File, "Instance of DOM File");
     92  is(blob1.size, blob2.size, "Correct size");
     93  is(blob1.type, blob2.type, "Correct type");
     94  if (blob2 instanceof File) {
     95    is(blob1.name, blob2.name, "Correct name");
     96  }
     97  is(utils.getFileId(blob1), fileId, "Correct file id");
     98 }
     99 
    100 /**
    101 * verifyBlobAsync checks that blob1 has the same size, type and buffer as
    102 * blob2, and the given fileId. Additionally, if blob2 is a File, the names
    103 * of two blobs must be equal.
    104 *
    105 * Note: Unlike the generator based verifyBlob routine, verifyBlobAsync uses
    106 * bufferCache for both blob1 and blob2 arguments.
    107 *
    108 * @param {Blob} blob1 actual Blob value
    109 * @param {Blob} blob2 Blob with expected properties
    110 * @param {number} fileId expected id
    111 */
    112 async function verifyBlobAsync(blob1, blob2, fileId) {
    113  verifyBlobProperties(blob1, blob2, fileId);
    114 
    115  let buffer1;
    116  let buffer2;
    117 
    118  for (let i = 0; i < bufferCache.length; i++) {
    119    if (!buffer1 && bufferCache[i].blob == blob1) {
    120      buffer1 = bufferCache[i].buffer;
    121    }
    122 
    123    if (!buffer2 && bufferCache[i].blob == blob2) {
    124      buffer2 = bufferCache[i].buffer;
    125    }
    126 
    127    if (!!buffer1 && !!buffer2) {
    128      break;
    129    }
    130  }
    131 
    132  const getBuffer = blobItem => {
    133    return new Promise((resolve, reject) => {
    134      const reader = new FileReader();
    135      reader.addEventListener("loadend", () => {
    136        if (reader.error) {
    137          reject(reader.error);
    138        }
    139 
    140        resolve(reader.result);
    141      });
    142      reader.readAsArrayBuffer(blobItem);
    143    });
    144  };
    145 
    146  if (!buffer1) {
    147    buffer1 = await getBuffer(blob1);
    148    bufferCache.push({ blob: blob1, buffer: buffer1 });
    149  }
    150 
    151  if (!buffer2) {
    152    buffer2 = await getBuffer(blob2);
    153    bufferCache.push({ blob: blob2, buffer: buffer2 });
    154  }
    155 
    156  verifyBuffers(buffer1, buffer2);
    157 }
    158 
    159 function verifyBlob(blob1, blob2, fileId, blobReadHandler) {
    160  verifyBlobProperties(blob1, blob2, fileId);
    161 
    162  let buffer1;
    163  let buffer2;
    164 
    165  for (let i = 0; i < bufferCache.length; i++) {
    166    if (bufferCache[i].blob == blob2) {
    167      buffer2 = bufferCache[i].buffer;
    168      break;
    169    }
    170  }
    171 
    172  if (!buffer2) {
    173    let reader = new FileReader();
    174    reader.readAsArrayBuffer(blob2);
    175    reader.onload = function (event) {
    176      buffer2 = event.target.result;
    177      bufferCache.push({ blob: blob2, buffer: buffer2 });
    178      if (buffer1) {
    179        verifyBuffers(buffer1, buffer2);
    180        if (blobReadHandler) {
    181          blobReadHandler();
    182        } else {
    183          testGenerator.next();
    184        }
    185      }
    186    };
    187  }
    188 
    189  let reader = new FileReader();
    190  reader.readAsArrayBuffer(blob1);
    191  reader.onload = function (event) {
    192    buffer1 = event.target.result;
    193    if (buffer2) {
    194      verifyBuffers(buffer1, buffer2);
    195      if (blobReadHandler) {
    196        blobReadHandler();
    197      } else {
    198        testGenerator.next();
    199      }
    200    }
    201  };
    202 }
    203 
    204 function verifyBlobArray(blobs1, blobs2, expectedFileIds) {
    205  is(blobs1 instanceof Array, true, "Got an array object");
    206  is(blobs1.length, blobs2.length, "Correct length");
    207 
    208  if (!blobs1.length) {
    209    return;
    210  }
    211 
    212  let verifiedCount = 0;
    213 
    214  function blobReadHandler() {
    215    if (++verifiedCount == blobs1.length) {
    216      testGenerator.next();
    217    } else {
    218      verifyBlob(
    219        blobs1[verifiedCount],
    220        blobs2[verifiedCount],
    221        expectedFileIds[verifiedCount],
    222        blobReadHandler
    223      );
    224    }
    225  }
    226 
    227  verifyBlob(
    228    blobs1[verifiedCount],
    229    blobs2[verifiedCount],
    230    expectedFileIds[verifiedCount],
    231    blobReadHandler
    232  );
    233 }
    234 
    235 function verifyView(view1, view2) {
    236  is(view1.byteLength, view2.byteLength, "Correct byteLength");
    237  verifyBuffers(view1, view2);
    238 }
    239 
    240 function verifyWasmModule(module1, module2) {
    241  // We assume the given modules have no imports and export a single function
    242  // named 'run'.
    243  var instance1 = new WebAssembly.Instance(module1);
    244  var instance2 = new WebAssembly.Instance(module2);
    245  is(instance1.exports.run(), instance2.exports.run(), "same run() result");
    246 
    247  continueToNextStep();
    248 }
    249 
    250 function grabFileUsageAndContinueHandler(request) {
    251  testGenerator.next(request.result.fileUsage);
    252 }
    253 
    254 function getCurrentUsage(usageHandler) {
    255  let qms = SpecialPowers.Services.qms;
    256  let principal = SpecialPowers.wrap(document).nodePrincipal;
    257  let cb = SpecialPowers.wrapCallback(usageHandler);
    258  qms.getUsageForPrincipal(principal, cb);
    259 }
    260 
    261 function getFileId(file) {
    262  return utils.getFileId(file);
    263 }
    264 
    265 function getFilePath(file) {
    266  return utils.getFilePath(file);
    267 }
    268 
    269 function* assertEventuallyHasFileInfo(name, id) {
    270  yield* assertEventuallyWithGC(
    271    () => utils.getFileReferences(name, id),
    272    `Expect existing DatabaseFileInfo for ${name}/${id}`
    273  );
    274 }
    275 
    276 function* assertEventuallyHasNoFileInfo(name, id) {
    277  yield* assertEventuallyWithGC(
    278    () => !utils.getFileReferences(name, id),
    279    `Expect no existing DatabaseFileInfo for ${name}/${id}`
    280  );
    281 }
    282 
    283 function* assertEventuallyFileRefCount(name, id, expectedCount) {
    284  yield* assertEventuallyWithGC(() => {
    285    let count = {};
    286    utils.getFileReferences(name, id, count);
    287    return count.value == expectedCount;
    288  }, `Expect ${expectedCount} existing references for ${name}/${id}`);
    289 }
    290 
    291 function getFileDBRefCount(name, id) {
    292  let count = {};
    293  utils.getFileReferences(name, id, {}, count);
    294  return count.value;
    295 }
    296 
    297 function flushPendingFileDeletions() {
    298  utils.flushPendingFileDeletions();
    299 }