Skip to content

vfs: mounted fs.readSync(fd, ..., null) treats position as -1 and throws #64162

Description

@trivikr

Version

main

Platform

macOS 26.5.0

Subsystem

vfs

What steps will reproduce the bug?

import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import vfs from 'node:vfs';

const mountPoint = fs.mkdtempSync(path.join(os.tmpdir(), 'vfs-mount-'));
const mounted = vfs
  .create({ emitExperimentalWarning: false })
  .mount(mountPoint);

try {
  const file = path.join(mountPoint, 'file.txt');

  fs.writeFileSync(file, 'abcdef');

  const fd = fs.openSync(file, 'r');
  const buffer = Buffer.alloc(2);

  try {
    const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, null);
    console.log('bytesRead:', bytesRead);
    console.log('buffer:', buffer.toString());
  } finally {
    fs.closeSync(fd);
  }
} finally {
  mounted.unmount();
  fs.rmSync(mountPoint, { recursive: true, force: true });
}

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

bytesRead: 2
buffer: ab

In fs.readSync, position: null means read from and advance the descriptor’s current file position, so VFS should translate the internal sentinel back to “no explicit position.”

What do you see instead?

node:buffer:253
      throw new ERR_OUT_OF_RANGE('sourceStart', `>= 0 && <= ${source.byteLength}`, sourceStart);
            ^

RangeError [ERR_OUT_OF_RANGE]: The value of "sourceStart" is out of range. It must be >= 0 && <= 6. Received -1
    at copyImpl (node:buffer:253:13)
    at Buffer.copy (node:buffer:894:12)
    at MemoryFileHandle.readSync (node:internal/vfs/file_handle:479:13)
    at Object.readSync (node:internal/vfs/setup:360:33)
    at Object.readSync (node:fs:892:22)
    at file:///Users/trivikram/workspace/test-repro/repro.js:20:26
    at ModuleJob.run (node:internal/modules/esm/module_job:447:25)
    at async node:internal/modules/esm/loader:646:26
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) {
  code: 'ERR_OUT_OF_RANGE'
}

VFS receives -1 as the position and treats it as an explicit negative offset.

Additional information

Native repro

import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';

const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'native-readsync-'));

try {
  const file = path.join(dir, 'file.txt');
  fs.writeFileSync(file, 'abcdef');

  const fd = fs.openSync(file, 'r');
  const buffer = Buffer.alloc(2);

  try {
    const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, null);
    console.log('bytesRead:', bytesRead);
    console.log('buffer:', buffer.toString());
  } finally {
    fs.closeSync(fd);
  }
} finally {
  fs.rmSync(dir, { recursive: true, force: true });
}

Metadata

Metadata

Assignees

Labels

vfsIssues and PRs related to the virtual filesystem subsystem.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions