| // Flags: --expose-internals |
| 'use strict'; |
| |
| const common = require('../common'); |
| const assert = require('assert'); |
| const fs = require('fs'); |
| const tmpdir = require('../common/tmpdir'); |
| const { internalBinding } = require('internal/test/binding'); |
| |
| const fsBinding = internalBinding('fs'); |
| |
| tmpdir.refresh(); |
| |
| const file = tmpdir.resolve('readfile-buffer-option.txt'); |
| const content = Buffer.from('Hello buffer option\n'.repeat(128)); |
| fs.writeFileSync(file, content); |
| |
| function readFile(path, options) { |
| return new Promise((resolve, reject) => { |
| fs.readFile(path, options, (err, data) => { |
| if (err) reject(err); |
| else resolve(data); |
| }); |
| }); |
| } |
| |
| async function withFstatSizeZero(fn) { |
| const originalFstat = fsBinding.fstat; |
| fsBinding.fstat = function(...args) { |
| const req = args[2]; |
| |
| if (req?.oncomplete) { |
| const originalOncomplete = req.oncomplete; |
| req.oncomplete = function(err, stats) { |
| if (!err) { |
| stats[8] = 0; |
| } |
| return originalOncomplete.call(this, err, stats); |
| }; |
| return Reflect.apply(originalFstat, this, args); |
| } |
| |
| const stats = Reflect.apply(originalFstat, this, args); |
| if (stats !== undefined) { |
| stats[8] = 0; |
| } |
| return stats; |
| }; |
| |
| try { |
| await fn(); |
| } finally { |
| fsBinding.fstat = originalFstat; |
| } |
| } |
| |
| (async () => { |
| { |
| const buffer = Buffer.alloc(content.length + 16, 0x78); |
| const data = fs.readFileSync(file, { buffer }); |
| assert.deepStrictEqual(data, buffer.subarray(0, content.length)); |
| assert.deepStrictEqual(data, content); |
| assert(buffer.subarray(content.length).every((byte) => byte === 0x78)); |
| } |
| |
| { |
| const buffer = Buffer.alloc(content.length + 16); |
| assert.strictEqual( |
| fs.readFileSync(file, { buffer, encoding: 'utf8' }), |
| content.toString('utf8'), |
| ); |
| assert.deepStrictEqual(buffer.subarray(0, content.length), content); |
| } |
| |
| { |
| let size; |
| const data = fs.readFileSync(file, { |
| buffer(fileSize) { |
| size = fileSize; |
| return Buffer.alloc(fileSize + 8); |
| }, |
| }); |
| assert.strictEqual(size, content.length); |
| assert.deepStrictEqual(data, content); |
| } |
| |
| { |
| const buffer = Buffer.alloc(content.length + 16, 0x78); |
| const data = await readFile(file, { buffer }); |
| assert.deepStrictEqual(data, buffer.subarray(0, content.length)); |
| assert.deepStrictEqual(data, content); |
| assert(buffer.subarray(content.length).every((byte) => byte === 0x78)); |
| } |
| |
| { |
| const buffer = Buffer.alloc(content.length + 16); |
| assert.strictEqual( |
| await readFile(file, { buffer, encoding: 'utf8' }), |
| content.toString('utf8'), |
| ); |
| assert.deepStrictEqual(buffer.subarray(0, content.length), content); |
| } |
| |
| { |
| let size; |
| const data = await readFile(file, { |
| buffer(fileSize) { |
| size = fileSize; |
| return Buffer.alloc(fileSize + 8); |
| }, |
| }); |
| assert.strictEqual(size, content.length); |
| assert.deepStrictEqual(data, content); |
| } |
| |
| { |
| const buffer = Buffer.alloc(content.length - 1); |
| assert.throws(() => fs.readFileSync(file, { buffer }), { |
| code: 'ERR_INVALID_ARG_VALUE', |
| }); |
| } |
| |
| await assert.rejects(readFile(file, { |
| buffer() { |
| return Buffer.alloc(content.length - 1); |
| }, |
| }), { |
| code: 'ERR_INVALID_ARG_VALUE', |
| }); |
| |
| |
| await withFstatSizeZero(common.mustCall(async () => { |
| { |
| const buffer = Buffer.alloc(content.length + 16, 0x78); |
| const data = fs.readFileSync(file, { buffer }); |
| assert.deepStrictEqual(data, buffer.subarray(0, content.length)); |
| assert.deepStrictEqual(data, content); |
| assert(buffer.subarray(content.length).every((byte) => byte === 0x78)); |
| } |
| |
| { |
| const buffer = Buffer.alloc(content.length + 16, 0x78); |
| const data = await readFile(file, { buffer }); |
| assert.deepStrictEqual(data, buffer.subarray(0, content.length)); |
| assert.deepStrictEqual(data, content); |
| assert(buffer.subarray(content.length).every((byte) => byte === 0x78)); |
| } |
| |
| { |
| const buffer = Buffer.alloc(content.length - 1); |
| assert.throws(() => fs.readFileSync(file, { buffer }), { |
| code: 'ERR_INVALID_ARG_VALUE', |
| }); |
| } |
| |
| await assert.rejects(readFile(file, { |
| buffer: Buffer.alloc(content.length - 1), |
| }), { |
| code: 'ERR_INVALID_ARG_VALUE', |
| }); |
| })); |
| })().then(common.mustCall()); |