Skip to content

Commit f4987eb

Browse files
RafaelGSSrichardlau
authored andcommitted
lib,permission: handle buffer on fs.symlink
PR-URL: #51212 Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Paolo Insogna <[email protected]>
1 parent 9e360df commit f4987eb

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

lib/fs.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const {
4040
StringPrototypeCharCodeAt,
4141
StringPrototypeIndexOf,
4242
StringPrototypeSlice,
43+
uncurryThis,
4344
} = primordials;
4445

4546
const { fs: constants } = internalBinding('constants');
@@ -66,6 +67,8 @@ const binding = internalBinding('fs');
6667
const { createBlobFromFilePath } = require('internal/blob');
6768

6869
const { Buffer } = require('buffer');
70+
const { isBuffer: BufferIsBuffer } = Buffer;
71+
const BufferToString = uncurryThis(Buffer.prototype.toString);
6972
const {
7073
aggregateTwoErrors,
7174
codes: {
@@ -1721,7 +1724,12 @@ function symlink(target, path, type_, callback_) {
17211724
if (permission.isEnabled()) {
17221725
// The permission model's security guarantees fall apart in the presence of
17231726
// relative symbolic links. Thus, we have to prevent their creation.
1724-
if (typeof target !== 'string' || !isAbsolute(toPathIfFileURL(target))) {
1727+
if (BufferIsBuffer(target)) {
1728+
if (!isAbsolute(BufferToString(target))) {
1729+
callback(new ERR_ACCESS_DENIED('relative symbolic link target'));
1730+
return;
1731+
}
1732+
} else if (typeof target !== 'string' || !isAbsolute(toPathIfFileURL(target))) {
17251733
callback(new ERR_ACCESS_DENIED('relative symbolic link target'));
17261734
return;
17271735
}

test/parallel/test-permission-fs-symlink-relative.js

+14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const common = require('../common');
55
common.skipIfWorker();
66

77
const assert = require('assert');
8+
const path = require('path');
89
const { symlinkSync, symlink, promises: { symlink: symlinkAsync } } = require('fs');
910

1011
const error = {
@@ -25,3 +26,16 @@ for (const targetString of ['a', './b/c', '../d', 'e/../f', 'C:drive-relative',
2526
}
2627
}
2728
}
29+
30+
// Absolute should not throw
31+
for (const targetString of [path.resolve('.')]) {
32+
for (const target of [targetString, Buffer.from(targetString)]) {
33+
for (const path of [__filename]) {
34+
symlink(target, path, common.mustCall((err) => {
35+
assert(err);
36+
assert.strictEqual(err.code, 'EEXIST');
37+
assert.match(err.message, /file already exists/);
38+
}));
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)