11cb0ef41Sopenharmony_ciimport * as common from '../common/index.mjs'; 21cb0ef41Sopenharmony_ciimport * as fixtures from '../common/fixtures.mjs'; 31cb0ef41Sopenharmony_ciimport fs from 'fs'; 41cb0ef41Sopenharmony_ciimport assert from 'assert'; 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci// This test ensures that "position" argument is correctly validated 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst filepath = fixtures.path('x.txt'); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst buffer = Buffer.from('xyz\n'); 111cb0ef41Sopenharmony_ciconst offset = 0; 121cb0ef41Sopenharmony_ciconst length = buffer.byteLength; 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci// allowedErrors is an array of acceptable internal errors 151cb0ef41Sopenharmony_ci// For example, on some platforms read syscall might return -EFBIG or -EOVERFLOW 161cb0ef41Sopenharmony_ciasync function testValid(position, allowedErrors = []) { 171cb0ef41Sopenharmony_ci return new Promise((resolve, reject) => { 181cb0ef41Sopenharmony_ci fs.open(filepath, 'r', common.mustSucceed((fd) => { 191cb0ef41Sopenharmony_ci let callCount = 3; 201cb0ef41Sopenharmony_ci const handler = common.mustCall((err) => { 211cb0ef41Sopenharmony_ci callCount--; 221cb0ef41Sopenharmony_ci if (err && !allowedErrors.includes(err.code)) { 231cb0ef41Sopenharmony_ci fs.close(fd, common.mustSucceed()); 241cb0ef41Sopenharmony_ci reject(err); 251cb0ef41Sopenharmony_ci } else if (callCount === 0) { 261cb0ef41Sopenharmony_ci fs.close(fd, common.mustSucceed(resolve)); 271cb0ef41Sopenharmony_ci } 281cb0ef41Sopenharmony_ci }, callCount); 291cb0ef41Sopenharmony_ci fs.read(fd, buffer, offset, length, position, handler); 301cb0ef41Sopenharmony_ci fs.read(fd, { buffer, offset, length, position }, handler); 311cb0ef41Sopenharmony_ci fs.read(fd, buffer, common.mustNotMutateObjectDeep({ offset, length, position }), handler); 321cb0ef41Sopenharmony_ci })); 331cb0ef41Sopenharmony_ci }); 341cb0ef41Sopenharmony_ci} 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ciasync function testInvalid(code, position) { 371cb0ef41Sopenharmony_ci return new Promise((resolve, reject) => { 381cb0ef41Sopenharmony_ci fs.open(filepath, 'r', common.mustSucceed((fd) => { 391cb0ef41Sopenharmony_ci try { 401cb0ef41Sopenharmony_ci assert.throws( 411cb0ef41Sopenharmony_ci () => fs.read(fd, buffer, offset, length, position, common.mustNotCall()), 421cb0ef41Sopenharmony_ci { code } 431cb0ef41Sopenharmony_ci ); 441cb0ef41Sopenharmony_ci assert.throws( 451cb0ef41Sopenharmony_ci () => fs.read(fd, { buffer, offset, length, position }, common.mustNotCall()), 461cb0ef41Sopenharmony_ci { code } 471cb0ef41Sopenharmony_ci ); 481cb0ef41Sopenharmony_ci assert.throws( 491cb0ef41Sopenharmony_ci () => fs.read(fd, buffer, common.mustNotMutateObjectDeep({ offset, length, position }), common.mustNotCall()), 501cb0ef41Sopenharmony_ci { code } 511cb0ef41Sopenharmony_ci ); 521cb0ef41Sopenharmony_ci resolve(); 531cb0ef41Sopenharmony_ci } catch (err) { 541cb0ef41Sopenharmony_ci reject(err); 551cb0ef41Sopenharmony_ci } finally { 561cb0ef41Sopenharmony_ci fs.close(fd, common.mustSucceed()); 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci })); 591cb0ef41Sopenharmony_ci }); 601cb0ef41Sopenharmony_ci} 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci{ 631cb0ef41Sopenharmony_ci await testValid(undefined); 641cb0ef41Sopenharmony_ci await testValid(null); 651cb0ef41Sopenharmony_ci await testValid(-1); 661cb0ef41Sopenharmony_ci await testValid(-1n); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci await testValid(0); 691cb0ef41Sopenharmony_ci await testValid(0n); 701cb0ef41Sopenharmony_ci await testValid(1); 711cb0ef41Sopenharmony_ci await testValid(1n); 721cb0ef41Sopenharmony_ci await testValid(9); 731cb0ef41Sopenharmony_ci await testValid(9n); 741cb0ef41Sopenharmony_ci await testValid(Number.MAX_SAFE_INTEGER, [ 'EFBIG', 'EOVERFLOW' ]); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci await testValid(2n ** 63n - 1n - BigInt(length), [ 'EFBIG', 'EOVERFLOW' ]); 771cb0ef41Sopenharmony_ci await testInvalid('ERR_OUT_OF_RANGE', 2n ** 63n); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci // TODO(LiviaMedeiros): test `2n ** 63n - BigInt(length)` 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci await testInvalid('ERR_OUT_OF_RANGE', NaN); 821cb0ef41Sopenharmony_ci await testInvalid('ERR_OUT_OF_RANGE', -Infinity); 831cb0ef41Sopenharmony_ci await testInvalid('ERR_OUT_OF_RANGE', Infinity); 841cb0ef41Sopenharmony_ci await testInvalid('ERR_OUT_OF_RANGE', -0.999); 851cb0ef41Sopenharmony_ci await testInvalid('ERR_OUT_OF_RANGE', -(2n ** 64n)); 861cb0ef41Sopenharmony_ci await testInvalid('ERR_OUT_OF_RANGE', Number.MAX_SAFE_INTEGER + 1); 871cb0ef41Sopenharmony_ci await testInvalid('ERR_OUT_OF_RANGE', Number.MAX_VALUE); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci for (const badTypeValue of [ 901cb0ef41Sopenharmony_ci false, true, '1', Symbol(1), {}, [], () => {}, Promise.resolve(1), 911cb0ef41Sopenharmony_ci ]) { 921cb0ef41Sopenharmony_ci await testInvalid('ERR_INVALID_ARG_TYPE', badTypeValue); 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci} 95