Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLivia Medeiros <74449973+LiviaMedeiros@users.noreply.github.com>2022-05-02 20:52:43 +0300
committerGitHub <noreply@github.com>2022-05-02 20:52:43 +0300
commit6be94c9443c890cd5706cfa6508c4c00e06dfe9e (patch)
tree8789a80f7ff48d4e3649787c0ed19cd2d7f2c62f /test
parent916a13a8a36debd9c9ce393bf1edd543ee75d449 (diff)
test: add test for position validation in fs.read() and fs.readSync()
PR-URL: https://github.com/nodejs/node/pull/42837 Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Diffstat (limited to 'test')
-rw-r--r--test/parallel/test-fs-read-position-validation.mjs133
1 files changed, 133 insertions, 0 deletions
diff --git a/test/parallel/test-fs-read-position-validation.mjs b/test/parallel/test-fs-read-position-validation.mjs
new file mode 100644
index 00000000000..bbd4e9ab417
--- /dev/null
+++ b/test/parallel/test-fs-read-position-validation.mjs
@@ -0,0 +1,133 @@
+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
+async function testValid(position, allowedErrors = []) {
+ let fdSync;
+ try {
+ fdSync = fs.openSync(filepath, 'r');
+ fs.readSync(fdSync, buffer, offset, length, position);
+ fs.readSync(fdSync, buffer, { offset, length, position });
+ } catch (err) {
+ if (!allowedErrors.includes(err.code)) {
+ assert.fail(err);
+ }
+ } finally {
+ if (fdSync) fs.closeSync(fdSync);
+ }
+
+ fs.open(filepath, 'r', common.mustSucceed((fd) => {
+ try {
+ if (allowedErrors.length) {
+ fs.read(fd, buffer, offset, length, position, common.mustCall((err, ...results) => {
+ if (err && !allowedErrors.includes(err.code)) {
+ assert.fail(err);
+ }
+ }));
+ fs.read(fd, { buffer, offset, length, position }, common.mustCall((err, ...results) => {
+ if (err && !allowedErrors.includes(err.code)) {
+ assert.fail(err);
+ }
+ }));
+ } else {
+ fs.read(fd, buffer, offset, length, position, common.mustSucceed());
+ fs.read(fd, { buffer, offset, length, position }, common.mustSucceed());
+ }
+ } finally {
+ fs.close(fd, common.mustSucceed());
+ }
+ }));
+}
+
+async function testInvalid(code, position, internalCatch = false) {
+ let fdSync;
+ try {
+ fdSync = fs.openSync(filepath, 'r');
+ assert.throws(
+ () => fs.readSync(fdSync, buffer, offset, length, position),
+ { code }
+ );
+ assert.throws(
+ () => fs.readSync(fdSync, buffer, { offset, length, position }),
+ { code }
+ );
+ } finally {
+ if (fdSync) fs.closeSync(fdSync);
+ }
+
+ // Set this flag for catching errors via first argument of callback function
+ if (internalCatch) {
+ fs.open(filepath, 'r', common.mustSucceed((fd) => {
+ try {
+ fs.read(fd, buffer, offset, length, position, (err, ...results) => {
+ assert.strictEqual(err.code, code);
+ });
+ fs.read(fd, { buffer, offset, length, position }, (err, ...results) => {
+ assert.strictEqual(err.code, code);
+ });
+ } finally {
+ fs.close(fd, common.mustSucceed());
+ }
+ }));
+ } else {
+ 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 }
+ );
+ } 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' ]);
+
+ await testValid(2n ** 63n - 1n - BigInt(length), [ 'EFBIG' ]);
+ await testInvalid('ERR_OUT_OF_RANGE', 2n ** 63n);
+
+ // TODO(LiviaMedeiros): test `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);
+ }
+}