diff --git a/js/private/node-patches/fs.cjs b/js/private/node-patches/fs.cjs index af980844d..d8a9eb000 100644 --- a/js/private/node-patches/fs.cjs +++ b/js/private/node-patches/fs.cjs @@ -45,18 +45,38 @@ const util = require("util"); // using require here on purpose so we can override methods with any // also even though imports are mutable in typescript the cognitive dissonance is too high because // es modules -const _fs = require('node:fs'); +const fs = require('node:fs'); const url = require('node:url'); const HOP_NON_LINK = Symbol.for('HOP NON LINK'); const HOP_NOT_FOUND = Symbol.for('HOP NOT FOUND'); -function patcher(fs = _fs, roots) { - fs = fs || _fs; +const PATCHED_FS_METHODS = [ + 'lstat', + 'lstatSync', + 'realpath', + 'realpathSync', + 'readlink', + 'readlinkSync', + 'readdir', + 'readdirSync', + 'opendir', +]; +/** + * Function that patches the `fs` module to not escape the given roots. + * @returns a function to undo the patches. + */ +function patcher(roots) { + if (fs._unpatched) { + throw new Error('FS is already patched.'); + } // Make the original version of the library available for when access to the // unguarded file system is necessary, such as the esbuild plugin that // protects against sandbox escaping that occurs through module resolution // in the Go binary. See // https://github.com/aspect-build/rules_esbuild/issues/58. - fs._unpatched = Object.assign({}, fs); + fs._unpatched = PATCHED_FS_METHODS.reduce((obj, method) => { + obj[method] = fs[method]; + return obj; + }, {}); roots = roots || []; roots = roots.filter((root) => fs.existsSync(root)); if (!roots.length) { @@ -245,15 +265,8 @@ function patcher(fs = _fs, roots) { !isEscape(resolved, next, [escapedRoot])) { return cb(null, next); } - // The escape from the root is not mappable back into the root; we must make - // this look like a real file so we call readlink on the realpath which we - // expect to return an error - return origRealpath(resolved, readlinkRealpathCb); - function readlinkRealpathCb(err, str) { - if (err) - return cb(err); - return origReadlink(str, cb); - } + // The escape from the root is not mappable back into the root; throw EINVAL + return cb(einval('readlink', args[0])); } } else { @@ -366,6 +379,7 @@ function patcher(fs = _fs, roots) { * this api is available as experimental without a flag so users can access it at any time. */ const promisePropertyDescriptor = Object.getOwnPropertyDescriptor(fs, 'promises'); + let unpatchPromises; if (promisePropertyDescriptor) { const promises = {}; promises.lstat = util.promisify(fs.lstat); @@ -380,16 +394,28 @@ function patcher(fs = _fs, roots) { if (promisePropertyDescriptor.get) { const oldGetter = promisePropertyDescriptor.get.bind(fs); const cachedPromises = {}; - promisePropertyDescriptor.get = () => { + function promisePropertyGetter() { const _promises = oldGetter(); Object.assign(cachedPromises, _promises, promises); return cachedPromises; + } + Object.defineProperty(fs, 'promises', Object.assign(Object.create(promisePropertyDescriptor), { + get: promisePropertyGetter, + })); + unpatchPromises = function unpatchFsPromises() { + Object.defineProperty(fs, 'promises', promisePropertyDescriptor); }; - Object.defineProperty(fs, 'promises', promisePropertyDescriptor); } else { + const unpatchedPromises = Object.keys(promises).reduce((obj, method) => { + obj[method] = fs.promises[method]; + return obj; + }, Object.create(fs.promises)); // api can be patched directly Object.assign(fs.promises, promises); + unpatchPromises = function unpatchFsPromises() { + Object.assign(fs.promises, unpatchedPromises); + }; } } // ========================================================================= @@ -721,6 +747,13 @@ function patcher(fs = _fs, roots) { } } } + return function revertPatch() { + Object.assign(fs, fs._unpatched); + delete fs._unpatched; + if (unpatchPromises) { + unpatchPromises(); + } + }; } // ========================================================================= // generic helper functions diff --git a/js/private/node-patches/register.cjs b/js/private/node-patches/register.cjs index 944e576ae..3f8ac24c9 100644 --- a/js/private/node-patches/register.cjs +++ b/js/private/node-patches/register.cjs @@ -35,7 +35,6 @@ if ( JS_BINARY__PATCH_NODE_FS != '0' && JS_BINARY__FS_PATCH_ROOTS ) { - const fs = require('node:fs') const module = require('node:module') const roots = JS_BINARY__FS_PATCH_ROOTS.split(':') if (JS_BINARY__LOG_DEBUG) { @@ -43,7 +42,7 @@ if ( `DEBUG: ${JS_BINARY__LOG_PREFIX}: node fs patches will be applied with roots: ${roots}` ) } - patchfs(fs, roots) + patchfs(roots) // Sync the esm modules to use the now patched fs cjs module. // See: https://nodejs.org/api/esm.html#builtin-modules diff --git a/js/private/node-patches/src/fs.cts b/js/private/node-patches/src/fs.cts index b07d4a1a2..ba334bf9d 100644 --- a/js/private/node-patches/src/fs.cts +++ b/js/private/node-patches/src/fs.cts @@ -28,7 +28,7 @@ type Dirent = any // using require here on purpose so we can override methods with any // also even though imports are mutable in typescript the cognitive dissonance is too high because // es modules -const _fs = require('node:fs') as typeof FsType +const fs = require('node:fs') as any const url = require('node:url') as typeof UrlType const HOP_NON_LINK = Symbol.for('HOP NON LINK') @@ -36,14 +36,37 @@ const HOP_NOT_FOUND = Symbol.for('HOP NOT FOUND') type HopResults = string | typeof HOP_NON_LINK | typeof HOP_NOT_FOUND -export function patcher(fs: any = _fs, roots: string[]) { - fs = fs || _fs +const PATCHED_FS_METHODS: ReadonlyArray = [ + 'lstat', + 'lstatSync', + 'realpath', + 'realpathSync', + 'readlink', + 'readlinkSync', + 'readdir', + 'readdirSync', + 'opendir', +] + +/** + * Function that patches the `fs` module to not escape the given roots. + * @returns a function to undo the patches. + */ +export function patcher(roots: string[]): () => void { + if (fs._unpatched) { + throw new Error('FS is already patched.') + } + // Make the original version of the library available for when access to the // unguarded file system is necessary, such as the esbuild plugin that // protects against sandbox escaping that occurs through module resolution // in the Go binary. See // https://github.com/aspect-build/rules_esbuild/issues/58. - fs._unpatched = { ...fs } + fs._unpatched = PATCHED_FS_METHODS.reduce((obj, method) => { + obj[method] = fs[method] + return obj + }, {}) + roots = roots || [] roots = roots.filter((root) => fs.existsSync(root)) if (!roots.length) { @@ -283,18 +306,8 @@ export function patcher(fs: any = _fs, roots: string[]) { ) { return cb(null, next) } - // The escape from the root is not mappable back into the root; we must make - // this look like a real file so we call readlink on the realpath which we - // expect to return an error - return origRealpath(resolved, readlinkRealpathCb) - - function readlinkRealpathCb( - err: NodeJS.ErrnoException, - str: string - ) { - if (err) return cb(err) - return origReadlink(str, cb) - } + // The escape from the root is not mappable back into the root; throw EINVAL + return cb(einval('readlink', args[0])) } } else { return cb(null, str) @@ -434,6 +447,9 @@ export function patcher(fs: any = _fs, roots: string[]) { fs, 'promises' ) + + let unpatchPromises: Function + if (promisePropertyDescriptor) { const promises: any = {} promises.lstat = util.promisify(fs.lstat) @@ -448,15 +464,36 @@ export function patcher(fs: any = _fs, roots: string[]) { const oldGetter = promisePropertyDescriptor.get.bind(fs) const cachedPromises = {} - promisePropertyDescriptor.get = () => { + function promisePropertyGetter() { const _promises = oldGetter() Object.assign(cachedPromises, _promises, promises) return cachedPromises } - Object.defineProperty(fs, 'promises', promisePropertyDescriptor) + Object.defineProperty( + fs, + 'promises', + Object.assign(Object.create(promisePropertyDescriptor), { + get: promisePropertyGetter, + }) + ) + + unpatchPromises = function unpatchFsPromises() { + Object.defineProperty(fs, 'promises', promisePropertyDescriptor) + } } else { + const unpatchedPromises = Object.keys(promises).reduce( + (obj, method) => { + obj[method] = fs.promises[method] + return obj + }, + Object.create(fs.promises) + ) + // api can be patched directly Object.assign(fs.promises, promises) + unpatchPromises = function unpatchFsPromises() { + Object.assign(fs.promises, unpatchedPromises) + } } } @@ -819,6 +856,15 @@ export function patcher(fs: any = _fs, roots: string[]) { } } } + + return function revertPatch() { + Object.assign(fs, fs._unpatched) + delete fs._unpatched + + if (unpatchPromises) { + unpatchPromises() + } + } } // ========================================================================= diff --git a/js/private/test/image/checksum_test.expected b/js/private/test/image/checksum_test.expected index d440b34f4..d80058535 100644 --- a/js/private/test/image/checksum_test.expected +++ b/js/private/test/image/checksum_test.expected @@ -1,4 +1,4 @@ -87a6d20e2cabd494a5c1cd816d5d17a5d13cf5b69ab1dd596f22753634ac4ed7 js/private/test/image/cksum_node +a4232a52470e03fc555dfc1bd5a6e83090a71bccad58eb45fbc55f780f84df1e js/private/test/image/cksum_node 52836a988c8ac815b4a3b70fa3a3acec67b851699fa989694cef4cc1fa53de96 js/private/test/image/cksum_package_store_3p 642b308a0561fb51dfd96d08d74a4ec419c9d2ca501cfa1002a49c8e25fbe4c2 js/private/test/image/cksum_package_store_1p 5d45f32dacf0b83e26c33d4e1017c694e79eaff29b8ecc336f9ea8fdee870d45 js/private/test/image/cksum_node_modules diff --git a/js/private/test/image/custom_layers_nomatch_test_node.listing b/js/private/test/image/custom_layers_nomatch_test_node.listing index 3f8272a9f..7930ce9cc 100644 --- a/js/private/test/image/custom_layers_nomatch_test_node.listing +++ b/js/private/test/image/custom_layers_nomatch_test_node.listing @@ -8,8 +8,8 @@ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin. drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/ --r-xr-xr-x 0 0 0 33280 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/fs.cjs --r-xr-xr-x 0 0 0 1702 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/register.cjs +-r-xr-xr-x 0 0 0 34161 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/fs.cjs +-r-xr-xr-x 0 0 0 1664 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/register.cjs drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/nodejs/ diff --git a/js/private/test/image/custom_owner_test_node.listing b/js/private/test/image/custom_owner_test_node.listing index 7caa554c4..4e0c9f2f8 100644 --- a/js/private/test/image/custom_owner_test_node.listing +++ b/js/private/test/image/custom_owner_test_node.listing @@ -7,8 +7,8 @@ drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runf drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/ drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/ drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/ --r-xr-xr-x 0 100 0 33280 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/fs.cjs --r-xr-xr-x 0 100 0 1702 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/register.cjs +-r-xr-xr-x 0 100 0 34161 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/fs.cjs +-r-xr-xr-x 0 100 0 1664 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/register.cjs drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/ drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/ drwxr-xr-x 0 100 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/nodejs/ diff --git a/js/private/test/image/default_test_node.listing b/js/private/test/image/default_test_node.listing index baae703b6..62760724a 100644 --- a/js/private/test/image/default_test_node.listing +++ b/js/private/test/image/default_test_node.listing @@ -7,8 +7,8 @@ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runf drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/ --r-xr-xr-x 0 0 0 33280 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/fs.cjs --r-xr-xr-x 0 0 0 1702 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/register.cjs +-r-xr-xr-x 0 0 0 34161 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/fs.cjs +-r-xr-xr-x 0 0 0 1664 Jan 1 1970 ./js/private/test/image/bin.runfiles/_main/js/private/node-patches/register.cjs drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/nodejs/ diff --git a/js/private/test/image/non_ascii/custom_layer_groups_test_just_the_fs_patch.listing b/js/private/test/image/non_ascii/custom_layer_groups_test_just_the_fs_patch.listing index 5b4ef14a3..21456b164 100644 --- a/js/private/test/image/non_ascii/custom_layer_groups_test_just_the_fs_patch.listing +++ b/js/private/test/image/non_ascii/custom_layer_groups_test_just_the_fs_patch.listing @@ -9,4 +9,4 @@ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-patches/ --r-xr-xr-x 0 0 0 33280 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-patches/fs.cjs +-r-xr-xr-x 0 0 0 34161 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-patches/fs.cjs diff --git a/js/private/test/image/non_ascii/custom_layer_groups_test_node.listing b/js/private/test/image/non_ascii/custom_layer_groups_test_node.listing index 976916477..89ba24f0d 100644 --- a/js/private/test/image/non_ascii/custom_layer_groups_test_node.listing +++ b/js/private/test/image/non_ascii/custom_layer_groups_test_node.listing @@ -9,7 +9,7 @@ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-patches/ --r-xr-xr-x 0 0 0 1702 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-patches/register.cjs +-r-xr-xr-x 0 0 0 1664 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/_main/js/private/node-patches/register.cjs drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/rules_nodejs~~node~nodejs_linux_amd64/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/non_ascii/bin2.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/nodejs/ diff --git a/js/private/test/image/regex_edge_cases_test_node.listing b/js/private/test/image/regex_edge_cases_test_node.listing index 3f8272a9f..7930ce9cc 100644 --- a/js/private/test/image/regex_edge_cases_test_node.listing +++ b/js/private/test/image/regex_edge_cases_test_node.listing @@ -8,8 +8,8 @@ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin. drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/ --r-xr-xr-x 0 0 0 33280 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/fs.cjs --r-xr-xr-x 0 0 0 1702 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/register.cjs +-r-xr-xr-x 0 0 0 34161 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/fs.cjs +-r-xr-xr-x 0 0 0 1664 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/_main/js/private/node-patches/register.cjs drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/ drwxr-xr-x 0 0 0 0 Jan 1 1970 ./app/js/private/test/image/bin.runfiles/rules_nodejs~~node~nodejs_linux_amd64/bin/nodejs/ diff --git a/js/private/test/node-patches/lstat.js b/js/private/test/node-patches/lstat.js index 1c3c8e7d5..55dc42c43 100644 --- a/js/private/test/node-patches/lstat.js +++ b/js/private/test/node-patches/lstat.js @@ -45,27 +45,25 @@ describe('testing lstat', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [path.join(fixturesDir)]) + const revertPatches = patcher([path.join(fixturesDir)]) const linkPath = path.join(fixturesDir, 'a', 'link') assert.ok( - patchedFs.lstatSync(linkPath).isSymbolicLink(), + fs.lstatSync(linkPath).isSymbolicLink(), 'lstatSync should find symbolic link if link is the root' ) assert.ok( - ( - await util.promisify(patchedFs.lstat)(linkPath) - ).isSymbolicLink(), + (await util.promisify(fs.lstat)(linkPath)).isSymbolicLink(), 'lstat should find symbolic link if link is the root' ) assert.ok( - (await patchedFs.promises.lstat(linkPath)).isSymbolicLink(), + (await fs.promises.lstat(linkPath)).isSymbolicLink(), 'promises.lstat should find symbolic link if link is the root' ) + + revertPatches() } ) }) @@ -79,20 +77,19 @@ describe('testing lstat', async () => { async (fixturesDir) => { fixturesDir = fs.realpathSync(fixturesDir) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [ + const revertPatches = patcher([ path.join(fixturesDir), path.join(fixturesDir, 'a', 'g'), ]) assert.equal( undefined, - patchedFs.lstatSync( - path.join(fixturesDir, 'doesnt-exist'), - { throwIfNoEntry: false } - ) + fs.lstatSync(path.join(fixturesDir, 'doesnt-exist'), { + throwIfNoEntry: false, + }) ) + + revertPatches() } ) }) @@ -111,28 +108,31 @@ describe('testing lstat', async () => { path.join(fixturesDir, 'a', 'g', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [ + const revertPatches = patcher([ path.join(fixturesDir), path.join(fixturesDir, 'a', 'g'), ]) + console.error('Starting') + console.error(fs.readlink.toString()) + const linkPath = path.join(fixturesDir, 'a', 'g', 'link') assert.ok( - patchedFs.lstatSync(linkPath).isFile(), + fs.lstatSync(linkPath).isFile(), 'lstatSync should find file if link is in guard' ) assert.ok( - (await util.promisify(patchedFs.lstat)(linkPath)).isFile(), + (await util.promisify(fs.lstat)(linkPath)).isFile(), 'lstat should find file if link is in guard' ) assert.ok( - (await patchedFs.promises.lstat(linkPath)).isFile(), + (await fs.promises.lstat(linkPath)).isFile(), 'promises.lstat should find file if link is in guard' ) + + revertPatches() } ) }) @@ -151,24 +151,22 @@ describe('testing lstat', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [path.join(fixturesDir, 'a')]) + const revertPatches = patcher([path.join(fixturesDir, 'a')]) const linkPath = path.join(fixturesDir, 'a', 'link') assert.ok( - patchedFs.lstatSync(linkPath).isFile(), + fs.lstatSync(linkPath).isFile(), 'lstatSync should find file it file link is out of root' ) assert.ok( - (await util.promisify(patchedFs.lstat)(linkPath)).isFile(), + (await util.promisify(fs.lstat)(linkPath)).isFile(), 'lstat should find file it file link is out of root' ) assert.ok( - (await patchedFs.promises.lstat(linkPath)).isFile(), + (await fs.promises.lstat(linkPath)).isFile(), 'promises.lstat should find file it file link is out of root' ) @@ -179,19 +177,17 @@ describe('testing lstat', async () => { ) assert.ok( - patchedFs.lstatSync(brokenLinkPath).isSymbolicLink(), + fs.lstatSync(brokenLinkPath).isSymbolicLink(), 'if a symlink is broken but is escaping return it as a link.' ) assert.ok( ( - await util.promisify(patchedFs.lstat)(brokenLinkPath) + await util.promisify(fs.lstat)(brokenLinkPath) ).isSymbolicLink(), 'if a symlink is broken but is escaping return it as a link.' ) assert.ok( - ( - await patchedFs.promises.lstat(brokenLinkPath) - ).isSymbolicLink(), + (await fs.promises.lstat(brokenLinkPath)).isSymbolicLink(), 'if a symlink is broken but is escaping return it as a link.' ) @@ -201,11 +197,13 @@ describe('testing lstat', async () => { brokenLinkPath ) - stat = await patchedFs.promises.lstat(brokenLinkPath) + stat = await fs.promises.lstat(brokenLinkPath) assert.ok( stat.isSymbolicLink(), 'if a symlink is broken but not escaping return it as a link.' ) + + revertPatches() } ) }) @@ -224,34 +222,34 @@ describe('testing lstat', async () => { path.join(fixturesDir, 'b', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [path.join(fixturesDir, 'a')]) + const revertPatches = patcher([path.join(fixturesDir, 'a')]) const linkPath = path.join(fixturesDir, 'b', 'link') assert.ok( - patchedFs.lstatSync(linkPath).isSymbolicLink(), + fs.lstatSync(linkPath).isSymbolicLink(), 'lstatSync should find symbolic link if link is out of the root' ) assert.ok( - patchedFs + fs .lstatSync(new URL(`file://${linkPath}`)) .isSymbolicLink(), 'lstatSync should find symbolic link if link is out of the root' ) - const stat = await util.promisify(patchedFs.lstat)(linkPath) + const stat = await util.promisify(fs.lstat)(linkPath) assert.ok( stat.isSymbolicLink(), 'lstat should find symbolic link if link is outside' ) assert.ok( - (await patchedFs.promises.lstat(linkPath)).isSymbolicLink(), + (await fs.promises.lstat(linkPath)).isSymbolicLink(), 'promises.lstat should find symbolic link if link is outside' ) + + revertPatches() } ) }) diff --git a/js/private/test/node-patches/opendir.js b/js/private/test/node-patches/opendir.js index f6c4dd462..1a7be4ddb 100644 --- a/js/private/test/node-patches/opendir.js +++ b/js/private/test/node-patches/opendir.js @@ -45,12 +45,10 @@ describe('testing opendir', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [fixturesDir]) + const revertPatches = patcher([fixturesDir]) let dir - dir = await util.promisify(patchedFs.opendir)( + dir = await util.promisify(fs.opendir)( path.join(fixturesDir, 'a') ) const entry1 = await dir.read() @@ -67,10 +65,12 @@ describe('testing opendir', async () => { assert.ok(!empty, 'last read should be falsey') // Assert reading via URL produces the same (first) result. - dir = await util.promisify(patchedFs.opendir)( + dir = await util.promisify(fs.opendir)( new URL(`file://${path.join(fixturesDir, 'a')}`) ) assert.equal(entry1.name, (await dir.read()).name) + + revertPatches() } ) }) @@ -89,12 +89,10 @@ describe('testing opendir', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [path.join(fixturesDir, 'a')]) + const revertPatches = patcher([path.join(fixturesDir, 'a')]) let dir - dir = await util.promisify(patchedFs.opendir)( + dir = await util.promisify(fs.opendir)( path.join(fixturesDir, 'a') ) const entry1 = await dir.read() @@ -111,6 +109,8 @@ describe('testing opendir', async () => { console.error(entry1, entry2) assert.ok(!maybeLink.isSymbolicLink()) + + revertPatches() } ) }) @@ -129,11 +129,9 @@ describe('testing opendir', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [path.join(fixturesDir)]) + const revertPatches = patcher([path.join(fixturesDir)]) - const dir = await util.promisify(patchedFs.opendir)( + const dir = await util.promisify(fs.opendir)( path.join(fixturesDir, 'a') ) const names = [] @@ -147,6 +145,8 @@ describe('testing opendir', async () => { } names.sort() assert.deepStrictEqual(names, ['apples', 'link']) + + revertPatches() } ) }) @@ -165,11 +165,9 @@ describe('testing opendir', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [path.join(fixturesDir, 'a')]) + const revertPatches = patcher([path.join(fixturesDir, 'a')]) - const dir = await util.promisify(patchedFs.opendir)( + const dir = await util.promisify(fs.opendir)( path.join(fixturesDir, 'a') ) const names = [] @@ -184,6 +182,8 @@ describe('testing opendir', async () => { } names.sort() assert.deepStrictEqual(names, ['apples', 'link']) + + revertPatches() } ) }) @@ -222,13 +222,12 @@ describe('testing opendir', async () => { path.join(fixturesDir, 'sandbox', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir, 'sandbox')]) + const revertPatches = patcher([ + path.join(fixturesDir, 'sandbox'), + ]) let dir - dir = await util.promisify(patchedFs.opendir)( + dir = await util.promisify(fs.opendir)( path.join(fixturesDir, 'sandbox') ) const entry1 = await dir.read() @@ -257,6 +256,8 @@ describe('testing opendir', async () => { ) assert.ok(!empty, 'last read should be falsey') + + revertPatches() } ) }) diff --git a/js/private/test/node-patches/readdir.js b/js/private/test/node-patches/readdir.js index df3ce626d..9d1dbc40e 100644 --- a/js/private/test/node-patches/readdir.js +++ b/js/private/test/node-patches/readdir.js @@ -45,22 +45,17 @@ describe('testing readdir', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [fixturesDir]) + const revertPatches = patcher([fixturesDir]) - let dirents = patchedFs.readdirSync( - path.join(fixturesDir, 'a'), - { - withFileTypes: true, - } - ) + let dirents = fs.readdirSync(path.join(fixturesDir, 'a'), { + withFileTypes: true, + }) assert.deepStrictEqual(dirents[0].name, 'apples') assert.deepStrictEqual(dirents[1].name, 'link') assert.ok(dirents[0].isFile()) assert.ok(dirents[1].isSymbolicLink()) - dirents = await util.promisify(patchedFs.readdir)( + dirents = await util.promisify(fs.readdir)( path.join(fixturesDir, 'a'), { withFileTypes: true } ) @@ -69,7 +64,7 @@ describe('testing readdir', async () => { assert.ok(dirents[0].isFile()) assert.ok(dirents[1].isSymbolicLink()) - dirents = await patchedFs.promises.readdir( + dirents = await fs.promises.readdir( path.join(fixturesDir, 'a'), { withFileTypes: true } ) @@ -79,7 +74,7 @@ describe('testing readdir', async () => { assert.ok(dirents[1].isSymbolicLink()) // Assert the same with URL file references - dirents = patchedFs.readdirSync( + dirents = fs.readdirSync( new URL(`file://${path.join(fixturesDir, 'a')}`), { withFileTypes: true, @@ -89,6 +84,8 @@ describe('testing readdir', async () => { assert.deepStrictEqual(dirents[1].name, 'link') assert.ok(dirents[0].isFile()) assert.ok(dirents[1].isSymbolicLink()) + + revertPatches() } ) }) @@ -107,18 +104,13 @@ describe('testing readdir', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - patcher(patchedFs, [path.join(fixturesDir, 'a')]) + const revertPatches = patcher([path.join(fixturesDir, 'a')]) console.error('FOO') - console.error(patchedFs.readdirSync) - let dirents = patchedFs.readdirSync( - path.join(fixturesDir, 'a'), - { - withFileTypes: true, - } - ) + console.error(fs.readdirSync) + let dirents = fs.readdirSync(path.join(fixturesDir, 'a'), { + withFileTypes: true, + }) console.error('BAR') console.log(dirents) assert.deepStrictEqual(dirents[0].name, 'apples') @@ -128,7 +120,7 @@ describe('testing readdir', async () => { assert.ok(dirents[1].isFile()) console.error('FOO') - dirents = await util.promisify(patchedFs.readdir)( + dirents = await util.promisify(fs.readdir)( path.join(fixturesDir, 'a'), { withFileTypes: true } ) @@ -139,7 +131,7 @@ describe('testing readdir', async () => { assert.ok(!dirents[1].isSymbolicLink()) assert.ok(dirents[1].isFile()) - dirents = await patchedFs.promises.readdir( + dirents = await fs.promises.readdir( path.join(fixturesDir, 'a'), { withFileTypes: true } ) @@ -148,6 +140,8 @@ describe('testing readdir', async () => { assert.ok(dirents[0].isFile()) assert.ok(!dirents[1].isSymbolicLink()) assert.ok(dirents[1].isFile()) + + revertPatches() } ) }) @@ -186,12 +180,11 @@ describe('testing readdir', async () => { path.join(fixturesDir, 'sandbox', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir, 'sandbox')]) + const revertPatches = patcher([ + path.join(fixturesDir, 'sandbox'), + ]) - let dirents = patchedFs.readdirSync( + let dirents = fs.readdirSync( path.join(fixturesDir, 'sandbox'), { withFileTypes: true, @@ -204,7 +197,7 @@ describe('testing readdir', async () => { assert.ok(dirents[1].isSymbolicLink()) assert.ok(dirents[2].isSymbolicLink()) - dirents = await util.promisify(patchedFs.readdir)( + dirents = await util.promisify(fs.readdir)( path.join(fixturesDir, 'sandbox'), { withFileTypes: true } ) @@ -215,7 +208,7 @@ describe('testing readdir', async () => { assert.ok(dirents[1].isSymbolicLink()) assert.ok(dirents[2].isSymbolicLink()) - dirents = await patchedFs.promises.readdir( + dirents = await fs.promises.readdir( path.join(fixturesDir, 'sandbox'), { withFileTypes: true } ) @@ -225,6 +218,8 @@ describe('testing readdir', async () => { assert.ok(dirents[0].isFile()) assert.ok(dirents[1].isSymbolicLink()) assert.ok(dirents[2].isSymbolicLink()) + + revertPatches() } ) }) diff --git a/js/private/test/node-patches/readlink.js b/js/private/test/node-patches/readlink.js index 21797a8f7..556bf6cc7 100644 --- a/js/private/test/node-patches/readlink.js +++ b/js/private/test/node-patches/readlink.js @@ -45,35 +45,43 @@ describe('testing readlink', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) + const revertPatches = patcher([path.join(fixturesDir)]) - patcher(patchedFs, [path.join(fixturesDir)]) const linkPath = path.join(fixturesDir, 'a', 'link') assert.deepStrictEqual( - patchedFs.readlinkSync(linkPath), + fs.readlinkSync(linkPath), path.join(fixturesDir, 'b', 'file'), 'SYNC: should read the symlink because its within root' ) assert.deepStrictEqual( - patchedFs.readlinkSync(new URL(`file://${linkPath}`)), + fs.readlinkSync(new URL(`file://${linkPath}`)), path.join(fixturesDir, 'b', 'file'), 'SYNC: should read the symlink because its within root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.readlink)(linkPath), + await util.promisify(fs.readlink)( + new URL(`file://${linkPath}`) + ), path.join(fixturesDir, 'b', 'file'), 'CB: should read the symlink because its within root' ) assert.deepStrictEqual( - await patchedFs.promises.readlink(linkPath), + await util.promisify(fs.readlink)(linkPath), + path.join(fixturesDir, 'b', 'file'), + 'CB: should read the symlink because its within root' + ) + + assert.deepStrictEqual( + await fs.promises.readlink(linkPath), path.join(fixturesDir, 'b', 'file'), 'Promise: should read the symlink because its within root' ) + + revertPatches() } ) }) @@ -92,10 +100,8 @@ describe('testing readlink', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) + const revertPatches = patcher([path.join(fixturesDir, 'a')]) - patcher(patchedFs, [path.join(fixturesDir, 'a')]) const linkPath = path.join( fs.realpathSync(fixturesDir), 'a', @@ -103,12 +109,12 @@ describe('testing readlink', async () => { ) assert.throws(() => { - patchedFs.readlinkSync(linkPath) + fs.readlinkSync(linkPath) }, "should throw because it's not a link") let thrown try { - await util.promisify(patchedFs.readlink)(linkPath) + await util.promisify(fs.readlink)(linkPath) } catch (e) { thrown = e } finally { @@ -117,12 +123,14 @@ describe('testing readlink', async () => { thrown = undefined try { - await patchedFs.promises.readlink(linkPath) + await fs.promises.readlink(linkPath) } catch (e) { thrown = e } finally { if (!thrown) assert.fail('must throw einval error') } + + revertPatches() } ) }) @@ -152,36 +160,45 @@ describe('testing readlink', async () => { path.join(fixturesDir, 'sandbox', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir, 'sandbox')]) + const revertPatches = patcher([ + path.join(fixturesDir, 'sandbox'), + ]) const linkPath = path.join(fixturesDir, 'sandbox', 'link') const filePath = path.join(fixturesDir, 'sandbox', 'file') assert.deepStrictEqual( - patchedFs.readlinkSync(linkPath), + fs.readlinkSync(linkPath), filePath, 'SYNC: should read the symlink in the sandbox' ) assert.deepStrictEqual( - patchedFs.readlinkSync(new URL(`file://${linkPath}`)), + fs.readlinkSync(new URL(`file://${linkPath}`)), filePath, 'SYNC: should read the symlink in the sandbox' ) assert.deepStrictEqual( - await util.promisify(patchedFs.readlink)(linkPath), + await util.promisify(fs.readlink)( + new URL(`file://${linkPath}`) + ), filePath, 'CB: should read the symlink in the sandbox' ) assert.deepStrictEqual( - await patchedFs.promises.readlink(linkPath), + await util.promisify(fs.readlink)(linkPath), + filePath, + 'CB: should read the symlink in the sandbox' + ) + + assert.deepStrictEqual( + await fs.promises.readlink(linkPath), filePath, 'Promise: should read the symlink in the sandbox' ) + + revertPatches() } ) }) @@ -207,20 +224,20 @@ describe('testing readlink', async () => { path.join(fixturesDir, 'sandbox', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) + const revertPatches = patcher([ + path.join(fixturesDir, 'sandbox'), + ]) - patcher(patchedFs, [path.join(fixturesDir, 'sandbox')]) const linkPath = path.join(fixturesDir, 'sandbox', 'link') const filePath = path.join(fixturesDir, 'sandbox', 'file') assert.throws(() => { - patchedFs.readlinkSync(linkPath) + fs.readlinkSync(linkPath) }, "should throw because it's not a resolvable link") let thrown try { - await util.promisify(patchedFs.readlink)(linkPath) + await util.promisify(fs.readlink)(linkPath) } catch (e) { thrown = e } finally { @@ -229,12 +246,14 @@ describe('testing readlink', async () => { thrown = undefined try { - await patchedFs.promises.readlink(linkPath) + await fs.promises.readlink(linkPath) } catch (e) { thrown = e } finally { if (!thrown) assert.fail('must throw einval error') } + + revertPatches() } ) }) diff --git a/js/private/test/node-patches/realpath.js b/js/private/test/node-patches/realpath.js index c316387e2..e4e694a14 100644 --- a/js/private/test/node-patches/realpath.js +++ b/js/private/test/node-patches/realpath.js @@ -32,33 +32,30 @@ async function it(_, fn) { describe('testing realpath', async () => { await it('can handle empty, dot, undefined & null values', async () => { - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [process.cwd()]) + const revertPatches = patcher([process.cwd()]) // --------------------------------------------------------------------- // empty string assert.deepStrictEqual( - patchedFs.realpathSync(''), + fs.realpathSync(''), process.cwd(), 'should handle an empty string' ) assert.throws(() => { - patchedFs.realpathSync.native('') + fs.realpathSync.native('') }, 'should throw if empty string is passed') assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)(''), + await util.promisify(fs.realpath)(''), process.cwd(), 'should handle an empty string' ) let thrown try { - await util.promisify(patchedFs.realpath.native)('') + await util.promisify(fs.realpath.native)('') } catch (e) { thrown = e } finally { @@ -69,25 +66,25 @@ describe('testing realpath', async () => { // '.' assert.deepStrictEqual( - patchedFs.realpathSync('.'), + fs.realpathSync('.'), process.cwd(), "should handle '.'" ) assert.deepStrictEqual( - patchedFs.realpathSync.native('.'), + fs.realpathSync.native('.'), process.cwd(), "should handle '.'" ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)('.'), + await util.promisify(fs.realpath)('.'), process.cwd(), "should handle '.'" ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath.native)('.'), + await util.promisify(fs.realpath.native)('.'), process.cwd(), "should handle '.'" ) @@ -96,16 +93,16 @@ describe('testing realpath', async () => { // undefined assert.throws(() => { - patchedFs.realpathSync(undefined) + fs.realpathSync(undefined) }, 'should throw if undefined is passed') assert.throws(() => { - patchedFs.realpathSync.native(undefined) + fs.realpathSync.native(undefined) }, 'should throw if undefined is passed') thrown = undefined try { - await util.promisify(patchedFs.realpath)(undefined) + await util.promisify(fs.realpath)(undefined) } catch (e) { thrown = e } finally { @@ -114,7 +111,7 @@ describe('testing realpath', async () => { thrown = undefined try { - await util.promisify(patchedFs.realpath.native)(undefined) + await util.promisify(fs.realpath.native)(undefined) } catch (e) { thrown = e } finally { @@ -125,16 +122,16 @@ describe('testing realpath', async () => { // null assert.throws(() => { - patchedFs.realpathSync(null) + fs.realpathSync(null) }, 'should throw if null is passed') assert.throws(() => { - patchedFs.realpathSync.native(null) + fs.realpathSync.native(null) }, 'should throw if null is passed') thrown = undefined try { - await util.promisify(patchedFs.realpath)(null) + await util.promisify(fs.realpath)(null) } catch (e) { thrown = e } finally { @@ -143,12 +140,14 @@ describe('testing realpath', async () => { thrown = undefined try { - await util.promisify(patchedFs.realpath.native)(null) + await util.promisify(fs.realpath.native)(null) } catch (e) { thrown = e } finally { if (!thrown) assert.fail('should throw if null is passed') } + + revertPatches() }) await it('can resolve symlink in root', async () => { @@ -167,10 +166,7 @@ describe('testing realpath', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir)]) + const revertPatches = patcher([path.join(fixturesDir)]) const linkPath = path.join( fs.realpathSync(fixturesDir), 'a', @@ -178,34 +174,36 @@ describe('testing realpath', async () => { ) assert.deepStrictEqual( - patchedFs.realpathSync(linkPath), + fs.realpathSync(linkPath), path.join(fixturesDir, 'b', 'file'), 'SYNC: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - patchedFs.realpathSync.native(linkPath), + fs.realpathSync.native(linkPath), path.join(fixturesDir, 'b', 'file'), 'SYNC.native: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)(linkPath), + await util.promisify(fs.realpath)(linkPath), path.join(fixturesDir, 'b', 'file'), 'CB: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath.native)(linkPath), + await util.promisify(fs.realpath.native)(linkPath), path.join(fixturesDir, 'b', 'file'), 'CB: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - await patchedFs.promises.realpath(linkPath), + await fs.promises.realpath(linkPath), path.join(fixturesDir, 'b', 'file'), 'Promise: should resolve the symlink the same because its within root' ) + + revertPatches() } ) }) @@ -219,10 +217,7 @@ describe('testing realpath', async () => { // on mac, inside of bazel, the fixtures dir returned here is not realpath-ed. fixturesDir = fs.realpathSync(fixturesDir) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir)]) + const revertPatches = patcher([path.join(fixturesDir)]) const filePath = path.join( fs.realpathSync(fixturesDir), 'a', @@ -230,31 +225,31 @@ describe('testing realpath', async () => { ) assert.deepStrictEqual( - patchedFs.realpathSync(filePath), + fs.realpathSync(filePath), filePath, 'SYNC: should resolve the a real file within the root' ) assert.deepStrictEqual( - patchedFs.realpathSync.native(filePath), + fs.realpathSync.native(filePath), filePath, 'SYNC.native: should resolve the a real file within the root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)(filePath), + await util.promisify(fs.realpath)(filePath), filePath, 'CB: should resolve the a real file within the root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath.native)(filePath), + await util.promisify(fs.realpath.native)(filePath), filePath, 'CB: should resolve the a real file within the root' ) assert.deepStrictEqual( - await patchedFs.promises.realpath(filePath), + await fs.promises.realpath(filePath), filePath, 'Promise: should resolve the a real file within the root' ) @@ -265,36 +260,36 @@ describe('testing realpath', async () => { ) assert.deepStrictEqual( - patchedFs.realpathSync(directoryPath), + fs.realpathSync(directoryPath), directoryPath, 'SYNC: should resolve the a real directory within the root' ) assert.deepStrictEqual( - patchedFs.realpathSync.native(directoryPath), + fs.realpathSync.native(directoryPath), directoryPath, 'SYNC.native: should resolve the a real directory within the root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)(directoryPath), + await util.promisify(fs.realpath)(directoryPath), directoryPath, 'CB: should resolve the a real directory within the root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath.native)( - directoryPath - ), + await util.promisify(fs.realpath.native)(directoryPath), directoryPath, 'CB: should resolve the a real directory within the root' ) assert.deepStrictEqual( - await patchedFs.promises.realpath(directoryPath), + await fs.promises.realpath(directoryPath), directoryPath, 'Promise: should resolve the a real directory within the root' ) + + revertPatches() } ) }) @@ -315,10 +310,7 @@ describe('testing realpath', async () => { path.join(fixturesDir, 'a', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir, 'a')]) + const revertPatches = patcher([path.join(fixturesDir, 'a')]) const linkPath = path.join( fs.realpathSync(fixturesDir), 'a', @@ -326,36 +318,36 @@ describe('testing realpath', async () => { ) assert.deepStrictEqual( - patchedFs.realpathSync(linkPath), + fs.realpathSync(linkPath), path.join(fixturesDir, 'a', 'link'), 'should pretend symlink is in the root' ) assert.deepStrictEqual( - patchedFs.realpathSync(new URL(`file://${linkPath}`)), + fs.realpathSync(new URL(`file://${linkPath}`)), path.join(fixturesDir, 'a', 'link'), 'should pretend symlink is in the root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)(linkPath), + await util.promisify(fs.realpath)(linkPath), path.join(fixturesDir, 'a', 'link'), 'should pretend symlink is in the root' ) assert.deepStrictEqual( - await patchedFs.promises.realpath(linkPath), + await fs.promises.realpath(linkPath), path.join(fixturesDir, 'a', 'link'), 'should pretend symlink is in the root' ) assert.deepStrictEqual( - await patchedFs.promises.realpath( - new URL(`file://${linkPath}`) - ), + await fs.promises.realpath(new URL(`file://${linkPath}`)), path.join(fixturesDir, 'a', 'link'), 'should pretend symlink is in the root' ) + + revertPatches() } ) }) @@ -382,63 +374,60 @@ describe('testing realpath', async () => { path.join(fixturesDir, 'sandbox', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir, 'sandbox')]) + const revertPatches = patcher([ + path.join(fixturesDir, 'sandbox'), + ]) const linkPath = path.join(fixturesDir, 'sandbox', 'link') assert.deepStrictEqual( - patchedFs.realpathSync(linkPath), + fs.realpathSync(linkPath), linkPath, 'SYNC: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - patchedFs.realpathSync(new URL(`file://${linkPath}`)), + fs.realpathSync(new URL(`file://${linkPath}`)), linkPath, 'SYNC: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - patchedFs.realpathSync.native(linkPath), + fs.realpathSync.native(linkPath), linkPath, 'SYNC.native: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - patchedFs.realpathSync.native( - new URL(`file://${linkPath}`) - ), + fs.realpathSync.native(new URL(`file://${linkPath}`)), linkPath, 'SYNC.native: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)(linkPath), + await util.promisify(fs.realpath)(linkPath), linkPath, 'CB: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath.native)(linkPath), + await util.promisify(fs.realpath.native)(linkPath), linkPath, 'CB: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - await patchedFs.promises.realpath(linkPath), + await fs.promises.realpath(linkPath), linkPath, 'Promise: should resolve the symlink the same because its within root' ) assert.deepStrictEqual( - await patchedFs.promises.realpath( - new URL(`file://${linkPath}`) - ), + await fs.promises.realpath(new URL(`file://${linkPath}`)), linkPath, 'Promise: should resolve the symlink the same because its within root' ) + + revertPatches() } ) }) @@ -464,23 +453,22 @@ describe('testing realpath', async () => { path.join(fixturesDir, 'sandbox', 'link') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir, 'sandbox')]) + const revertPatches = patcher([ + path.join(fixturesDir, 'sandbox'), + ]) const linkPath = path.join(fixturesDir, 'sandbox', 'link') assert.throws(() => { - patchedFs.realpathSync(linkPath) + fs.realpathSync(linkPath) }, "should throw because it's not a resolvable link") assert.throws(() => { - patchedFs.realpathSync.native(linkPath) + fs.realpathSync.native(linkPath) }, "should throw because it's not a resolvable link") let thrown try { - await util.promisify(patchedFs.realpath)(linkPath) + await util.promisify(fs.realpath)(linkPath) } catch (e) { thrown = e } finally { @@ -489,7 +477,7 @@ describe('testing realpath', async () => { thrown = undefined try { - await util.promisify(patchedFs.realpath.native)(linkPath) + await util.promisify(fs.realpath.native)(linkPath) } catch (e) { thrown = e } finally { @@ -498,12 +486,14 @@ describe('testing realpath', async () => { thrown = undefined try { - await patchedFs.promises.realpath(linkPath) + await fs.promises.realpath(linkPath) } catch (e) { thrown = e } finally { if (!thrown) assert.fail('must throw einval error') } + + revertPatches() } ) }) @@ -555,10 +545,9 @@ describe('testing realpath', async () => { path.join(fixturesDir, 'sandbox', 'node_modules', 'pkg') ) - const patchedFs = Object.assign({}, fs) - patchedFs.promises = Object.assign({}, fs.promises) - - patcher(patchedFs, [path.join(fixturesDir, 'sandbox')]) + const revertPatches = patcher([ + path.join(fixturesDir, 'sandbox'), + ]) const linkPath = path.join( fixturesDir, 'sandbox', @@ -575,31 +564,31 @@ describe('testing realpath', async () => { ) assert.deepStrictEqual( - patchedFs.realpathSync(linkPath), + fs.realpathSync(linkPath), filePath, 'SYNC: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) assert.deepStrictEqual( - patchedFs.realpathSync.native(linkPath), + fs.realpathSync.native(linkPath), filePath, 'SYNC.native: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)(linkPath), + await util.promisify(fs.realpath)(linkPath), filePath, 'CB: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath.native)(linkPath), + await util.promisify(fs.realpath.native)(linkPath), filePath, 'CB: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) assert.deepStrictEqual( - await patchedFs.promises.realpath(linkPath), + await fs.promises.realpath(linkPath), filePath, 'Promise: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) @@ -618,34 +607,36 @@ describe('testing realpath', async () => { ) assert.deepStrictEqual( - patchedFs.realpathSync(linkPath2), + fs.realpathSync(linkPath2), filePath2, 'SYNC: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) assert.deepStrictEqual( - patchedFs.realpathSync.native(linkPath2), + fs.realpathSync.native(linkPath2), filePath2, 'SYNC.native: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath)(linkPath2), + await util.promisify(fs.realpath)(linkPath2), filePath2, 'CB: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) assert.deepStrictEqual( - await util.promisify(patchedFs.realpath.native)(linkPath2), + await util.promisify(fs.realpath.native)(linkPath2), filePath2, 'CB: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) assert.deepStrictEqual( - await patchedFs.promises.realpath(linkPath2), + await fs.promises.realpath(linkPath2), filePath2, 'Promise: should resolve the nested escaping symlinking within a non-escaping parent directory symlink' ) + + revertPatches() } ) })