tor-browser

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

headers-record.any.js (14227B)


      1 // META: global=window,worker
      2 
      3 "use strict";
      4 
      5 var log = [];
      6 function clearLog() {
      7  log = [];
      8 }
      9 function addLogEntry(name, args) {
     10  log.push([ name, ...args ]);
     11 }
     12 
     13 var loggingHandler = {
     14 };
     15 
     16 setup(function() {
     17  for (let prop of Object.getOwnPropertyNames(Reflect)) {
     18    loggingHandler[prop] = function(...args) {
     19      addLogEntry(prop, args);
     20      return Reflect[prop](...args);
     21    }
     22  }
     23 });
     24 
     25 test(function() {
     26  var h = new Headers();
     27  assert_equals([...h].length, 0);
     28 }, "Passing nothing to Headers constructor");
     29 
     30 test(function() {
     31  var h = new Headers(undefined);
     32  assert_equals([...h].length, 0);
     33 }, "Passing undefined to Headers constructor");
     34 
     35 test(function() {
     36  assert_throws_js(TypeError, function() {
     37    var h = new Headers(null);
     38  });
     39 }, "Passing null to Headers constructor");
     40 
     41 test(function() {
     42  this.add_cleanup(clearLog);
     43  var record = { a: "b" };
     44  var proxy = new Proxy(record, loggingHandler);
     45  var h = new Headers(proxy);
     46 
     47  assert_equals(log.length, 4);
     48  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
     49  // we're a sequence, during overload resolution.
     50  assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]);
     51  // Then we have the [[OwnPropertyKeys]] from
     52  // https://webidl.spec.whatwg.org/#es-to-record step 4.
     53  assert_array_equals(log[1], ["ownKeys", record]);
     54  // Then the [[GetOwnProperty]] from step 5.1.
     55  assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]);
     56  // Then the [[Get]] from step 5.2.
     57  assert_array_equals(log[3], ["get", record, "a", proxy]);
     58 
     59  // Check the results.
     60  assert_equals([...h].length, 1);
     61  assert_array_equals([...h.keys()], ["a"]);
     62  assert_true(h.has("a"));
     63  assert_equals(h.get("a"), "b");
     64 }, "Basic operation with one property");
     65 
     66 test(function() {
     67  this.add_cleanup(clearLog);
     68  var recordProto = { c: "d" };
     69  var record = Object.create(recordProto, { a: { value: "b", enumerable: true } });
     70  var proxy = new Proxy(record, loggingHandler);
     71  var h = new Headers(proxy);
     72 
     73  assert_equals(log.length, 4);
     74  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
     75  // we're a sequence, during overload resolution.
     76  assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]);
     77  // Then we have the [[OwnPropertyKeys]] from
     78  // https://webidl.spec.whatwg.org/#es-to-record step 4.
     79  assert_array_equals(log[1], ["ownKeys", record]);
     80  // Then the [[GetOwnProperty]] from step 5.1.
     81  assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]);
     82  // Then the [[Get]] from step 5.2.
     83  assert_array_equals(log[3], ["get", record, "a", proxy]);
     84 
     85  // Check the results.
     86  assert_equals([...h].length, 1);
     87  assert_array_equals([...h.keys()], ["a"]);
     88  assert_true(h.has("a"));
     89  assert_equals(h.get("a"), "b");
     90 }, "Basic operation with one property and a proto");
     91 
     92 test(function() {
     93  this.add_cleanup(clearLog);
     94  var record = { a: "b", c: "d" };
     95  var proxy = new Proxy(record, loggingHandler);
     96  var h = new Headers(proxy);
     97 
     98  assert_equals(log.length, 6);
     99  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
    100  // we're a sequence, during overload resolution.
    101  assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]);
    102  // Then we have the [[OwnPropertyKeys]] from
    103  // https://webidl.spec.whatwg.org/#es-to-record step 4.
    104  assert_array_equals(log[1], ["ownKeys", record]);
    105  // Then the [[GetOwnProperty]] from step 5.1.
    106  assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]);
    107  // Then the [[Get]] from step 5.2.
    108  assert_array_equals(log[3], ["get", record, "a", proxy]);
    109  // Then the second [[GetOwnProperty]] from step 5.1.
    110  assert_array_equals(log[4], ["getOwnPropertyDescriptor", record, "c"]);
    111  // Then the second [[Get]] from step 5.2.
    112  assert_array_equals(log[5], ["get", record, "c", proxy]);
    113 
    114  // Check the results.
    115  assert_equals([...h].length, 2);
    116  assert_array_equals([...h.keys()], ["a", "c"]);
    117  assert_true(h.has("a"));
    118  assert_equals(h.get("a"), "b");
    119  assert_true(h.has("c"));
    120  assert_equals(h.get("c"), "d");
    121 }, "Correct operation ordering with two properties");
    122 
    123 test(function() {
    124  this.add_cleanup(clearLog);
    125  var record = { a: "b", "\uFFFF": "d" };
    126  var proxy = new Proxy(record, loggingHandler);
    127  assert_throws_js(TypeError, function() {
    128    var h = new Headers(proxy);
    129  });
    130 
    131  assert_equals(log.length, 5);
    132  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
    133  // we're a sequence, during overload resolution.
    134  assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]);
    135  // Then we have the [[OwnPropertyKeys]] from
    136  // https://webidl.spec.whatwg.org/#es-to-record step 4.
    137  assert_array_equals(log[1], ["ownKeys", record]);
    138  // Then the [[GetOwnProperty]] from step 5.1.
    139  assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]);
    140  // Then the [[Get]] from step 5.2.
    141  assert_array_equals(log[3], ["get", record, "a", proxy]);
    142  // Then the second [[GetOwnProperty]] from step 5.1.
    143  assert_array_equals(log[4], ["getOwnPropertyDescriptor", record, "\uFFFF"]);
    144  // The second [[Get]] never happens, because we convert the invalid name to a
    145  // ByteString first and throw.
    146 }, "Correct operation ordering with two properties one of which has an invalid name");
    147 
    148 test(function() {
    149  this.add_cleanup(clearLog);
    150  var record = { a: "\uFFFF", c: "d" }
    151  var proxy = new Proxy(record, loggingHandler);
    152  assert_throws_js(TypeError, function() {
    153    var h = new Headers(proxy);
    154  });
    155 
    156  assert_equals(log.length, 4);
    157  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
    158  // we're a sequence, during overload resolution.
    159  assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]);
    160  // Then we have the [[OwnPropertyKeys]] from
    161  // https://webidl.spec.whatwg.org/#es-to-record step 4.
    162  assert_array_equals(log[1], ["ownKeys", record]);
    163  // Then the [[GetOwnProperty]] from step 5.1.
    164  assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]);
    165  // Then the [[Get]] from step 5.2.
    166  assert_array_equals(log[3], ["get", record, "a", proxy]);
    167  // Nothing else after this, because converting the result of that [[Get]] to a
    168  // ByteString throws.
    169 }, "Correct operation ordering with two properties one of which has an invalid value");
    170 
    171 test(function() {
    172  this.add_cleanup(clearLog);
    173  var record = {};
    174  Object.defineProperty(record, "a", { value: "b", enumerable: false });
    175  Object.defineProperty(record, "c", { value: "d", enumerable: true });
    176  Object.defineProperty(record, "e", { value: "f", enumerable: false });
    177  var proxy = new Proxy(record, loggingHandler);
    178  var h = new Headers(proxy);
    179 
    180  assert_equals(log.length, 6);
    181  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
    182  // we're a sequence, during overload resolution.
    183  assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]);
    184  // Then we have the [[OwnPropertyKeys]] from
    185  // https://webidl.spec.whatwg.org/#es-to-record step 4.
    186  assert_array_equals(log[1], ["ownKeys", record]);
    187  // Then the [[GetOwnProperty]] from step 5.1.
    188  assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]);
    189  // No [[Get]] because not enumerable
    190  // Then the second [[GetOwnProperty]] from step 5.1.
    191  assert_array_equals(log[3], ["getOwnPropertyDescriptor", record, "c"]);
    192  // Then the [[Get]] from step 5.2.
    193  assert_array_equals(log[4], ["get", record, "c", proxy]);
    194  // Then the third [[GetOwnProperty]] from step 5.1.
    195  assert_array_equals(log[5], ["getOwnPropertyDescriptor", record, "e"]);
    196  // No [[Get]] because not enumerable
    197 
    198  // Check the results.
    199  assert_equals([...h].length, 1);
    200  assert_array_equals([...h.keys()], ["c"]);
    201  assert_true(h.has("c"));
    202  assert_equals(h.get("c"), "d");
    203 }, "Correct operation ordering with non-enumerable properties");
    204 
    205 test(function() {
    206  this.add_cleanup(clearLog);
    207  var record = {a: "b", c: "d", e: "f"};
    208  var lyingHandler = {
    209    getOwnPropertyDescriptor: function(target, name) {
    210      if (name == "a" || name == "e") {
    211        return undefined;
    212      }
    213      return Reflect.getOwnPropertyDescriptor(target, name);
    214    }
    215  };
    216  var lyingProxy = new Proxy(record, lyingHandler);
    217  var proxy = new Proxy(lyingProxy, loggingHandler);
    218  var h = new Headers(proxy);
    219 
    220  assert_equals(log.length, 6);
    221  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
    222  // we're a sequence, during overload resolution.
    223  assert_array_equals(log[0], ["get", lyingProxy, Symbol.iterator, proxy]);
    224  // Then we have the [[OwnPropertyKeys]] from
    225  // https://webidl.spec.whatwg.org/#es-to-record step 4.
    226  assert_array_equals(log[1], ["ownKeys", lyingProxy]);
    227  // Then the [[GetOwnProperty]] from step 5.1.
    228  assert_array_equals(log[2], ["getOwnPropertyDescriptor", lyingProxy, "a"]);
    229  // No [[Get]] because no descriptor
    230  // Then the second [[GetOwnProperty]] from step 5.1.
    231  assert_array_equals(log[3], ["getOwnPropertyDescriptor", lyingProxy, "c"]);
    232  // Then the [[Get]] from step 5.2.
    233  assert_array_equals(log[4], ["get", lyingProxy, "c", proxy]);
    234  // Then the third [[GetOwnProperty]] from step 5.1.
    235  assert_array_equals(log[5], ["getOwnPropertyDescriptor", lyingProxy, "e"]);
    236  // No [[Get]] because no descriptor
    237 
    238  // Check the results.
    239  assert_equals([...h].length, 1);
    240  assert_array_equals([...h.keys()], ["c"]);
    241  assert_true(h.has("c"));
    242  assert_equals(h.get("c"), "d");
    243 }, "Correct operation ordering with undefined descriptors");
    244 
    245 test(function() {
    246  this.add_cleanup(clearLog);
    247  var record = {a: "b", c: "d"};
    248  var lyingHandler = {
    249    ownKeys: function() {
    250      return [ "a", "c", "a", "c" ];
    251    },
    252  };
    253  var lyingProxy = new Proxy(record, lyingHandler);
    254  var proxy = new Proxy(lyingProxy, loggingHandler);
    255 
    256  // Returning duplicate keys from ownKeys() throws a TypeError.
    257  assert_throws_js(TypeError,
    258                   function() { var h = new Headers(proxy); });
    259 
    260  assert_equals(log.length, 2);
    261  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
    262  // we're a sequence, during overload resolution.
    263  assert_array_equals(log[0], ["get", lyingProxy, Symbol.iterator, proxy]);
    264  // Then we have the [[OwnPropertyKeys]] from
    265  // https://webidl.spec.whatwg.org/#es-to-record step 4.
    266  assert_array_equals(log[1], ["ownKeys", lyingProxy]);
    267 }, "Correct operation ordering with repeated keys");
    268 
    269 test(function() {
    270  this.add_cleanup(clearLog);
    271  var record = {
    272    a: "b",
    273    [Symbol.toStringTag]: {
    274      // Make sure the ToString conversion of the value happens
    275      // after the ToString conversion of the key.
    276      toString: function () { addLogEntry("toString", [this]); return "nope"; }
    277    },
    278    c: "d" };
    279  var proxy = new Proxy(record, loggingHandler);
    280  assert_throws_js(TypeError,
    281                   function() { var h = new Headers(proxy); });
    282 
    283  assert_equals(log.length, 7);
    284  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
    285  // we're a sequence, during overload resolution.
    286  assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]);
    287  // Then we have the [[OwnPropertyKeys]] from
    288  // https://webidl.spec.whatwg.org/#es-to-record step 4.
    289  assert_array_equals(log[1], ["ownKeys", record]);
    290  // Then the [[GetOwnProperty]] from step 5.1.
    291  assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]);
    292  // Then the [[Get]] from step 5.2.
    293  assert_array_equals(log[3], ["get", record, "a", proxy]);
    294  // Then the second [[GetOwnProperty]] from step 5.1.
    295  assert_array_equals(log[4], ["getOwnPropertyDescriptor", record, "c"]);
    296  // Then the second [[Get]] from step 5.2.
    297  assert_array_equals(log[5], ["get", record, "c", proxy]);
    298  // Then the third [[GetOwnProperty]] from step 5.1.
    299  assert_array_equals(log[6], ["getOwnPropertyDescriptor", record,
    300                               Symbol.toStringTag]);
    301  // Then we throw an exception converting the Symbol to a string, before we do
    302  // the third [[Get]].
    303 }, "Basic operation with Symbol keys");
    304 
    305 test(function() {
    306  this.add_cleanup(clearLog);
    307  var record = {
    308    a: {
    309      toString: function() { addLogEntry("toString", [this]); return "b"; }
    310    },
    311    [Symbol.toStringTag]: {
    312      toString: function () { addLogEntry("toString", [this]); return "nope"; }
    313    },
    314    c: {
    315      toString: function() { addLogEntry("toString", [this]); return "d"; }
    316    }
    317  };
    318  // Now make that Symbol-named property not enumerable.
    319  Object.defineProperty(record, Symbol.toStringTag, { enumerable: false });
    320  assert_array_equals(Reflect.ownKeys(record),
    321                      ["a", "c", Symbol.toStringTag]);
    322 
    323  var proxy = new Proxy(record, loggingHandler);
    324  var h = new Headers(proxy);
    325 
    326  assert_equals(log.length, 9);
    327  // The first thing is the [[Get]] of Symbol.iterator to figure out whether
    328  // we're a sequence, during overload resolution.
    329  assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]);
    330  // Then we have the [[OwnPropertyKeys]] from
    331  // https://webidl.spec.whatwg.org/#es-to-record step 4.
    332  assert_array_equals(log[1], ["ownKeys", record]);
    333  // Then the [[GetOwnProperty]] from step 5.1.
    334  assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]);
    335  // Then the [[Get]] from step 5.2.
    336  assert_array_equals(log[3], ["get", record, "a", proxy]);
    337  // Then the ToString on the value.
    338  assert_array_equals(log[4], ["toString", record.a]);
    339  // Then the second [[GetOwnProperty]] from step 5.1.
    340  assert_array_equals(log[5], ["getOwnPropertyDescriptor", record, "c"]);
    341  // Then the second [[Get]] from step 5.2.
    342  assert_array_equals(log[6], ["get", record, "c", proxy]);
    343  // Then the ToString on the value.
    344  assert_array_equals(log[7], ["toString", record.c]);
    345  // Then the third [[GetOwnProperty]] from step 5.1.
    346  assert_array_equals(log[8], ["getOwnPropertyDescriptor", record,
    347                               Symbol.toStringTag]);
    348  // No [[Get]] because not enumerable.
    349 
    350  // Check the results.
    351  assert_equals([...h].length, 2);
    352  assert_array_equals([...h.keys()], ["a", "c"]);
    353  assert_true(h.has("a"));
    354  assert_equals(h.get("a"), "b");
    355  assert_true(h.has("c"));
    356  assert_equals(h.get("c"), "d");
    357 }, "Operation with non-enumerable Symbol keys");