tor-browser

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

test_fileListUpgrade.js (5757B)


      1 /**
      2 * Any copyright is dedicated to the Public Domain.
      3 * http://creativecommons.org/publicdomain/zero/1.0/
      4 */
      5 
      6 /* exported testGenerator */
      7 var testGenerator = testSteps();
      8 
      9 function* testSteps() {
     10  /**
     11   * High level description: This is a synthetic test whose main aim is to
     12   * ensure that DeserializeUpgradeValueHelper is safe with the FileList type
     13   * in its future use cases, and in the unlikely case that someone traverses
     14   * this code path with an artificially constructed profile.
     15   *
     16   * The packaged profile of filelistUpgrade_profile.zip was manufactured in
     17   * the following way:
     18   *
     19   * 1. IDBFactory methods OpenForPrincipal was exposed by removing the
     20   * ChromeOnly attribute from the IDBFactory.webidl file and making the
     21   * corresponding changes to the header and source files.
     22   * 1. mochitest test_file_filelist.html was converted to an xpcshell-test
     23   * which from here on is referred to as test_file_filelist.js
     24   * 1. test_file_filelist.js test was modified to create a principal for
     25   * example.com the same way as dom/push/test/xpcshell/test_service_child.js
     26   * 1. test_file_filelist.js test was modified to open the databases using
     27   * the openForPrincipal method, with the principal above
     28   * 1. test_file_filelist.js test was executed and the related
     29   * xpcshell profile was saved
     30   * 1. this whole play with the principals is necessary to make sure that the
     31   * resulting database is not encrypted, and can be queried with a normal
     32   * sqlite3 client
     33   * 1. file dom/indexedDB/SchemaUpgrades.cpp was modified to expect the
     34   * current database version to be 19 and stop the upgrades at this version
     35   * 1. additionally, the function UpgradeKeyFunction of
     36   * UpgradeSchemaFrom17_0To18_0Helper was modified to copy the aSource value to
     37   * aDestination, set aTagOffset to zero and return with NS_OK when the
     38   * aSource value equals 48
     39   * 1. test_schema18upgrade.js was modified to stop after the database upgrade
     40   * and executed. The related xpcshell profile with version 19 was saved.
     41   * 1. the version 19 database was opened with sqlite3 client and the other
     42   * profile with a filelist was attached to it as "future"
     43   * 1. values (2, 0, "FileLists", "key") and
     44   * (3, 0, "Other FileLists", "key") were inserted to table object_store
     45   * 1. the .schema command was executed to record the current schema
     46   * 1. object_data_insert_trigger was dropped (temporarily)
     47   * 1. the following query was used to insert all data from the attached
     48   * database to the old version:
     49   *   INSERT INTO object_data (
     50   *     object_store_id,
     51   *     key,
     52   *     index_data_values,
     53   *     file_ids,
     54   *     data)
     55   *   SELECT
     56   *     (CASE WHEN (ROW_NUMBER() OVER () <= 2) THEN 2 ELSE 3 END),
     57   *     key,
     58   *     NULL,
     59   *     file_ids,
     60   *     data
     61   *   FROM future.object_data;
     62   * 1. everything from future.file is inserted to file
     63   * 1. the following query was used to update the database name:
     64   *    INSERT INTO database
     65   *    SELECT
     66   *      'fileListUpgrade',
     67   *      origin,
     68   *      version,
     69   *      last_vacuum_time,
     70   *      last_analyze_time,
     71   *      last_vacuum_size
     72   *    FROM database WHERE name = 'schema18upgrade';
     73   * 1. the row with name 'schema18upgrade' was deleted from database
     74   * 1. the sqlite3 client was closed
     75   * 1. the filename that is expected for this test was found out with the
     76   * GetFileName method of dbFileUrl in the beginning of CreateStorageConnection
     77   * function in dom/indexedDB/ActorsParent.cpp
     78   * 1. under the idb-directory under the profile/storage path, the
     79   * .sqlite database file and the directory with a matching name having
     80   * a .files extension were renamed to have the expected name with the same
     81   * extensions
     82   * 1. the file '1' and the journal firectory from the other, filelist
     83   * containing profile, for the example.com principal, were copied under the
     84   * just renamed .files directory
     85   * 1. lastly, the storage/ folder and storage.sqlite were recursively zipped
     86   * into an archive (note: zip -r on wsl did not produce a readable archive,
     87   * the artifact was created with the windows file manager compression tool)
     88   */
     89  const testName = "fileListUpgrade";
     90 
     91  clearAllDatabases(continueToNextStepSync);
     92  yield undefined;
     93 
     94  info("Installing profile");
     95 
     96  installPackagedProfile(testName + "_profile");
     97 
     98  info("Opening existing database with a filelist");
     99 
    100  let request = indexedDB.open(testName);
    101  request.onerror = errorHandler;
    102  request.onupgradeneeded = unexpectedSuccessHandler;
    103  request.onsuccess = grabEventAndContinueHandler;
    104  let event = yield undefined;
    105  info("Database version " + event.target.result.version);
    106 
    107  let db = event.target.result;
    108 
    109  is(db.version, 3, "Correct db version");
    110 
    111  let transaction = db.transaction(["FileLists"]);
    112  transaction.oncomplete = grabEventAndContinueHandler;
    113 
    114  let objectStore = transaction.objectStore("FileLists");
    115 
    116  request = objectStore.openCursor();
    117  request.onerror = errorHandler;
    118  request.onupgradeneeded = unexpectedSuccessHandler;
    119  var cursorItems = 0;
    120  const expectedValues = new Set([
    121    '{"key":"A","idx":0,"fileList":{"0":{},"1":{},"2":{}},"blob":{}}',
    122    '{"key":"C","idx":2,"fileList":{"0":{},"1":{},"2":{}},"blob":{}}',
    123  ]);
    124  request.onsuccess = event => {
    125    let cursor = event.target.result;
    126    if (cursor) {
    127      cursorItems = cursorItems + 1;
    128      const actualValue = JSON.stringify(cursor.value);
    129      ok(expectedValues.has(actualValue), "Is value as expected?");
    130      cursor.continue();
    131    } else {
    132      testGenerator.next();
    133    }
    134  };
    135  yield undefined;
    136  is(cursorItems, expectedValues.size, "Did we get expected number of items?");
    137 
    138  finishTest();
    139  yield undefined;
    140 }