Skip to content

Commit 39f1b89

Browse files
authored
fs: fix edge case in readFileSync utf8 fast path
Fix a file permissions regression when `fs.readFileSync()` is called in append mode on a file that does not already exist introduced by the fast path for utf8 encoding. PR-URL: #52101 Fixes: #52079 Refs: #49691 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br> Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
1 parent 5f7fad2 commit 39f1b89

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/node_file.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2402,7 +2402,7 @@ static void ReadFileUtf8(const FunctionCallbackInfo<Value>& args) {
24022402
if (CheckOpenPermissions(env, path, flags).IsNothing()) return;
24032403

24042404
FS_SYNC_TRACE_BEGIN(open);
2405-
file = uv_fs_open(nullptr, &req, *path, flags, O_RDONLY, nullptr);
2405+
file = uv_fs_open(nullptr, &req, *path, flags, 0666, nullptr);
24062406
FS_SYNC_TRACE_END(open);
24072407
if (req.result < 0) {
24082408
uv_fs_req_cleanup(&req);

test/parallel/test-fs-read-file-sync.js

+26
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,37 @@ require('../common');
2424
const assert = require('assert');
2525
const fs = require('fs');
2626
const fixtures = require('../common/fixtures');
27+
const tmpdir = require('../common/tmpdir');
2728

2829
const fn = fixtures.path('elipses.txt');
30+
tmpdir.refresh();
2931

3032
const s = fs.readFileSync(fn, 'utf8');
3133
for (let i = 0; i < s.length; i++) {
3234
assert.strictEqual(s[i], '\u2026');
3335
}
3436
assert.strictEqual(s.length, 10000);
37+
38+
// Test file permissions set for readFileSync() in append mode.
39+
{
40+
const expectedMode = 0o666 & ~process.umask();
41+
42+
for (const test of [
43+
{ },
44+
{ encoding: 'ascii' },
45+
{ encoding: 'base64' },
46+
{ encoding: 'hex' },
47+
{ encoding: 'latin1' },
48+
{ encoding: 'uTf8' }, // case variation
49+
{ encoding: 'utf16le' },
50+
{ encoding: 'utf8' },
51+
]) {
52+
const opts = { ...test, flag: 'a+' };
53+
const file = tmpdir.resolve(`testReadFileSyncAppend${opts.encoding ?? ''}.txt`);
54+
const variant = `for '${file}'`;
55+
56+
const content = fs.readFileSync(file, opts);
57+
assert.strictEqual(opts.encoding ? content : content.toString(), '', `file contents ${variant}`);
58+
assert.strictEqual(fs.statSync(file).mode & 0o777, expectedMode, `file permissions ${variant}`);
59+
}
60+
}

0 commit comments

Comments
 (0)