diff --git a/lib/fs.js b/lib/fs.js index f47dba6e43debb..5f225a4a97e381 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -231,7 +231,7 @@ function access(path, mode, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.access(pathModule.toNamespacedPath(path), mode, req); + binding.access(path, mode, req); } /** @@ -242,8 +242,7 @@ function access(path, mode, callback) { * @returns {void} */ function accessSync(path, mode) { - path = getValidatedPath(path); - binding.access(pathModule.toNamespacedPath(path), mode); + binding.access(getValidatedPath(path), mode); } /** @@ -291,7 +290,7 @@ function existsSync(path) { return false; } - return binding.existsSync(pathModule.toNamespacedPath(path)); + return binding.existsSync(path); } function readFileAfterOpen(err, fd) { @@ -384,15 +383,10 @@ function readFile(path, options, callback) { return; const flagsNumber = stringToFlags(options.flag, 'options.flag'); - path = getValidatedPath(path); - const req = new FSReqCallback(); req.context = context; req.oncomplete = readFileAfterOpen; - binding.open(pathModule.toNamespacedPath(path), - flagsNumber, - 0o666, - req); + binding.open(getValidatedPath(path), flagsNumber, 0o666, req); } function tryStatSync(fd, isUserFd) { @@ -444,7 +438,7 @@ function readFileSync(path, options) { if (options.encoding === 'utf8' || options.encoding === 'utf-8') { if (!isInt32(path)) { - path = pathModule.toNamespacedPath(getValidatedPath(path)); + path = getValidatedPath(path); } return binding.readFileUtf8(path, stringToFlags(options.flag)); } @@ -555,10 +549,7 @@ function open(path, flags, mode, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.open(pathModule.toNamespacedPath(path), - flagsNumber, - mode, - req); + binding.open(path, flagsNumber, mode, req); } /** @@ -569,10 +560,8 @@ function open(path, flags, mode, callback) { * @returns {number} */ function openSync(path, flags, mode) { - path = getValidatedPath(path); - return binding.open( - pathModule.toNamespacedPath(path), + getValidatedPath(path), stringToFlags(flags), parseFileMode(mode, 'mode', 0o666), ); @@ -593,7 +582,7 @@ function openAsBlob(path, options = kEmptyObject) { // To give ourselves flexibility to maybe return the Blob asynchronously, // this API returns a Promise. path = getValidatedPath(path); - return PromiseResolve(createBlobFromFilePath(pathModule.toNamespacedPath(path), { type })); + return PromiseResolve(createBlobFromFilePath(path, { type })); } /** @@ -1010,13 +999,13 @@ function writevSync(fd, buffers, position) { */ function rename(oldPath, newPath, callback) { callback = makeCallback(callback); - oldPath = getValidatedPath(oldPath, 'oldPath'); - newPath = getValidatedPath(newPath, 'newPath'); const req = new FSReqCallback(); req.oncomplete = callback; - binding.rename(pathModule.toNamespacedPath(oldPath), - pathModule.toNamespacedPath(newPath), - req); + binding.rename( + getValidatedPath(oldPath, 'oldPath'), + getValidatedPath(newPath, 'newPath'), + req, + ); } @@ -1028,11 +1017,9 @@ function rename(oldPath, newPath, callback) { * @returns {void} */ function renameSync(oldPath, newPath) { - oldPath = getValidatedPath(oldPath, 'oldPath'); - newPath = getValidatedPath(newPath, 'newPath'); binding.rename( - pathModule.toNamespacedPath(oldPath), - pathModule.toNamespacedPath(newPath), + getValidatedPath(oldPath, 'oldPath'), + getValidatedPath(newPath, 'newPath'), ); } @@ -1126,8 +1113,7 @@ function ftruncate(fd, len = 0, callback) { */ function ftruncateSync(fd, len = 0) { validateInteger(len, 'len'); - len = MathMax(0, len); - binding.ftruncate(fd, len); + binding.ftruncate(fd, len < 0 ? 0 : len); } function lazyLoadCp() { @@ -1161,7 +1147,7 @@ function rmdir(path, options, callback) { } callback = makeCallback(callback); - path = pathModule.toNamespacedPath(getValidatedPath(path)); + path = getValidatedPath(path); if (options?.recursive) { emitRecursiveRmdirWarning(); @@ -1209,13 +1195,13 @@ function rmdirSync(path, options) { options = validateRmOptionsSync(path, { ...options, force: false }, true); if (options !== false) { lazyLoadRimraf(); - return rimrafSync(pathModule.toNamespacedPath(path), options); + return rimrafSync(path, options); } } else { validateRmdirOptions(options); } - binding.rmdir(pathModule.toNamespacedPath(path)); + binding.rmdir(path); } /** @@ -1243,7 +1229,7 @@ function rm(path, options, callback) { return callback(err); } lazyLoadRimraf(); - return rimraf(pathModule.toNamespacedPath(path), options, callback); + return rimraf(path, options, callback); }); } @@ -1260,11 +1246,11 @@ function rm(path, options, callback) { * @returns {void} */ function rmSync(path, options) { - path = getValidatedPath(path); - options = validateRmOptionsSync(path, options, false); - lazyLoadRimraf(); - return rimrafSync(pathModule.toNamespacedPath(path), options); + return rimrafSync( + getValidatedPath(path), + validateRmOptionsSync(path, options, false), + ); } /** @@ -1345,8 +1331,12 @@ function mkdir(path, options, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.mkdir(pathModule.toNamespacedPath(path), - parseFileMode(mode, 'mode'), recursive, req); + binding.mkdir( + path, + parseFileMode(mode, 'mode'), + recursive, + req, + ); } /** @@ -1373,7 +1363,7 @@ function mkdirSync(path, options) { validateBoolean(recursive, 'options.recursive'); const result = binding.mkdir( - pathModule.toNamespacedPath(path), + path, parseFileMode(mode, 'mode'), recursive, ); @@ -1400,7 +1390,7 @@ function readdirSyncRecursive(basePath, options) { function read(path) { const readdirResult = binding.readdir( - pathModule.toNamespacedPath(path), + path, encoding, withFileTypes, ); @@ -1452,7 +1442,7 @@ function readdirSyncRecursive(basePath, options) { * recursive?: boolean; * }} [options] * @param {( - * err?: Error, + * err?: Error; * files?: string[] | Buffer[] | Dirent[]; * ) => any} callback * @returns {void} @@ -1482,8 +1472,12 @@ function readdir(path, options, callback) { getDirents(path, result, callback); }; } - binding.readdir(pathModule.toNamespacedPath(path), options.encoding, - !!options.withFileTypes, req); + binding.readdir( + path, + options.encoding, + !!options.withFileTypes, + req, + ); } /** @@ -1508,7 +1502,7 @@ function readdirSync(path, options) { } const result = binding.readdir( - pathModule.toNamespacedPath(path), + path, options.encoding, !!options.withFileTypes, ); @@ -1524,7 +1518,7 @@ function readdirSync(path, options) { * @param {( * err?: Error, * stats?: Stats - * ) => any} callback + * ) => any} [callback] * @returns {void} */ function fstat(fd, options = { bigint: false }, callback) { @@ -1560,7 +1554,7 @@ function lstat(path, options = { bigint: false }, callback) { const req = new FSReqCallback(options.bigint); req.oncomplete = callback; - binding.lstat(pathModule.toNamespacedPath(path), options.bigint, req); + binding.lstat(path, options.bigint, req); } /** @@ -1579,11 +1573,10 @@ function stat(path, options = { bigint: false }, callback) { options = kEmptyObject; } callback = makeStatsCallback(callback); - path = getValidatedPath(path); const req = new FSReqCallback(options.bigint); req.oncomplete = callback; - binding.stat(pathModule.toNamespacedPath(path), options.bigint, req); + binding.stat(getValidatedPath(path), options.bigint, req); } function statfs(path, options = { bigint: false }, callback) { @@ -1601,16 +1594,14 @@ function statfs(path, options = { bigint: false }, callback) { callback(err, getStatFsFromBinding(stats)); }; - binding.statfs(pathModule.toNamespacedPath(path), options.bigint, req); + binding.statfs(getValidatedPath(path), options.bigint, req); } /** * Synchronously retrieves the `fs.Stats` for * the file descriptor. * @param {number} fd - * @param {{ - * bigint?: boolean; - * }} [options] + * @param {{ bigint?: boolean; }} [options] * @returns {Stats | undefined} */ function fstatSync(fd, options = { bigint: false }) { @@ -1632,9 +1623,8 @@ function fstatSync(fd, options = { bigint: false }) { * @returns {Stats | undefined} */ function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) { - path = getValidatedPath(path); const stats = binding.lstat( - pathModule.toNamespacedPath(path), + getValidatedPath(path), options.bigint, undefined, options.throwIfNoEntry, @@ -1657,9 +1647,8 @@ function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) { * @returns {Stats} */ function statSync(path, options = { bigint: false, throwIfNoEntry: true }) { - path = getValidatedPath(path); const stats = binding.stat( - pathModule.toNamespacedPath(path), + getValidatedPath(path), options.bigint, undefined, options.throwIfNoEntry, @@ -1671,8 +1660,7 @@ function statSync(path, options = { bigint: false, throwIfNoEntry: true }) { } function statfsSync(path, options = { bigint: false }) { - path = getValidatedPath(path); - const stats = binding.statfs(pathModule.toNamespacedPath(path), options.bigint); + const stats = binding.statfs(getValidatedPath(path), options.bigint); return getStatFsFromBinding(stats); } @@ -1690,10 +1678,9 @@ function statfsSync(path, options = { bigint: false }) { function readlink(path, options, callback) { callback = makeCallback(typeof options === 'function' ? options : callback); options = getOptions(options); - path = getValidatedPath(path, 'oldPath'); const req = new FSReqCallback(); req.oncomplete = callback; - binding.readlink(pathModule.toNamespacedPath(path), options.encoding, req); + binding.readlink(getValidatedPath(path), options.encoding, req); } /** @@ -1705,11 +1692,7 @@ function readlink(path, options, callback) { */ function readlinkSync(path, options) { options = getOptions(options); - path = getValidatedPath(path, 'oldPath'); - return binding.readlink( - pathModule.toNamespacedPath(path), - options.encoding, - ); + return binding.readlink(getValidatedPath(path), options.encoding); } /** @@ -1767,8 +1750,12 @@ function symlink(target, path, type, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.symlink(destination, - pathModule.toNamespacedPath(path), resolvedFlags, req); + binding.symlink( + destination, + path, + resolvedFlags, + req, + ); }); return; } @@ -1779,7 +1766,7 @@ function symlink(target, path, type, callback) { const flags = stringToSymlinkType(type); const req = new FSReqCallback(); req.oncomplete = callback; - binding.symlink(destination, pathModule.toNamespacedPath(path), flags, req); + binding.symlink(destination, path, flags, req); } /** @@ -1816,7 +1803,7 @@ function symlinkSync(target, path, type) { binding.symlink( preprocessSymlinkDestination(target, type, path), - pathModule.toNamespacedPath(path), + path, stringToSymlinkType(type), ); } @@ -1838,9 +1825,7 @@ function link(existingPath, newPath, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.link(pathModule.toNamespacedPath(existingPath), - pathModule.toNamespacedPath(newPath), - req); + binding.link(existingPath, newPath, req); } /** @@ -1855,8 +1840,8 @@ function linkSync(existingPath, newPath) { newPath = getValidatedPath(newPath, 'newPath'); binding.link( - pathModule.toNamespacedPath(existingPath), - pathModule.toNamespacedPath(newPath), + existingPath, + newPath, ); } @@ -1868,10 +1853,9 @@ function linkSync(existingPath, newPath) { */ function unlink(path, callback) { callback = makeCallback(callback); - path = getValidatedPath(path); const req = new FSReqCallback(); req.oncomplete = callback; - binding.unlink(pathModule.toNamespacedPath(path), req); + binding.unlink(getValidatedPath(path), req); } /** @@ -1880,8 +1864,7 @@ function unlink(path, callback) { * @returns {void} */ function unlinkSync(path) { - path = pathModule.toNamespacedPath(getValidatedPath(path)); - binding.unlink(path); + binding.unlink(getValidatedPath(path)); } /** @@ -1972,7 +1955,7 @@ function chmod(path, mode, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.chmod(pathModule.toNamespacedPath(path), mode, req); + binding.chmod(path, mode, req); } /** @@ -1985,10 +1968,7 @@ function chmodSync(path, mode) { path = getValidatedPath(path); mode = parseFileMode(mode, 'mode'); - binding.chmod( - pathModule.toNamespacedPath(path), - mode, - ); + binding.chmod(path, mode); } /** @@ -2006,7 +1986,7 @@ function lchown(path, uid, gid, callback) { validateInteger(gid, 'gid', -1, kMaxUserId); const req = new FSReqCallback(); req.oncomplete = callback; - binding.lchown(pathModule.toNamespacedPath(path), uid, gid, req); + binding.lchown(path, uid, gid, req); } /** @@ -2020,11 +2000,7 @@ function lchownSync(path, uid, gid) { path = getValidatedPath(path); validateInteger(uid, 'uid', -1, kMaxUserId); validateInteger(gid, 'gid', -1, kMaxUserId); - binding.lchown( - pathModule.toNamespacedPath(path), - uid, - gid, - ); + binding.lchown(path, uid, gid); } /** @@ -2076,7 +2052,7 @@ function chown(path, uid, gid, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.chown(pathModule.toNamespacedPath(path), uid, gid, req); + binding.chown(path, uid, gid, req); } /** @@ -2091,11 +2067,7 @@ function chownSync(path, uid, gid) { path = getValidatedPath(path); validateInteger(uid, 'uid', -1, kMaxUserId); validateInteger(gid, 'gid', -1, kMaxUserId); - binding.chown( - pathModule.toNamespacedPath(path), - uid, - gid, - ); + binding.chown(path, uid, gid); } /** @@ -2113,10 +2085,12 @@ function utimes(path, atime, mtime, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.utimes(pathModule.toNamespacedPath(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); + binding.utimes( + path, + toUnixTimestamp(atime), + toUnixTimestamp(mtime), + req, + ); } /** @@ -2128,9 +2102,8 @@ function utimes(path, atime, mtime, callback) { * @returns {void} */ function utimesSync(path, atime, mtime) { - path = getValidatedPath(path); binding.utimes( - pathModule.toNamespacedPath(path), + getValidatedPath(path), toUnixTimestamp(atime), toUnixTimestamp(mtime), ); @@ -2187,10 +2160,12 @@ function lutimes(path, atime, mtime, callback) { const req = new FSReqCallback(); req.oncomplete = callback; - binding.lutimes(pathModule.toNamespacedPath(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); + binding.lutimes( + path, + toUnixTimestamp(atime), + toUnixTimestamp(mtime), + req, + ); } /** @@ -2202,9 +2177,8 @@ function lutimes(path, atime, mtime, callback) { * @returns {void} */ function lutimesSync(path, atime, mtime) { - path = getValidatedPath(path); binding.lutimes( - pathModule.toNamespacedPath(path), + getValidatedPath(path), toUnixTimestamp(atime), toUnixTimestamp(mtime), ); @@ -2347,11 +2321,12 @@ function writeFileSync(path, data, options) { // C++ fast path for string data and UTF8 encoding if (typeof data === 'string' && (options.encoding === 'utf8' || options.encoding === 'utf-8')) { if (!isInt32(path)) { - path = pathModule.toNamespacedPath(getValidatedPath(path)); + path = getValidatedPath(path); } return binding.writeFileUtf8( - path, data, + path, + data, stringToFlags(flag), parseFileMode(options.mode, 'mode', 0o666), ); @@ -2668,7 +2643,7 @@ function realpathSync(p, options) { // On windows, check that the root exists. On unix there is no need. if (isWindows) { - const out = binding.lstat(pathModule.toNamespacedPath(base), false, undefined, true /* throwIfNoEntry */); + const out = binding.lstat(base, false, undefined, true /* throwIfNoEntry */); if (out === undefined) { return; } @@ -2710,8 +2685,7 @@ function realpathSync(p, options) { // Use stats array directly to avoid creating an fs.Stats instance just // for our internal use. - const baseLong = pathModule.toNamespacedPath(base); - const stats = binding.lstat(baseLong, true, undefined, true /* throwIfNoEntry */); + const stats = binding.lstat(base, true, undefined, true /* throwIfNoEntry */); if (stats === undefined) { return; } @@ -2735,8 +2709,8 @@ function realpathSync(p, options) { } } if (linkTarget === null) { - binding.stat(baseLong, false, undefined, true); - linkTarget = binding.readlink(baseLong, undefined); + binding.stat(base, false, undefined, true); + linkTarget = binding.readlink(base, undefined); } resolvedLink = pathModule.resolve(previous, linkTarget); @@ -2753,7 +2727,7 @@ function realpathSync(p, options) { // On windows, check that the root exists. On unix there is no need. if (isWindows && !knownHard.has(base)) { - const out = binding.lstat(pathModule.toNamespacedPath(base), false, undefined, true /* throwIfNoEntry */); + const out = binding.lstat(base, false, undefined, true /* throwIfNoEntry */); if (out === undefined) { return; } @@ -2773,9 +2747,8 @@ function realpathSync(p, options) { */ realpathSync.native = (path, options) => { options = getOptions(options); - path = getValidatedPath(path); return binding.realpath( - pathModule.toNamespacedPath(path), + getValidatedPath(path), options.encoding, ); }; @@ -2939,7 +2912,7 @@ realpath.native = (path, options, callback) => { path = getValidatedPath(path); const req = new FSReqCallback(); req.oncomplete = callback; - binding.realpath(pathModule.toNamespacedPath(path), options.encoding, req); + binding.realpath(path, options.encoding, req); }; /** @@ -2995,9 +2968,6 @@ function copyFile(src, dest, mode, callback) { src = getValidatedPath(src, 'src'); dest = getValidatedPath(dest, 'dest'); - - src = pathModule.toNamespacedPath(src); - dest = pathModule.toNamespacedPath(dest); callback = makeCallback(callback); const req = new FSReqCallback(); @@ -3014,12 +2984,9 @@ function copyFile(src, dest, mode, callback) { * @returns {void} */ function copyFileSync(src, dest, mode) { - src = getValidatedPath(src, 'src'); - dest = getValidatedPath(dest, 'dest'); - binding.copyFile( - pathModule.toNamespacedPath(src), - pathModule.toNamespacedPath(dest), + getValidatedPath(src, 'src'), + getValidatedPath(dest, 'dest'), mode, ); } @@ -3040,8 +3007,8 @@ function cp(src, dest, options, callback) { } callback = makeCallback(callback); options = validateCpOptions(options); - src = pathModule.toNamespacedPath(getValidatedPath(src, 'src')); - dest = pathModule.toNamespacedPath(getValidatedPath(dest, 'dest')); + src = getValidatedPath(src, 'src'); + dest = getValidatedPath(dest, 'dest'); lazyLoadCp(); cpFn(src, dest, options, callback); } @@ -3056,8 +3023,8 @@ function cp(src, dest, options, callback) { */ function cpSync(src, dest, options) { options = validateCpOptions(options); - src = pathModule.toNamespacedPath(getValidatedPath(src, 'src')); - dest = pathModule.toNamespacedPath(getValidatedPath(dest, 'dest')); + src = getValidatedPath(src, 'src'); + dest = getValidatedPath(dest, 'dest'); lazyLoadCp(); cpSyncFn(src, dest, options); } diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index a035a8b5a0a609..4f1931f725bfb8 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -604,10 +604,8 @@ async function readFileHandle(filehandle, options) { // All of the functions are defined as async in order to ensure that errors // thrown cause promise rejections rather than being thrown synchronously. async function access(path, mode = F_OK) { - path = getValidatedPath(path); - return await PromisePrototypeThen( - binding.access(pathModule.toNamespacedPath(path), mode, kUsePromises), + binding.access(getValidatedPath(path), mode, kUsePromises), undefined, handleErrorFromBinding, ); @@ -615,19 +613,19 @@ async function access(path, mode = F_OK) { async function cp(src, dest, options) { options = validateCpOptions(options); - src = pathModule.toNamespacedPath(getValidatedPath(src, 'src')); - dest = pathModule.toNamespacedPath(getValidatedPath(dest, 'dest')); + src = getValidatedPath(src, 'src'); + dest = getValidatedPath(dest, 'dest'); return lazyLoadCpPromises()(src, dest, options); } async function copyFile(src, dest, mode) { - src = getValidatedPath(src, 'src'); - dest = getValidatedPath(dest, 'dest'); return await PromisePrototypeThen( - binding.copyFile(pathModule.toNamespacedPath(src), - pathModule.toNamespacedPath(dest), - mode, - kUsePromises), + binding.copyFile( + getValidatedPath(src, 'src'), + getValidatedPath(dest, 'dest'), + mode, + kUsePromises, + ), undefined, handleErrorFromBinding, ); @@ -640,8 +638,7 @@ async function open(path, flags, mode) { const flagsNumber = stringToFlags(flags); mode = parseFileMode(mode, 'mode', 0o666); return new FileHandle(await PromisePrototypeThen( - binding.openFileHandle(pathModule.toNamespacedPath(path), - flagsNumber, mode, kUsePromises), + binding.openFileHandle(path, flagsNumber, mode, kUsePromises), undefined, handleErrorFromBinding, )); @@ -786,9 +783,7 @@ async function rename(oldPath, newPath) { oldPath = getValidatedPath(oldPath, 'oldPath'); newPath = getValidatedPath(newPath, 'newPath'); return await PromisePrototypeThen( - binding.rename(pathModule.toNamespacedPath(oldPath), - pathModule.toNamespacedPath(newPath), - kUsePromises), + binding.rename(oldPath, newPath, kUsePromises), undefined, handleErrorFromBinding, ); @@ -810,13 +805,13 @@ async function ftruncate(handle, len = 0) { } async function rm(path, options) { - path = pathModule.toNamespacedPath(getValidatedPath(path)); + path = getValidatedPath(path); options = await validateRmOptionsPromise(path, options, false); return lazyRimRaf()(path, options); } async function rmdir(path, options) { - path = pathModule.toNamespacedPath(getValidatedPath(path)); + path = getValidatedPath(path); options = validateRmdirOptions(options); if (options.recursive) { @@ -862,9 +857,12 @@ async function mkdir(path, options) { validateBoolean(recursive, 'options.recursive'); return await PromisePrototypeThen( - binding.mkdir(pathModule.toNamespacedPath(path), - parseFileMode(mode, 'mode', 0o777), recursive, - kUsePromises), + binding.mkdir( + path, + parseFileMode(mode, 'mode', 0o777), + recursive, + kUsePromises, + ), undefined, handleErrorFromBinding, ); @@ -877,7 +875,7 @@ async function readdirRecursive(originalPath, options) { originalPath, await PromisePrototypeThen( binding.readdir( - pathModule.toNamespacedPath(originalPath), + originalPath, options.encoding, !!options.withFileTypes, kUsePromises, @@ -928,7 +926,7 @@ async function readdirRecursive(originalPath, options) { direntPath, await PromisePrototypeThen( binding.readdir( - pathModule.toNamespacedPath(direntPath), + direntPath, options.encoding, false, kUsePromises, @@ -953,7 +951,7 @@ async function readdir(path, options) { } const result = await PromisePrototypeThen( binding.readdir( - pathModule.toNamespacedPath(path), + path, options.encoding, !!options.withFileTypes, kUsePromises, @@ -970,8 +968,7 @@ async function readlink(path, options) { options = getOptions(options); path = getValidatedPath(path, 'oldPath'); return await PromisePrototypeThen( - binding.readlink(pathModule.toNamespacedPath(path), - options.encoding, kUsePromises), + binding.readlink(path, options.encoding, kUsePromises), undefined, handleErrorFromBinding, ); @@ -1004,10 +1001,12 @@ async function symlink(target, path, type) { target = getValidatedPath(target, 'target'); path = getValidatedPath(path); return await PromisePrototypeThen( - binding.symlink(preprocessSymlinkDestination(target, type, path), - pathModule.toNamespacedPath(path), - stringToSymlinkType(type), - kUsePromises), + binding.symlink( + preprocessSymlinkDestination(target, type, path), + path, + stringToSymlinkType(type), + kUsePromises, + ), undefined, handleErrorFromBinding, ); @@ -1023,10 +1022,8 @@ async function fstat(handle, options = { bigint: false }) { } async function lstat(path, options = { bigint: false }) { - path = getValidatedPath(path); const result = await PromisePrototypeThen( - binding.lstat(pathModule.toNamespacedPath(path), - options.bigint, kUsePromises), + binding.lstat(getValidatedPath(path), options.bigint, kUsePromises), undefined, handleErrorFromBinding, ); @@ -1034,10 +1031,8 @@ async function lstat(path, options = { bigint: false }) { } async function stat(path, options = { bigint: false }) { - path = getValidatedPath(path); const result = await PromisePrototypeThen( - binding.stat(pathModule.toNamespacedPath(path), - options.bigint, kUsePromises), + binding.stat(getValidatedPath(path), options.bigint, kUsePromises), undefined, handleErrorFromBinding, ); @@ -1045,10 +1040,8 @@ async function stat(path, options = { bigint: false }) { } async function statfs(path, options = { bigint: false }) { - path = getValidatedPath(path); const result = await PromisePrototypeThen( - binding.statfs(pathModule.toNamespacedPath(path), - options.bigint, kUsePromises), + binding.statfs(path, options.bigint, kUsePromises), undefined, handleErrorFromBinding, ); @@ -1059,18 +1052,15 @@ async function link(existingPath, newPath) { existingPath = getValidatedPath(existingPath, 'existingPath'); newPath = getValidatedPath(newPath, 'newPath'); return await PromisePrototypeThen( - binding.link(pathModule.toNamespacedPath(existingPath), - pathModule.toNamespacedPath(newPath), - kUsePromises), + binding.link(existingPath, newPath, kUsePromises), undefined, handleErrorFromBinding, ); } async function unlink(path) { - path = getValidatedPath(path); return await PromisePrototypeThen( - binding.unlink(pathModule.toNamespacedPath(path), kUsePromises), + binding.unlink(getValidatedPath(path), kUsePromises), undefined, handleErrorFromBinding, ); @@ -1089,7 +1079,7 @@ async function chmod(path, mode) { path = getValidatedPath(path); mode = parseFileMode(mode, 'mode'); return await PromisePrototypeThen( - binding.chmod(pathModule.toNamespacedPath(path), mode, kUsePromises), + binding.chmod(path, mode, kUsePromises), undefined, handleErrorFromBinding, ); @@ -1108,7 +1098,7 @@ async function lchown(path, uid, gid) { validateInteger(uid, 'uid', -1, kMaxUserId); validateInteger(gid, 'gid', -1, kMaxUserId); return await PromisePrototypeThen( - binding.lchown(pathModule.toNamespacedPath(path), uid, gid, kUsePromises), + binding.lchown(path, uid, gid, kUsePromises), undefined, handleErrorFromBinding, ); @@ -1129,7 +1119,7 @@ async function chown(path, uid, gid) { validateInteger(uid, 'uid', -1, kMaxUserId); validateInteger(gid, 'gid', -1, kMaxUserId); return await PromisePrototypeThen( - binding.chown(pathModule.toNamespacedPath(path), uid, gid, kUsePromises), + binding.chown(path, uid, gid, kUsePromises), undefined, handleErrorFromBinding, ); @@ -1138,10 +1128,12 @@ async function chown(path, uid, gid) { async function utimes(path, atime, mtime) { path = getValidatedPath(path); return await PromisePrototypeThen( - binding.utimes(pathModule.toNamespacedPath(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - kUsePromises), + binding.utimes( + path, + toUnixTimestamp(atime), + toUnixTimestamp(mtime), + kUsePromises, + ), undefined, handleErrorFromBinding, ); @@ -1158,12 +1150,13 @@ async function futimes(handle, atime, mtime) { } async function lutimes(path, atime, mtime) { - path = getValidatedPath(path); return await PromisePrototypeThen( - binding.lutimes(pathModule.toNamespacedPath(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - kUsePromises), + binding.lutimes( + getValidatedPath(path), + toUnixTimestamp(atime), + toUnixTimestamp(mtime), + kUsePromises, + ), undefined, handleErrorFromBinding, ); @@ -1171,9 +1164,8 @@ async function lutimes(path, atime, mtime) { async function realpath(path, options) { options = getOptions(options); - path = getValidatedPath(path); return await PromisePrototypeThen( - binding.realpath(pathModule.toNamespacedPath(path), options.encoding, kUsePromises), + binding.realpath(getValidatedPath(path), options.encoding, kUsePromises), undefined, handleErrorFromBinding, ); diff --git a/src/node_blob.cc b/src/node_blob.cc index 1fe6237e73f466..5170b4b6946aa1 100644 --- a/src/node_blob.cc +++ b/src/node_blob.cc @@ -8,6 +8,7 @@ #include "node_errors.h" #include "node_external_reference.h" #include "node_file.h" +#include "path.h" #include "permission/permission.h" #include "util.h" #include "v8.h" @@ -96,6 +97,7 @@ void BlobFromFilePath(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); auto entry = DataQueue::CreateFdEntry(env, args[0]); diff --git a/src/node_file.cc b/src/node_file.cc index 230396b95c34a8..75a96e937e475a 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -30,6 +30,7 @@ #include "node_process-inl.h" #include "node_stat_watcher.h" #include "node_url.h" +#include "path.h" #include "permission/permission.h" #include "util-inl.h" @@ -825,7 +826,6 @@ void AfterMkdirp(uv_fs_t* req) { std::string first_path(req_wrap->continuation_data()->first_path()); if (first_path.empty()) return req_wrap->Resolve(Undefined(req_wrap->env()->isolate())); - node::url::FromNamespacedPath(&first_path); Local path; Local error; if (!StringBytes::Encode(req_wrap->env()->isolate(), first_path.c_str(), @@ -942,6 +942,7 @@ void Access(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); if (argc > 2) { // access(path, mode, req) FSReqBase* req_wrap_async = GetReqWrap(args, 2); @@ -998,6 +999,7 @@ static void ExistsSync(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); @@ -1028,7 +1030,9 @@ static void InternalModuleStat(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CHECK(args[0]->IsString()); - node::Utf8Value path(env->isolate(), args[0]); + BufferValue path(env->isolate(), args[0]); + CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); @@ -1084,6 +1088,7 @@ static void Stat(const FunctionCallbackInfo& args) { BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); bool use_bigint = args[1]->IsTrue(); if (!args[2]->IsUndefined()) { // stat(path, use_bigint, req) @@ -1131,6 +1136,7 @@ static void LStat(const FunctionCallbackInfo& args) { BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); bool use_bigint = args[1]->IsTrue(); if (!args[2]->IsUndefined()) { // lstat(path, use_bigint, req) @@ -1210,6 +1216,7 @@ static void StatFs(const FunctionCallbackInfo& args) { BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); bool use_bigint = args[1]->IsTrue(); if (argc > 2) { // statfs(path, use_bigint, req) @@ -1268,6 +1275,7 @@ static void Symlink(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[1]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); @@ -1302,11 +1310,14 @@ static void Link(const FunctionCallbackInfo& args) { BufferValue src(isolate, args[0]); CHECK_NOT_NULL(*src); + ToNamespacedPath(env, &src); const auto src_view = src.ToStringView(); BufferValue dest(isolate, args[1]); CHECK_NOT_NULL(*dest); + ToNamespacedPath(env, &dest); + const auto dest_view = dest.ToStringView(); if (argc > 2) { // link(src, dest, req) @@ -1361,6 +1372,7 @@ static void ReadLink(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); @@ -1406,10 +1418,12 @@ static void Rename(const FunctionCallbackInfo& args) { BufferValue old_path(isolate, args[0]); CHECK_NOT_NULL(*old_path); + ToNamespacedPath(env, &old_path); auto view_old_path = old_path.ToStringView(); BufferValue new_path(isolate, args[1]); CHECK_NOT_NULL(*new_path); + ToNamespacedPath(env, &new_path); if (argc > 2) { // rename(old_path, new_path, req) FSReqBase* req_wrap_async = GetReqWrap(args, 2); @@ -1539,6 +1553,7 @@ static void Unlink(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); if (argc > 1) { // unlink(path, req) FSReqBase* req_wrap_async = GetReqWrap(args, 1); @@ -1572,6 +1587,7 @@ static void RMDir(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); @@ -1760,6 +1776,8 @@ static void MKDir(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); + THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); @@ -1790,7 +1808,6 @@ static void MKDir(const FunctionCallbackInfo& args) { if (!req_wrap_sync.continuation_data()->first_path().empty()) { Local error; std::string first_path(req_wrap_sync.continuation_data()->first_path()); - node::url::FromNamespacedPath(&first_path); MaybeLocal path = StringBytes::Encode(env->isolate(), first_path.c_str(), UTF8, &error); @@ -1816,6 +1833,7 @@ static void RealPath(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); const enum encoding encoding = ParseEncoding(isolate, args[1], UTF8); @@ -1860,6 +1878,7 @@ static void ReadDir(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); const enum encoding encoding = ParseEncoding(isolate, args[1], UTF8); @@ -2014,6 +2033,7 @@ static void Open(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); CHECK(args[1]->IsInt32()); const int flags = args[1].As()->Value(); @@ -2054,6 +2074,7 @@ static void OpenFileHandle(const FunctionCallbackInfo& args) { BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); CHECK(args[1]->IsInt32()); const int flags = args[1].As()->Value(); @@ -2099,9 +2120,11 @@ static void CopyFile(const FunctionCallbackInfo& args) { BufferValue src(isolate, args[0]); CHECK_NOT_NULL(*src); + ToNamespacedPath(env, &src); BufferValue dest(isolate, args[1]); CHECK_NOT_NULL(*dest); + ToNamespacedPath(env, &dest); if (argc > 3) { // copyFile(src, dest, flags, req) FSReqBase* req_wrap_async = GetReqWrap(args, 3); @@ -2381,6 +2404,7 @@ static void WriteFileUtf8(const FunctionCallbackInfo& args) { } else { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); if (CheckOpenPermissions(env, path, flags).IsNothing()) return; FSReqWrapSync req_open("open", *path); @@ -2516,6 +2540,7 @@ static void ReadFileUtf8(const FunctionCallbackInfo& args) { } else { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); if (CheckOpenPermissions(env, path, flags).IsNothing()) return; FS_SYNC_TRACE_BEGIN(open); @@ -2524,7 +2549,8 @@ static void ReadFileUtf8(const FunctionCallbackInfo& args) { if (req.result < 0) { uv_fs_req_cleanup(&req); // req will be cleaned up by scope leave. - return env->ThrowUVException(req.result, "open", nullptr, path.out()); + return env->ThrowUVException( + static_cast(req.result), "open", nullptr, path.out()); } } @@ -2547,7 +2573,8 @@ static void ReadFileUtf8(const FunctionCallbackInfo& args) { if (req.result < 0) { FS_SYNC_TRACE_END(read); // req will be cleaned up by scope leave. - return env->ThrowUVException(req.result, "read", nullptr); + return env->ThrowUVException( + static_cast(req.result), "read", nullptr); } if (r <= 0) { break; @@ -2620,6 +2647,7 @@ static void Chmod(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); @@ -2682,6 +2710,7 @@ static void Chown(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); CHECK(IsSafeJsInt(args[1])); const uv_uid_t uid = static_cast(args[1].As()->Value()); @@ -2756,6 +2785,7 @@ static void LChown(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); CHECK(IsSafeJsInt(args[1])); const uv_uid_t uid = static_cast(args[1].As()->Value()); @@ -2795,6 +2825,7 @@ static void UTimes(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); @@ -2858,6 +2889,7 @@ static void LUTimes(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); + ToNamespacedPath(env, &path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); diff --git a/src/node_url.cc b/src/node_url.cc index 74b639c23084b5..bf0de4ccdf12f9 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -6,6 +6,7 @@ #include "node_i18n.h" #include "node_metadata.h" #include "node_process-inl.h" +#include "path.h" #include "util-inl.h" #include "v8-fast-api-calls.h" #include "v8.h" diff --git a/src/path.cc b/src/path.cc index af9dae4071d794..c084d8ff1aef66 100644 --- a/src/path.cc +++ b/src/path.cc @@ -3,7 +3,6 @@ #include #include "env-inl.h" #include "node_internals.h" -#include "util.h" namespace node { @@ -89,7 +88,7 @@ std::string NormalizeString(const std::string_view path, } #ifdef _WIN32 -bool IsWindowsDeviceRoot(const char c) noexcept { +constexpr bool IsWindowsDeviceRoot(const char c) noexcept { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } @@ -267,4 +266,52 @@ std::string PathResolve(Environment* env, } #endif // _WIN32 +void ToNamespacedPath(Environment* env, BufferValue* path) { +#ifdef _WIN32 + if (path->length() == 0) return; + auto resolved_path = node::PathResolve(env, {path->ToStringView()}); + if (resolved_path.size() <= 2) { + return; + } + + // SAFETY: We know that resolved_path.size() > 2, therefore accessing [0], + // [1], and [2] is safe. + if (resolved_path[0] == '\\') { + // Possible UNC root + if (resolved_path[1] == '\\') { + if (resolved_path[2] != '?' && resolved_path[2] != '.') { + // Matched non-long UNC root, convert the path to a long UNC path + std::string_view unc_prefix = R"(\\?\UNC\)"; + std::string_view resolved_path2 = resolved_path.substr(2); + size_t new_length = unc_prefix.size() + resolved_path2.size(); + path->AllocateSufficientStorage(new_length + 1); + path->SetLength(new_length); + memcpy(path->out(), unc_prefix.data(), unc_prefix.size()); + memcpy(path->out() + unc_prefix.size(), + resolved_path.c_str() + 2, + resolved_path2.size() + 1); + return; + } + } + } else if (IsWindowsDeviceRoot(resolved_path[0]) && resolved_path[1] == ':' && + resolved_path[2] == '\\') { + // Matched device root, convert the path to a long UNC path + std::string_view new_prefix = R"(\\?\)"; + size_t new_length = new_prefix.size() + resolved_path.size(); + path->AllocateSufficientStorage(new_length + 1); + path->SetLength(new_length); + memcpy(path->out(), new_prefix.data(), new_prefix.size()); + memcpy(path->out() + new_prefix.size(), + resolved_path.c_str(), + resolved_path.size() + 1); + return; + } + + size_t new_length = resolved_path.size(); + path->AllocateSufficientStorage(new_length + 1); + path->SetLength(new_length); + memcpy(path->out(), resolved_path.c_str(), resolved_path.size() + 1); +#endif +} + } // namespace node diff --git a/src/path.h b/src/path.h index 532c5f5849652c..3d3354fe32b494 100644 --- a/src/path.h +++ b/src/path.h @@ -5,11 +5,11 @@ #include #include +#include "node_options-inl.h" +#include "util-inl.h" namespace node { -class Environment; - bool IsPathSeparator(const char c) noexcept; std::string NormalizeString(const std::string_view path, @@ -17,7 +17,14 @@ std::string NormalizeString(const std::string_view path, const std::string_view separator); std::string PathResolve(Environment* env, - const std::vector& args); + const std::vector& paths); + +#ifdef _WIN32 +constexpr bool IsWindowsDeviceRoot(const char c) noexcept; +#endif // _WIN32 + +void ToNamespacedPath(Environment* env, BufferValue* path); + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/test/cctest/test_path.cc b/test/cctest/test_path.cc index 44f3b30ddff341..16bd9872f3b035 100644 --- a/test/cctest/test_path.cc +++ b/test/cctest/test_path.cc @@ -4,8 +4,12 @@ #include "node_options.h" #include "node_test_fixture.h" #include "path.h" +#include "util.h" +#include "v8.h" +using node::BufferValue; using node::PathResolve; +using node::ToNamespacedPath; class PathTest : public EnvironmentTestFixture {}; @@ -45,3 +49,43 @@ TEST_F(PathTest, PathResolve) { "/foo/tmp.3/cycles/root.js"); #endif } + +TEST_F(PathTest, ToNamespacedPath) { + const v8::HandleScope handle_scope(isolate_); + Argv argv; + Env env{handle_scope, argv, node::EnvironmentFlags::kNoBrowserGlobals}; +#ifdef _WIN32 + BufferValue data(isolate_, + v8::String::NewFromUtf8(isolate_, "").ToLocalChecked()); + ToNamespacedPath(*env, &data); + EXPECT_EQ(data.ToStringView(), ""); // Empty string should not be mutated + BufferValue data_2( + isolate_, v8::String::NewFromUtf8(isolate_, "C://").ToLocalChecked()); + ToNamespacedPath(*env, &data_2); + EXPECT_EQ(data_2.ToStringView(), "\\\\?\\C:\\"); + BufferValue data_3( + isolate_, + v8::String::NewFromUtf8( + isolate_, + "C:\\workspace\\node-test-binary-windows-js-" + "suites\\node\\test\\fixtures\\permission\\deny\\protected-file.md") + .ToLocalChecked()); + ToNamespacedPath(*env, &data_3); + EXPECT_EQ( + data_3.ToStringView(), + "\\\\?\\C:\\workspace\\node-test-binary-windows-js-" + "suites\\node\\test\\fixtures\\permission\\deny\\protected-file.md"); + BufferValue data_4( + isolate_, + v8::String::NewFromUtf8(isolate_, "\\\\?\\c:\\Windows/System") + .ToLocalChecked()); + ToNamespacedPath(*env, &data_4); + EXPECT_EQ(data_4.ToStringView(), "\\\\?\\c:\\Windows\\System"); +#else + BufferValue data( + isolate_, + v8::String::NewFromUtf8(isolate_, "hello world").ToLocalChecked()); + ToNamespacedPath(*env, &data); + EXPECT_EQ(data.ToStringView(), "hello world"); // Input should not be mutated +#endif +} diff --git a/test/parallel/test-fs-mkdir.js b/test/parallel/test-fs-mkdir.js index 95e9c56974132a..eac13f3cac5d4a 100644 --- a/test/parallel/test-fs-mkdir.js +++ b/test/parallel/test-fs-mkdir.js @@ -271,11 +271,11 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) { const firstPathCreated = tmpdir.resolve(dir1); const pathname = tmpdir.resolve(dir1, dir2); - fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, path) { + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, result) { assert.strictEqual(err, null); assert.strictEqual(fs.existsSync(pathname), true); assert.strictEqual(fs.statSync(pathname).isDirectory(), true); - assert.strictEqual(path, firstPathCreated); + assert.strictEqual(result, path.toNamespacedPath(firstPathCreated)); })); } @@ -285,11 +285,11 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) { const dir2 = nextdir(); const pathname = tmpdir.resolve(dir1, dir2); fs.mkdirSync(tmpdir.resolve(dir1)); - fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, path) { + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, result) { assert.strictEqual(err, null); assert.strictEqual(fs.existsSync(pathname), true); assert.strictEqual(fs.statSync(pathname).isDirectory(), true); - assert.strictEqual(path, pathname); + assert.strictEqual(result, path.toNamespacedPath(pathname)); })); } @@ -316,7 +316,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) { const p = fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true })); assert.strictEqual(fs.existsSync(pathname), true); assert.strictEqual(fs.statSync(pathname).isDirectory(), true); - assert.strictEqual(p, firstPathCreated); + assert.strictEqual(p, path.toNamespacedPath(firstPathCreated)); } // `mkdirp.sync` returns first folder created, when last folder is new. @@ -328,7 +328,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) { const p = fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true })); assert.strictEqual(fs.existsSync(pathname), true); assert.strictEqual(fs.statSync(pathname).isDirectory(), true); - assert.strictEqual(p, pathname); + assert.strictEqual(p, path.toNamespacedPath(pathname)); } // `mkdirp.sync` returns undefined, when no new folders are created. @@ -353,7 +353,7 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) { const p = await fs.promises.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true })); assert.strictEqual(fs.existsSync(pathname), true); assert.strictEqual(fs.statSync(pathname).isDirectory(), true); - assert.strictEqual(p, firstPathCreated); + assert.strictEqual(p, path.toNamespacedPath(firstPathCreated)); } testCase(); }