1import * as common from '../common/index.mjs'; 2import * as fixtures from '../common/fixtures.mjs'; 3import fs from 'fs'; 4import assert from 'assert'; 5 6// This test ensures that "position" argument is correctly validated 7 8const filepath = fixtures.path('x.txt'); 9 10const buffer = Buffer.from('xyz\n'); 11const offset = 0; 12const length = buffer.byteLength; 13 14// allowedErrors is an array of acceptable internal errors 15// For example, on some platforms read syscall might return -EFBIG or -EOVERFLOW 16function testValid(position, allowedErrors = []) { 17 let fdSync; 18 try { 19 fdSync = fs.openSync(filepath, 'r'); 20 fs.readSync(fdSync, buffer, offset, length, position); 21 fs.readSync(fdSync, buffer, common.mustNotMutateObjectDeep({ offset, length, position })); 22 } catch (err) { 23 if (!allowedErrors.includes(err.code)) { 24 assert.fail(err); 25 } 26 } finally { 27 if (fdSync) fs.closeSync(fdSync); 28 } 29} 30 31function testInvalid(code, position, internalCatch = false) { 32 let fdSync; 33 try { 34 fdSync = fs.openSync(filepath, 'r'); 35 assert.throws( 36 () => fs.readSync(fdSync, buffer, offset, length, position), 37 { code } 38 ); 39 assert.throws( 40 () => fs.readSync(fdSync, buffer, common.mustNotMutateObjectDeep({ offset, length, position })), 41 { code } 42 ); 43 } finally { 44 if (fdSync) fs.closeSync(fdSync); 45 } 46} 47 48{ 49 testValid(undefined); 50 testValid(null); 51 testValid(-1); 52 testValid(-1n); 53 54 testValid(0); 55 testValid(0n); 56 testValid(1); 57 testValid(1n); 58 testValid(9); 59 testValid(9n); 60 testValid(Number.MAX_SAFE_INTEGER, [ 'EFBIG', 'EOVERFLOW' ]); 61 62 testValid(2n ** 63n - 1n - BigInt(length), [ 'EFBIG', 'EOVERFLOW' ]); 63 testInvalid('ERR_OUT_OF_RANGE', 2n ** 63n); 64 65 // TODO(LiviaMedeiros): test `2n ** 63n - BigInt(length)` 66 67 testInvalid('ERR_OUT_OF_RANGE', NaN); 68 testInvalid('ERR_OUT_OF_RANGE', -Infinity); 69 testInvalid('ERR_OUT_OF_RANGE', Infinity); 70 testInvalid('ERR_OUT_OF_RANGE', -0.999); 71 testInvalid('ERR_OUT_OF_RANGE', -(2n ** 64n)); 72 testInvalid('ERR_OUT_OF_RANGE', Number.MAX_SAFE_INTEGER + 1); 73 testInvalid('ERR_OUT_OF_RANGE', Number.MAX_VALUE); 74 75 for (const badTypeValue of [ 76 false, true, '1', Symbol(1), {}, [], () => {}, Promise.resolve(1), 77 ]) { 78 testInvalid('ERR_INVALID_ARG_TYPE', badTypeValue); 79 } 80} 81