tor-browser

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

string-charCodeAt-oob.js (3349B)


      1 // Test String.prototype.charCodeAt with out-of-bounds indices.
      2 
      3 function* characters(...ranges) {
      4  for (let [start, end] of ranges) {
      5    for (let i = start; i <= end; ++i) {
      6      yield i;
      7    }
      8  }
      9 }
     10 
     11 const empty = [];
     12 
     13 const ascii = [...characters(
     14  [0x41, 0x5A], // A..Z
     15  [0x61, 0x7A], // a..z
     16 )];
     17 
     18 const latin1 = [...characters(
     19  [0xC0, 0xFF], // À..ÿ
     20 )];
     21 
     22 const twoByte = [...characters(
     23  [0x100, 0x17E], // Ā..ž
     24 )];
     25 
     26 function atomize(s) {
     27  return Object.keys({[s]: 0})[0];
     28 }
     29 
     30 function codePoints() {
     31  return [empty, ascii, latin1, twoByte];
     32 }
     33 
     34 function toRope(s) {
     35  // Ropes have at least two characters.
     36  if (s.length < 2) {
     37    return s;
     38  }
     39  if (s.length === 2) {
     40    return newRope(s[0], s[1]);
     41  }
     42  return newRope(s[0], s.substring(1));
     43 }
     44 
     45 function makeStrings() {
     46  let strings = codePoints()
     47  .map(codePoints => String.fromCodePoint(...codePoints))
     48  .flatMap(x => [
     49    x,
     50    toRope(x),
     51    newString(x, {twoByte: true}),
     52    atomize(x),
     53  ]);
     54  return strings;
     55 }
     56 
     57 function testNegativeIndexConstant() {
     58  let strings = makeStrings();
     59  for (let i = 0; i < 200; ++i) {
     60    let str = strings[i % strings.length];
     61    let ch = str.charCodeAt(-1);
     62    assertEq(ch, NaN);
     63  }
     64 }
     65 for (let i = 0; i < 2; ++i) {
     66  testNegativeIndexConstant();
     67 }
     68 
     69 function testNegativeIndexVariable() {
     70  let indices = [-1, -2];
     71  let strings = makeStrings();
     72  for (let i = 0; i < 200; ++i) {
     73    let str = strings[i % strings.length];
     74    let ch = str.charCodeAt(indices[i & 1]);
     75    assertEq(ch, NaN);
     76  }
     77 }
     78 for (let i = 0; i < 2; ++i) {
     79  testNegativeIndexVariable();
     80 }
     81 
     82 function testNegativeOrValidIndex() {
     83  let indices = [-1, 0];
     84  let strings = makeStrings();
     85 
     86  // Number of string kinds created in makeStrings.
     87  const N = 4;
     88 
     89  let cpoints = codePoints();
     90  assertEq(strings.length, cpoints.length * N);
     91 
     92  for (let i = 0; i < 200; ++i) {
     93    let str = strings[i % strings.length];
     94    let index = indices[i & 1];
     95    let ch = str.charCodeAt(index);
     96 
     97    let cp = cpoints[Math.trunc((i % strings.length) / N)];
     98    assertEq(ch, (0 <= index && index < cp.length ? cp[index] : NaN));
     99  }
    100 }
    101 for (let i = 0; i < 2; ++i) {
    102  testNegativeOrValidIndex();
    103 }
    104 
    105 function testTooLargeIndexConstant() {
    106  let strings = makeStrings();
    107  for (let i = 0; i < 200; ++i) {
    108    let str = strings[i % strings.length];
    109    let ch = str.charCodeAt(1000);
    110    assertEq(ch, NaN);
    111  }
    112 }
    113 for (let i = 0; i < 2; ++i) {
    114  testTooLargeIndexConstant();
    115 }
    116 
    117 function testTooLargeIndexVariable() {
    118  let indices = [1000, 2000];
    119  let strings = makeStrings();
    120  for (let i = 0; i < 200; ++i) {
    121    let str = strings[i % strings.length];
    122    let ch = str.charCodeAt(indices[i & 1]);
    123    assertEq(ch, NaN);
    124  }
    125 }
    126 for (let i = 0; i < 2; ++i) {
    127  testTooLargeIndexVariable();
    128 }
    129 
    130 function testTooLargeOrValidIndex() {
    131  let indices = [1000, 0];
    132  let strings = makeStrings();
    133 
    134  // Number of string kinds created in makeStrings.
    135  const N = 4;
    136 
    137  let cpoints = codePoints();
    138  assertEq(strings.length, cpoints.length * N);
    139 
    140  for (let i = 0; i < 200; ++i) {
    141    let str = strings[i % strings.length];
    142    let index = indices[i & 1];
    143    let ch = str.charCodeAt(index);
    144 
    145    let cp = cpoints[Math.trunc((i % strings.length) / N)];
    146    assertEq(ch, (0 <= index && index < cp.length ? cp[index] : NaN));
    147  }
    148 }
    149 for (let i = 0; i < 2; ++i) {
    150  testTooLargeOrValidIndex();
    151 }