fix: asar integration for require('node:child_process') (#38742)

This commit is contained in:
Milan Burda 2023-06-14 11:03:53 +02:00 committed by GitHub
parent 46458ab517
commit dc2e822dc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 51 deletions

View file

@ -838,7 +838,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
const originalModuleLoad = Module._load; const originalModuleLoad = Module._load;
Module._load = (request: string, ...args: any[]) => { Module._load = (request: string, ...args: any[]) => {
const loadResult = originalModuleLoad(request, ...args); const loadResult = originalModuleLoad(request, ...args);
if (request === 'child_process') { if (request === 'child_process' || request === 'node:child_process') {
if (!asarReady.has(loadResult)) { if (!asarReady.has(loadResult)) {
asarReady.add(loadResult); asarReady.add(loadResult);
// Just to make it obvious what we are dealing with here // Just to make it obvious what we are dealing with here

View file

@ -1220,64 +1220,69 @@ describe('asar package', function () {
}); });
}); });
describe('child_process.fork', function () { function generateSpecs (childProcess: string) {
itremote('opens a normal js file', async function () { describe(`${childProcess}.fork`, function () {
const child = require('child_process').fork(path.join(asarDir, 'a.asar', 'ping.js')); itremote('opens a normal js file', async function (childProcess: string) {
const child = require(childProcess).fork(path.join(asarDir, 'a.asar', 'ping.js'));
child.send('message'); child.send('message');
const msg = await new Promise(resolve => child.once('message', resolve)); const msg = await new Promise(resolve => child.once('message', resolve));
expect(msg).to.equal('message'); expect(msg).to.equal('message');
}); }, [childProcess]);
itremote('supports asar in the forked js', async function (fixtures: string) { itremote('supports asar in the forked js', async function (childProcess: string, fixtures: string) {
const file = path.join(asarDir, 'a.asar', 'file1'); const file = path.join(asarDir, 'a.asar', 'file1');
const child = require('child_process').fork(path.join(fixtures, 'module', 'asar.js')); const child = require(childProcess).fork(path.join(fixtures, 'module', 'asar.js'));
child.send(file); child.send(file);
const content = await new Promise(resolve => child.once('message', resolve)); const content = await new Promise(resolve => child.once('message', resolve));
expect(content).to.equal(fs.readFileSync(file).toString()); expect(content).to.equal(fs.readFileSync(file).toString());
}, [fixtures]); }, [childProcess, fixtures]);
}); });
describe('child_process.exec', function () { describe(`${childProcess}.exec`, function () {
itremote('should not try to extract the command if there is a reference to a file inside an .asar', async function () { itremote('should not try to extract the command if there is a reference to a file inside an .asar', async function (childProcess: string) {
const echo = path.join(asarDir, 'echo.asar', 'echo'); const echo = path.join(asarDir, 'echo.asar', 'echo');
const stdout = await promisify(require('child_process').exec)('echo ' + echo + ' foo bar'); const stdout = await promisify(require(childProcess).exec)('echo ' + echo + ' foo bar');
expect(stdout.toString().replace(/\r/g, '')).to.equal(echo + ' foo bar\n'); expect(stdout.toString().replace(/\r/g, '')).to.equal(echo + ' foo bar\n');
}); }, [childProcess]);
}); });
describe('child_process.execSync', function () { describe(`${childProcess}.execSync`, function () {
itremote('should not try to extract the command if there is a reference to a file inside an .asar', async function () { itremote('should not try to extract the command if there is a reference to a file inside an .asar', async function (childProcess: string) {
const echo = path.join(asarDir, 'echo.asar', 'echo'); const echo = path.join(asarDir, 'echo.asar', 'echo');
const stdout = require('child_process').execSync('echo ' + echo + ' foo bar'); const stdout = require(childProcess).execSync('echo ' + echo + ' foo bar');
expect(stdout.toString().replace(/\r/g, '')).to.equal(echo + ' foo bar\n'); expect(stdout.toString().replace(/\r/g, '')).to.equal(echo + ' foo bar\n');
}); }, [childProcess]);
}); });
ifdescribe(process.platform === 'darwin' && process.arch !== 'arm64')('child_process.execFile', function () { ifdescribe(process.platform === 'darwin' && process.arch !== 'arm64')(`${childProcess}.execFile`, function () {
itremote('executes binaries', async function () { itremote('executes binaries', async function (childProcess: string) {
const echo = path.join(asarDir, 'echo.asar', 'echo'); const echo = path.join(asarDir, 'echo.asar', 'echo');
const stdout = await promisify(require('child_process').execFile)(echo, ['test']); const stdout = await promisify(require(childProcess).execFile)(echo, ['test']);
expect(stdout).to.equal('test\n'); expect(stdout).to.equal('test\n');
}); }, [childProcess]);
itremote('executes binaries without callback', async function () { itremote('executes binaries without callback', async function (childProcess: string) {
const echo = path.join(asarDir, 'echo.asar', 'echo'); const echo = path.join(asarDir, 'echo.asar', 'echo');
const process = require('child_process').execFile(echo, ['test']); const process = require(childProcess).execFile(echo, ['test']);
const code = await new Promise(resolve => process.once('close', resolve)); const code = await new Promise(resolve => process.once('close', resolve));
expect(code).to.equal(0); expect(code).to.equal(0);
process.on('error', function () { process.on('error', function () {
throw new Error('error'); throw new Error('error');
}); });
}); }, [childProcess]);
itremote('execFileSync executes binaries', function () { itremote('execFileSync executes binaries', function (childProcess: string) {
const echo = path.join(asarDir, 'echo.asar', 'echo'); const echo = path.join(asarDir, 'echo.asar', 'echo');
const output = require('child_process').execFileSync(echo, ['test']); const output = require(childProcess).execFileSync(echo, ['test']);
expect(String(output)).to.equal('test\n'); expect(String(output)).to.equal('test\n');
}, [childProcess]);
}); });
}); }
generateSpecs('child_process');
generateSpecs('node:child_process');
describe('internalModuleReadJSON', function () { describe('internalModuleReadJSON', function () {
itremote('reads a normal file', function () { itremote('reads a normal file', function () {