From 9faaedd311748b20b63efe15e930820d17fadb5c Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Sat, 9 Dec 2023 00:17:38 +0000 Subject: [PATCH] Fix error message when serializing `require.resolve` or `require.resolve.paths` [fix] --- lib/init/index.js | 2 + lib/init/module.js | 2 + test/commonjs.test.js | 114 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/lib/init/index.js b/lib/init/index.js index 63738a6d..0ce14b0c 100644 --- a/lib/init/index.js +++ b/lib/init/index.js @@ -36,6 +36,8 @@ module.exports = (filename, module, require, nextBlockId, prefixNum) => { // Record `module` + `require` globals.set(module, {type: COMMON_JS_MODULE, parent: null, key: 'module'}); specialFunctions.set(require, {type: 'require', path: filename}); + specialFunctions.set(require.resolve, {type: 'require', path: filename}); + specialFunctions.set(require.resolve.paths, {type: 'require', path: filename}); // Create local tracker function with additional properties and methods specific to the file const blockIdCounter = {nextBlockId}; diff --git a/lib/init/module.js b/lib/init/module.js index e18f670e..46b1380e 100644 --- a/lib/init/module.js +++ b/lib/init/module.js @@ -55,6 +55,8 @@ function createWrappedRequire(require, filename) { // Record `require` specialFunctions.set(wrappedRequire, {type: 'require', path: filename}); + specialFunctions.set(wrappedRequire.resolve, {type: 'require', path: filename}); + specialFunctions.set(wrappedRequire.resolve.paths, {type: 'require', path: filename}); // Return wrapped `require` return wrappedRequire; diff --git a/test/commonjs.test.js b/test/commonjs.test.js index 67cefc49..d404a98a 100644 --- a/test/commonjs.test.js +++ b/test/commonjs.test.js @@ -186,3 +186,117 @@ describe('`require`', () => { }); }); }); + +describe('`require.resolve`', () => { + describe('from same file', () => { + it('cannot be serialized directly', () => { + expect(() => serialize(require.resolve)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + }); + + it('cannot be serialized in function scope', () => { + const {resolve} = require; + expect(() => serialize(() => resolve)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + }); + }); + + describe('from another file', () => { + it('cannot be serialized directly', () => { + withFixtures( + 'module.exports = require.resolve;', + (otherResolve) => { + expect(() => serialize(otherResolve)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + } + ); + }); + + it('cannot be serialized in function scope', () => { + withFixtures( + 'module.exports = require.resolve;', + (otherResolve) => { + expect(() => serialize(() => otherResolve)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + } + ); + }); + }); + + describe('created by `Module.createRequire()`', () => { + it('cannot be serialized directly', () => { + const otherResolve = Module.createRequire(__filename).resolve; + expect(() => serialize(otherResolve)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + }); + + it('cannot be serialized in function scope', () => { + const otherResolve = Module.createRequire(__filename).resolve; + expect(() => serialize(() => otherResolve)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + }); + }); +}); + +describe('`require.resolve.paths`', () => { + describe('from same file', () => { + it('cannot be serialized directly', () => { + expect(() => serialize(require.resolve.paths)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + }); + + it('cannot be serialized in function scope', () => { + const {paths} = require.resolve; + expect(() => serialize(() => paths)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + }); + }); + + describe('from another file', () => { + it('cannot be serialized directly', () => { + withFixtures( + 'module.exports = require.resolve.paths;', + (otherPaths) => { + expect(() => serialize(otherPaths)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + } + ); + }); + + it('cannot be serialized in function scope', () => { + withFixtures( + 'module.exports = require.resolve.paths;', + (otherPaths) => { + expect(() => serialize(() => otherPaths)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + } + ); + }); + }); + + describe('created by `Module.createRequire()`', () => { + it('cannot be serialized directly', () => { + const otherPaths = Module.createRequire(__filename).resolve.paths; + expect(() => serialize(otherPaths)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + }); + + it('cannot be serialized in function scope', () => { + const otherPaths = Module.createRequire(__filename).resolve.paths; + expect(() => serialize(() => otherPaths)).toThrowWithMessage( + Error, /^Cannot serialize `require` or `import` \(in / + ); + }); + }); +});