From 3f971d89a96556b00d45ce482888d77649a0096e Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Thu, 21 May 2020 14:12:42 +0200 Subject: [PATCH] win,fs: use namespaced path in absolute symlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the namespaced (with the \\?\ prefix) paths for symlink targets when the path is absolute. This allows creation of symlinks to files with long filenames. Fixes: https://github.com/nodejs/node/issues/27795 PR-URL: https://github.com/nodejs/node/pull/33351 Reviewed-By: Colin Ihrig Reviewed-By: Gerhard Stöbich Reviewed-By: Anna Henningsen Reviewed-By: Ruben Bridgewater --- lib/internal/fs/utils.js | 4 ++++ test/parallel/test-fs-symlink-longpath.js | 29 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 test/parallel/test-fs-symlink-longpath.js diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 96be328a8ea2fc..b005a5793387ea 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -302,6 +302,10 @@ function preprocessSymlinkDestination(path, type, linkPath) { path = pathModule.resolve(linkPath, '..', path); return pathModule.toNamespacedPath(path); } + if (pathModule.isAbsolute(path)) { + // If the path is absolute, use the \\?\-prefix to enable long filenames + return pathModule.toNamespacedPath(path); + } // Windows symlinks don't tolerate forward slashes. return ('' + path).replace(/\//g, '\\'); } diff --git a/test/parallel/test-fs-symlink-longpath.js b/test/parallel/test-fs-symlink-longpath.js new file mode 100644 index 00000000000000..f6824218137bf2 --- /dev/null +++ b/test/parallel/test-fs-symlink-longpath.js @@ -0,0 +1,29 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); +const tmpDir = tmpdir.path; +const longPath = path.join(...[tmpDir].concat(Array(30).fill('1234567890'))); +fs.mkdirSync(longPath, { recursive: true }); + +// Test if we can have symlinks to files and folders with long filenames +const targetDirtectory = path.join(longPath, 'target-directory'); +fs.mkdirSync(targetDirtectory); +const pathDirectory = path.join(tmpDir, 'new-directory'); +fs.symlink(targetDirtectory, pathDirectory, 'dir', common.mustCall((err) => { + assert.ifError(err); + assert(fs.existsSync(pathDirectory)); +})); + +const targetFile = path.join(longPath, 'target-file'); +fs.writeFileSync(targetFile, 'data'); +const pathFile = path.join(tmpDir, 'new-file'); +fs.symlink(targetFile, pathFile, common.mustCall((err) => { + assert.ifError(err); + assert(fs.existsSync(pathFile)); +}));