tor-browser

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

bad-buffers-and-views.any.js (12909B)


      1 // META: global=window,worker,shadowrealm
      2 'use strict';
      3 
      4 promise_test(() => {
      5  const stream = new ReadableStream({
      6    start(c) {
      7      c.close();
      8    },
      9    type: 'bytes'
     10  });
     11 
     12  const reader = stream.getReader({ mode: 'byob' });
     13  const view = new Uint8Array([1, 2, 3]);
     14  return reader.read(view).then(({ value, done }) => {
     15    // Sanity checks
     16    assert_true(value instanceof Uint8Array, 'The value read must be a Uint8Array');
     17    assert_not_equals(value, view, 'The value read must not be the *same* Uint8Array');
     18    assert_array_equals(value, [], 'The value read must be an empty Uint8Array, since the stream is closed');
     19    assert_true(done, 'done must be true, since the stream is closed');
     20 
     21    // The important assertions
     22    assert_not_equals(value.buffer, view.buffer, 'a different ArrayBuffer must underlie the value');
     23    assert_equals(view.buffer.byteLength, 0, 'the original buffer must be detached');
     24  });
     25 }, 'ReadableStream with byte source: read()ing from a closed stream still transfers the buffer');
     26 
     27 promise_test(() => {
     28  const stream = new ReadableStream({
     29    start(c) {
     30      c.enqueue(new Uint8Array([1, 2, 3]));
     31    },
     32    type: 'bytes'
     33  });
     34 
     35  const reader = stream.getReader({ mode: 'byob' });
     36  const view = new Uint8Array([4, 5, 6]);
     37  return reader.read(view).then(({ value, done }) => {
     38    // Sanity checks
     39    assert_true(value instanceof Uint8Array, 'The value read must be a Uint8Array');
     40    assert_not_equals(value, view, 'The value read must not be the *same* Uint8Array');
     41    assert_array_equals(value, [1, 2, 3], 'The value read must be the enqueued Uint8Array, not the original values');
     42    assert_false(done, 'done must be false, since the stream is not closed');
     43 
     44    // The important assertions
     45    assert_not_equals(value.buffer, view.buffer, 'a different ArrayBuffer must underlie the value');
     46    assert_equals(view.buffer.byteLength, 0, 'the original buffer must be detached');
     47  });
     48 }, 'ReadableStream with byte source: read()ing from a stream with queued chunks still transfers the buffer');
     49 
     50 test(() => {
     51  new ReadableStream({
     52    start(c) {
     53      const view = new Uint8Array([1, 2, 3]);
     54      c.enqueue(view);
     55      assert_throws_js(TypeError, () => c.enqueue(view));
     56    },
     57    type: 'bytes'
     58  });
     59 }, 'ReadableStream with byte source: enqueuing an already-detached buffer throws');
     60 
     61 test(() => {
     62  new ReadableStream({
     63    start(c) {
     64      const view = new Uint8Array([]);
     65      assert_throws_js(TypeError, () => c.enqueue(view));
     66    },
     67    type: 'bytes'
     68  });
     69 }, 'ReadableStream with byte source: enqueuing a zero-length buffer throws');
     70 
     71 test(() => {
     72  new ReadableStream({
     73    start(c) {
     74      const view = new Uint8Array(new ArrayBuffer(10), 0, 0);
     75      assert_throws_js(TypeError, () => c.enqueue(view));
     76    },
     77    type: 'bytes'
     78  });
     79 }, 'ReadableStream with byte source: enqueuing a zero-length view on a non-zero-length buffer throws');
     80 
     81 promise_test(t => {
     82  const stream = new ReadableStream({
     83    start(c) {
     84      c.enqueue(new Uint8Array([1, 2, 3]));
     85    },
     86    type: 'bytes'
     87  });
     88  const reader = stream.getReader({ mode: 'byob' });
     89 
     90  const view = new Uint8Array([4, 5, 6]);
     91  return reader.read(view).then(() => {
     92    // view is now detached
     93    return promise_rejects_js(t, TypeError, reader.read(view));
     94  });
     95 }, 'ReadableStream with byte source: reading into an already-detached buffer rejects');
     96 
     97 promise_test(t => {
     98  const stream = new ReadableStream({
     99    start(c) {
    100      c.enqueue(new Uint8Array([1, 2, 3]));
    101    },
    102    type: 'bytes'
    103  });
    104  const reader = stream.getReader({ mode: 'byob' });
    105 
    106  const view = new Uint8Array();
    107  return promise_rejects_js(t, TypeError, reader.read(view));
    108 }, 'ReadableStream with byte source: reading into a zero-length buffer rejects');
    109 
    110 promise_test(t => {
    111  const stream = new ReadableStream({
    112    start(c) {
    113      c.enqueue(new Uint8Array([1, 2, 3]));
    114    },
    115    type: 'bytes'
    116  });
    117  const reader = stream.getReader({ mode: 'byob' });
    118 
    119  const view = new Uint8Array(new ArrayBuffer(10), 0, 0);
    120  return promise_rejects_js(t, TypeError, reader.read(view));
    121 }, 'ReadableStream with byte source: reading into a zero-length view on a non-zero-length buffer rejects');
    122 
    123 async_test(t => {
    124  const stream = new ReadableStream({
    125    pull: t.step_func_done(c => {
    126      c.byobRequest.view.buffer.transfer();
    127 
    128      assert_throws_js(TypeError, () => c.byobRequest.respond(1),
    129        'respond() must throw if the corresponding view has become detached');
    130    }),
    131    type: 'bytes'
    132  });
    133  const reader = stream.getReader({ mode: 'byob' });
    134 
    135  reader.read(new Uint8Array([4, 5, 6]));
    136 }, 'ReadableStream with byte source: respond() throws if the BYOB request\'s buffer has been detached (in the ' +
    137   'readable state)');
    138 
    139 async_test(t => {
    140  const stream = new ReadableStream({
    141    pull: t.step_func_done(c => {
    142      c.close();
    143      c.byobRequest.view.buffer.transfer();
    144 
    145      assert_throws_js(TypeError, () => c.byobRequest.respond(0),
    146        'respond() must throw if the corresponding view has become detached');
    147    }),
    148    type: 'bytes'
    149  });
    150  const reader = stream.getReader({ mode: 'byob' });
    151 
    152  reader.read(new Uint8Array([4, 5, 6]));
    153 }, 'ReadableStream with byte source: respond() throws if the BYOB request\'s buffer has been detached (in the ' +
    154   'closed state)');
    155 
    156 async_test(t => {
    157  const stream = new ReadableStream({
    158    pull: t.step_func_done(c => {
    159      const view = new Uint8Array([1, 2, 3]);
    160      view.buffer.transfer();
    161 
    162      assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view));
    163    }),
    164    type: 'bytes'
    165  });
    166  const reader = stream.getReader({ mode: 'byob' });
    167 
    168  reader.read(new Uint8Array([4, 5, 6]));
    169 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has been detached ' +
    170    '(in the readable state)');
    171 
    172 async_test(t => {
    173  const stream = new ReadableStream({
    174    pull: t.step_func_done(c => {
    175      const view = new Uint8Array();
    176 
    177      assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view));
    178    }),
    179    type: 'bytes'
    180  });
    181  const reader = stream.getReader({ mode: 'byob' });
    182 
    183  reader.read(new Uint8Array([4, 5, 6]));
    184 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer is zero-length ' +
    185    '(in the readable state)');
    186 
    187 async_test(t => {
    188  const stream = new ReadableStream({
    189    pull: t.step_func_done(c => {
    190      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 0);
    191 
    192      assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view));
    193    }),
    194    type: 'bytes'
    195  });
    196  const reader = stream.getReader({ mode: 'byob' });
    197 
    198  reader.read(new Uint8Array([4, 5, 6]));
    199 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a ' +
    200    'non-zero-length buffer (in the readable state)');
    201 
    202 async_test(t => {
    203  const stream = new ReadableStream({
    204    pull: t.step_func_done(c => {
    205      const view = c.byobRequest.view.subarray(1, 2);
    206 
    207      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
    208    }),
    209    type: 'bytes'
    210  });
    211  const reader = stream.getReader({ mode: 'byob' });
    212 
    213  reader.read(new Uint8Array([4, 5, 6]));
    214 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset ' +
    215   '(in the readable state)');
    216 
    217 async_test(t => {
    218  const stream = new ReadableStream({
    219    pull: t.step_func_done(c => {
    220      c.close();
    221 
    222      const view = c.byobRequest.view.subarray(1, 1);
    223 
    224      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
    225    }),
    226    type: 'bytes'
    227  });
    228  const reader = stream.getReader({ mode: 'byob' });
    229 
    230  reader.read(new Uint8Array([4, 5, 6]));
    231 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset ' +
    232   '(in the closed state)');
    233 
    234 async_test(t => {
    235  const stream = new ReadableStream({
    236    pull: t.step_func_done(c => {
    237      const view = new Uint8Array(new ArrayBuffer(10), 0, 3);
    238 
    239      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
    240    }),
    241    type: 'bytes'
    242  });
    243  const reader = stream.getReader({ mode: 'byob' });
    244 
    245  reader.read(new Uint8Array([4, 5, 6]));
    246 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has a ' +
    247   'different length (in the readable state)');
    248 
    249 async_test(t => {
    250  // Tests https://github.com/nodejs/node/issues/41886
    251  const stream = new ReadableStream({
    252    pull: t.step_func_done(c => {
    253      const view = new Uint8Array(new ArrayBuffer(11), 0, 3);
    254 
    255      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
    256    }),
    257    type: 'bytes',
    258    autoAllocateChunkSize: 10
    259  });
    260  const reader = stream.getReader();
    261 
    262  reader.read();
    263 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has a ' +
    264   'different length (autoAllocateChunkSize)');
    265 
    266 async_test(t => {
    267  const stream = new ReadableStream({
    268    pull: t.step_func_done(c => {
    269      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 4);
    270      view[0] = 20;
    271      view[1] = 21;
    272      view[2] = 22;
    273      view[3] = 23;
    274 
    275      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
    276    }),
    277    type: 'bytes'
    278  });
    279  const reader = stream.getReader({ mode: 'byob' });
    280 
    281  const buffer = new ArrayBuffer(10);
    282  const view = new Uint8Array(buffer, 0, 3);
    283  view[0] = 10;
    284  view[1] = 11;
    285  view[2] = 12;
    286  reader.read(view);
    287 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a larger length ' +
    288   '(in the readable state)');
    289 
    290 async_test(t => {
    291  const stream = new ReadableStream({
    292    pull: t.step_func_done(c => {
    293      c.close();
    294 
    295      // Detach it by reading into it
    296      const view = new Uint8Array([1, 2, 3]);
    297      reader.read(view);
    298 
    299      assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view));
    300    }),
    301    type: 'bytes'
    302  });
    303  const reader = stream.getReader({ mode: 'byob' });
    304 
    305  reader.read(new Uint8Array([4, 5, 6]));
    306 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has been detached ' +
    307   '(in the closed state)');
    308 
    309 async_test(t => {
    310  const stream = new ReadableStream({
    311    pull: t.step_func_done(c => {
    312      const view = new Uint8Array();
    313 
    314      c.close();
    315 
    316      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
    317    }),
    318    type: 'bytes'
    319  });
    320  const reader = stream.getReader({ mode: 'byob' });
    321 
    322  reader.read(new Uint8Array([4, 5, 6]));
    323 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer is zero-length ' +
    324   '(in the closed state)');
    325 
    326 async_test(t => {
    327  const stream = new ReadableStream({
    328    pull: t.step_func_done(c => {
    329      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 1);
    330 
    331      c.close();
    332 
    333      assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view));
    334    }),
    335    type: 'bytes'
    336  });
    337  const reader = stream.getReader({ mode: 'byob' });
    338 
    339  reader.read(new Uint8Array([4, 5, 6]));
    340 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view is non-zero-length ' +
    341   '(in the closed state)');
    342 
    343 async_test(t => {
    344  const stream = new ReadableStream({
    345    pull: t.step_func_done(c => {
    346      const view = new Uint8Array(new ArrayBuffer(10), 0, 0);
    347 
    348      c.close();
    349 
    350      assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view));
    351    }),
    352    type: 'bytes'
    353  });
    354  const reader = stream.getReader({ mode: 'byob' });
    355 
    356  reader.read(new Uint8Array([4, 5, 6]));
    357 }, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has a ' +
    358   'different length (in the closed state)');
    359 
    360 async_test(t => {
    361  const stream = new ReadableStream({
    362    pull: t.step_func_done(c => {
    363      c.byobRequest.view.buffer.transfer();
    364 
    365      assert_throws_js(TypeError, () => c.enqueue(new Uint8Array([1])),
    366        'enqueue() must throw if the BYOB request\'s buffer has become detached');
    367    }),
    368    type: 'bytes'
    369  });
    370  const reader = stream.getReader({ mode: 'byob' });
    371 
    372  reader.read(new Uint8Array([4, 5, 6]));
    373 }, 'ReadableStream with byte source: enqueue() throws if the BYOB request\'s buffer has been detached (in the ' +
    374  'readable state)');
    375 
    376 async_test(t => {
    377  const stream = new ReadableStream({
    378    pull: t.step_func_done(c => {
    379      c.close();
    380      c.byobRequest.view.buffer.transfer();
    381 
    382      assert_throws_js(TypeError, () => c.enqueue(new Uint8Array([1])),
    383        'enqueue() must throw if the BYOB request\'s buffer has become detached');
    384    }),
    385    type: 'bytes'
    386  });
    387  const reader = stream.getReader({ mode: 'byob' });
    388 
    389  reader.read(new Uint8Array([4, 5, 6]));
    390 }, 'ReadableStream with byte source: enqueue() throws if the BYOB request\'s buffer has been detached (in the ' +
    391  'closed state)');