tor-browser

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

big-arrays.js (7040B)


      1 // |jit-test| slow; allow-oom; skip-if: getBuildConfiguration("simulator")
      2 
      3 //////////////////////////////////////////////////////////////////////////////
      4 //
      5 // Checks for requests for oversize arrays (more than MaxArrayPayloadBytes),
      6 // where MaxArrayPayloadBytes == 1,987,654,321.
      7 
      8 const MaxArrayPayloadBytes = 1987654321;
      9 
     10 function maxNumElementsForSize(bytes, elemSize) {
     11  let n = bytes;
     12  n = bytes & ~0b111; // round down to nearest multiple of gc::CellAlignSize
     13  n -= getBuildConfiguration()['pointer-byte-size']; // subtract size of data header
     14  n = Math.floor(n / elemSize); // divide by elemSize and round down
     15  return n;
     16 }
     17 
     18 // // Test code for maxNumElementsForSize
     19 // for (const bytes of [32, 33, 112]) {
     20 //   for (const size of [1, 2, 4, 8, 16]) {
     21 //     print(bytes, size, "->", maxNumElementsForSize(bytes, size));
     22 //   }
     23 // }
     24 // throw "see above";
     25 
     26 // array.new
     27 {
     28  const { test1, test2, test4, test8, test16 } = wasmEvalText(`(module
     29    (type $1 (array i8))
     30    (type $2 (array i16))
     31    (type $4 (array i32))
     32    (type $8 (array i64))
     33    ${wasmSimdEnabled() ? `
     34      (type $16 (array v128))
     35    ` : ""}
     36    (func (export "test1") (param i32) (result eqref)
     37      (array.new $1 (i32.const 0xAB) (local.get 0))
     38    )
     39    (func (export "test2") (param i32) (result eqref)
     40      (array.new $2 (i32.const 0xCD) (local.get 0))
     41    )
     42    (func (export "test4") (param i32) (result eqref)
     43      (array.new $4 (i32.const 0xABCD1234) (local.get 0))
     44    )
     45    (func (export "test8") (param i32) (result eqref)
     46      (array.new $8 (i64.const 0xABCD1234) (local.get 0))
     47    )
     48    ${wasmSimdEnabled() ? `
     49      (func (export "test16") (param i32) (result eqref)
     50        (array.new $16 (v128.const i64x2 0xABCD1234 0xABCD1234) (local.get 0))
     51      )
     52    ` : ""}
     53  )`).exports;
     54 
     55  const tests = [[1, test1], [2, test2], [4, test4], [8, test8]];
     56  if (wasmSimdEnabled()) {
     57    tests.push([16, test16]);
     58  }
     59  for (const [size, test] of tests) {
     60    for (const doMasm of [false, true]) {
     61      if (doMasm) {
     62        // Prime the alloc site with a successful allocation so we hit masm from here on out
     63        test(0);
     64      }
     65 
     66      // Test boundaries of implementation limit
     67      const maxNumElements = maxNumElementsForSize(MaxArrayPayloadBytes, size);
     68      test(maxNumElements);
     69      assertErrorMessage(() => test(maxNumElements + 1), WebAssembly.RuntimeError, /too many array elements/);
     70 
     71      // Test around signed overflow boundary
     72      for (let i = -16; i <= 16; i++) {
     73        assertErrorMessage(
     74          () => test(maxNumElementsForSize(Math.pow(2, 31) + i, size)),
     75          WebAssembly.RuntimeError,
     76          /too many array elements/,
     77        );
     78      }
     79 
     80      // Test around unsigned overflow boundary
     81      for (let i = -16; i <= -1; i++) {
     82        assertErrorMessage(() => test(i), WebAssembly.RuntimeError, /too many array elements/);
     83      }
     84    }
     85  }
     86 }
     87 
     88 // array.new_default
     89 {
     90  const { test1, test2, test4, test8, test16 } = wasmEvalText(`(module
     91    (type $1 (array i8))
     92    (type $2 (array i16))
     93    (type $4 (array i32))
     94    (type $8 (array i64))
     95    ${wasmSimdEnabled() ? `
     96      (type $16 (array v128))
     97    ` : ""}
     98    (func (export "test1") (param i32) (result eqref)
     99      (array.new_default $1 (local.get 0))
    100    )
    101    (func (export "test2") (param i32) (result eqref)
    102      (array.new_default $2 (local.get 0))
    103    )
    104    (func (export "test4") (param i32) (result eqref)
    105      (array.new_default $4 (local.get 0))
    106    )
    107    (func (export "test8") (param i32) (result eqref)
    108      (array.new_default $8 (local.get 0))
    109    )
    110    ${wasmSimdEnabled() ? `
    111      (func (export "test16") (param i32) (result eqref)
    112        (array.new_default $16 (local.get 0))
    113      )
    114    ` : ""}
    115  )`).exports;
    116 
    117  const tests = [[1, test1], [2, test2], [4, test4], [8, test8]];
    118  if (wasmSimdEnabled()) {
    119    tests.push([16, test16]);
    120  }
    121  for (const [size, test] of tests) {
    122    for (const doMasm of [false, true]) {
    123      if (doMasm) {
    124        // Prime the alloc site with a successful allocation so we hit masm from here on out
    125        test(0);
    126      }
    127 
    128      // Test boundaries of implementation limit
    129      const maxNumElements = maxNumElementsForSize(MaxArrayPayloadBytes, size);
    130      test(maxNumElements);
    131      assertErrorMessage(() => test(maxNumElements + 1), WebAssembly.RuntimeError, /too many array elements/);
    132 
    133      // Test around signed overflow boundary
    134      for (let i = -16; i <= 16; i++) {
    135        assertErrorMessage(
    136          () => test(maxNumElementsForSize(Math.pow(2, 31) + i, size)),
    137          WebAssembly.RuntimeError,
    138          /too many array elements/,
    139        );
    140      }
    141 
    142      // Test around unsigned overflow boundary
    143      for (let i = -16; i <= -1; i++) {
    144        assertErrorMessage(() => test(i), WebAssembly.RuntimeError, /too many array elements/);
    145      }
    146    }
    147  }
    148 }
    149 
    150 // array.new_fixed
    151 {
    152  assertErrorMessage(() => wasmEvalText(`(module
    153    (type $a (array i8))
    154    (func (result (ref $a))
    155      array.new_fixed $a 10001
    156    )
    157  )`), WebAssembly.CompileError, /too many array.new_fixed elements/);
    158  assertErrorMessage(() => wasmEvalText(`(module
    159    (type $a (array f32))
    160    (func (result (ref $a))
    161      array.new_fixed $a 10001
    162    )
    163  )`), WebAssembly.CompileError, /too many array.new_fixed elements/);
    164  assertErrorMessage(() => wasmEvalText(`(module
    165    (type $a (array f32))
    166    (func (result (ref $a))
    167      array.new_fixed $a 2147483647
    168    )
    169  )`), WebAssembly.CompileError, /too many array.new_fixed elements/);
    170  assertErrorMessage(() => wasmEvalText(`(module
    171    (type $a (array i8))
    172    (func (result (ref $a))
    173      array.new_fixed $a 4294967295
    174    )
    175  )`), WebAssembly.CompileError, /too many array.new_fixed elements/);
    176 }
    177 
    178 // array.new (constant length)
    179 {
    180  const { testA, testB, testC, testD } = wasmEvalText(`(module
    181    (type $a (array f32))
    182    (type $b (array i8))
    183 
    184    (func (export "testA") (result (ref $a))
    185      (array.new $a (f32.const 0) (i32.const 2147483647))
    186    )
    187    (func (export "testB") (result (ref $b))
    188      ;; overflows due to size of data header
    189      (array.new $b (i32.const 0) (i32.const 4294967295))
    190    )
    191    (func (export "testC") (result (ref $a))
    192      (array.new $a (f32.const 0) (i32.const -1))
    193    )
    194    (func (export "testD") (result (ref $b))
    195      (array.new $b (i32.const 0) (i32.const -1))
    196    )
    197  )`).exports;
    198  assertErrorMessage(() => testA(), WebAssembly.RuntimeError, /too many array elements/);
    199  assertErrorMessage(() => testB(), WebAssembly.RuntimeError, /too many array elements/);
    200  assertErrorMessage(() => testC(), WebAssembly.RuntimeError, /too many array elements/);
    201  assertErrorMessage(() => testD(), WebAssembly.RuntimeError, /too many array elements/);
    202 }
    203 
    204 // array.new_data
    205 // Impossible to test because the max data segment length is 1GB
    206 // (1,073,741,824 bytes) (MaxDataSegmentLengthPages * PageSize), which is less
    207 // than MaxArrayPayloadBytes.
    208 
    209 // array.new_element
    210 // Similarly, impossible to test because an element segment can contain at
    211 // most 10,000,000 (MaxElemSegmentLength) entries.