Skip to content

Commit

Permalink
lib,permission: handle buffer on fs.symlink
Browse files Browse the repository at this point in the history
PR-URL: #51212
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
  • Loading branch information
RafaelGSS authored Dec 21, 2023
1 parent 3f2e234 commit 2000c26
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
10 changes: 9 additions & 1 deletion lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const {
StringPrototypeCharCodeAt,
StringPrototypeIndexOf,
StringPrototypeSlice,
uncurryThis,
} = primordials;

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

const { Buffer } = require('buffer');
const { isBuffer: BufferIsBuffer } = Buffer;
const BufferToString = uncurryThis(Buffer.prototype.toString);
const {
aggregateTwoErrors,
codes: {
Expand Down Expand Up @@ -1721,7 +1724,12 @@ function symlink(target, path, type_, callback_) {
if (permission.isEnabled()) {
// The permission model's security guarantees fall apart in the presence of
// relative symbolic links. Thus, we have to prevent their creation.
if (typeof target !== 'string' || !isAbsolute(toPathIfFileURL(target))) {
if (BufferIsBuffer(target)) {
if (!isAbsolute(BufferToString(target))) {
callback(new ERR_ACCESS_DENIED('relative symbolic link target'));
return;
}
} else if (typeof target !== 'string' || !isAbsolute(toPathIfFileURL(target))) {
callback(new ERR_ACCESS_DENIED('relative symbolic link target'));
return;
}
Expand Down
14 changes: 14 additions & 0 deletions test/parallel/test-permission-fs-symlink-relative.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const common = require('../common');
common.skipIfWorker();

const assert = require('assert');
const path = require('path');
const { symlinkSync, symlink, promises: { symlink: symlinkAsync } } = require('fs');

const error = {
Expand All @@ -25,3 +26,16 @@ for (const targetString of ['a', './b/c', '../d', 'e/../f', 'C:drive-relative',
}
}
}

// Absolute should not throw
for (const targetString of [path.resolve('.')]) {
for (const target of [targetString, Buffer.from(targetString)]) {
for (const path of [__filename]) {
symlink(target, path, common.mustCall((err) => {
assert(err);
assert.strictEqual(err.code, 'EEXIST');
assert.match(err.message, /file already exists/);
}));
}
}
}

0 comments on commit 2000c26

Please sign in to comment.