out-of-bounds-access.js (1759B)
1 // Out-of-bounds accesses are detected when inlining DataView. 2 3 function testRead() { 4 const xs = [0x11_22_33_44, 0x55_66_77_88]; 5 6 let dv = new DataView(new ArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2)); 7 dv.setInt32(0 * Int32Array.BYTES_PER_ELEMENT, xs[0], true); 8 dv.setInt32(1 * Int32Array.BYTES_PER_ELEMENT, xs[1], true); 9 10 function f(dv, q) { 11 for (let i = 0; i <= 1000; ++i) { 12 // Perform an out-of-bounds read in the last iteration. 13 let k = (i & 1) * Int32Array.BYTES_PER_ELEMENT + (i === 1000 && q == 2 ? 7 : 0); 14 15 let v = dv.getInt32(k, true); 16 assertEq(v, xs[i & 1]); 17 } 18 } 19 20 try { 21 for (var i = 0; i <= 2; ++i) { 22 f(dv, i); 23 } 24 } catch (e) { 25 assertEq(e instanceof RangeError, true, e.message); 26 assertEq(i, 2); 27 } 28 } 29 testRead(); 30 31 function testWrite() { 32 const xs = [0x11_22_33_44, 0x55_66_77_88]; 33 34 let dv = new DataView(new ArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2)); 35 let ui8 = new Uint8Array(dv.buffer); 36 37 function f(dv, q) { 38 for (let i = 0; i <= 1000; ++i) { 39 // Perform an out-of-bounds read in the last iteration. 40 let k = (i & 1) * Int32Array.BYTES_PER_ELEMENT + (i === 1000 && q == 2 ? 7 : 0); 41 let x = xs[i & 1]; 42 43 dv.setInt32(k, x); 44 45 assertEq(ui8[0 + (i & 1) * Int32Array.BYTES_PER_ELEMENT], (x >> 24) & 0xff); 46 assertEq(ui8[1 + (i & 1) * Int32Array.BYTES_PER_ELEMENT], (x >> 16) & 0xff); 47 assertEq(ui8[2 + (i & 1) * Int32Array.BYTES_PER_ELEMENT], (x >> 8) & 0xff); 48 assertEq(ui8[3 + (i & 1) * Int32Array.BYTES_PER_ELEMENT], (x >> 0) & 0xff); 49 } 50 } 51 52 try { 53 for (var i = 0; i <= 2; ++i) { 54 f(dv, i); 55 } 56 } catch (e) { 57 assertEq(e instanceof RangeError, true, e.message); 58 assertEq(i, 2); 59 } 60 } 61 testWrite();