mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 21:19:50 +01:00
b3ec13d449
This prohibits invalid values (< -1 and non-integers) and allows `filehandle.read()` to handle position up to `2n ** 63n - 1n` PR-URL: https://github.com/nodejs/node/pull/42835 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
94 lines
3.0 KiB
JavaScript
94 lines
3.0 KiB
JavaScript
import * as common from '../common/index.mjs';
|
|
import * as fixtures from '../common/fixtures.mjs';
|
|
import fs from 'fs';
|
|
import assert from 'assert';
|
|
|
|
// This test ensures that "position" argument is correctly validated
|
|
|
|
const filepath = fixtures.path('x.txt');
|
|
|
|
const buffer = Buffer.from('xyz\n');
|
|
const offset = 0;
|
|
const length = buffer.byteLength;
|
|
|
|
// allowedErrors is an array of acceptable internal errors
|
|
// For example, on some platforms read syscall might return -EFBIG or -EOVERFLOW
|
|
async function testValid(position, allowedErrors = []) {
|
|
return new Promise((resolve, reject) => {
|
|
fs.open(filepath, 'r', common.mustSucceed((fd) => {
|
|
let callCount = 3;
|
|
const handler = common.mustCall((err) => {
|
|
callCount--;
|
|
if (err && !allowedErrors.includes(err.code)) {
|
|
fs.close(fd, common.mustSucceed());
|
|
reject(err);
|
|
} else if (callCount === 0) {
|
|
fs.close(fd, common.mustSucceed(resolve));
|
|
}
|
|
}, callCount);
|
|
fs.read(fd, buffer, offset, length, position, handler);
|
|
fs.read(fd, { buffer, offset, length, position }, handler);
|
|
fs.read(fd, buffer, common.mustNotMutateObjectDeep({ offset, length, position }), handler);
|
|
}));
|
|
});
|
|
}
|
|
|
|
async function testInvalid(code, position) {
|
|
return new Promise((resolve, reject) => {
|
|
fs.open(filepath, 'r', common.mustSucceed((fd) => {
|
|
try {
|
|
assert.throws(
|
|
() => fs.read(fd, buffer, offset, length, position, common.mustNotCall()),
|
|
{ code }
|
|
);
|
|
assert.throws(
|
|
() => fs.read(fd, { buffer, offset, length, position }, common.mustNotCall()),
|
|
{ code }
|
|
);
|
|
assert.throws(
|
|
() => fs.read(fd, buffer, common.mustNotMutateObjectDeep({ offset, length, position }), common.mustNotCall()),
|
|
{ code }
|
|
);
|
|
resolve();
|
|
} catch (err) {
|
|
reject(err);
|
|
} finally {
|
|
fs.close(fd, common.mustSucceed());
|
|
}
|
|
}));
|
|
});
|
|
}
|
|
|
|
{
|
|
await testValid(undefined);
|
|
await testValid(null);
|
|
await testValid(-1);
|
|
await testValid(-1n);
|
|
|
|
await testValid(0);
|
|
await testValid(0n);
|
|
await testValid(1);
|
|
await testValid(1n);
|
|
await testValid(9);
|
|
await testValid(9n);
|
|
await testValid(Number.MAX_SAFE_INTEGER, [ 'EFBIG', 'EOVERFLOW' ]);
|
|
|
|
await testValid(2n ** 63n - 1n - BigInt(length), [ 'EFBIG', 'EOVERFLOW' ]);
|
|
await testInvalid('ERR_OUT_OF_RANGE', 2n ** 63n);
|
|
await testInvalid('ERR_OUT_OF_RANGE', 2n ** 63n - BigInt(length));
|
|
|
|
await testInvalid('ERR_OUT_OF_RANGE', NaN);
|
|
await testInvalid('ERR_OUT_OF_RANGE', -Infinity);
|
|
await testInvalid('ERR_OUT_OF_RANGE', Infinity);
|
|
await testInvalid('ERR_OUT_OF_RANGE', -0.999);
|
|
await testInvalid('ERR_OUT_OF_RANGE', -(2n ** 64n));
|
|
await testInvalid('ERR_OUT_OF_RANGE', Number.MAX_SAFE_INTEGER + 1);
|
|
await testInvalid('ERR_OUT_OF_RANGE', Number.MAX_VALUE);
|
|
|
|
for (const badTypeValue of [
|
|
false, true, '1', Symbol(1), {}, [], () => {}, Promise.resolve(1),
|
|
]) {
|
|
await testInvalid('ERR_INVALID_ARG_TYPE', badTypeValue);
|
|
}
|
|
}
|