From: Juan Cruz Viotti Date: Thu, 19 May 2016 15:08:08 +0000 (-0400) Subject: Override `child_process.execFile` asar patch for `child_process.exec` X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1a27ecdad41ba0854a8a890774e1ec67c83ee427;p=platform%2Fframework%2Fweb%2Fcrosswalk-tizen.git Override `child_process.execFile` asar patch for `child_process.exec` NodeJS implements `child_process.exec` by simply passing the whole command to `child_process.execFile`. See: - https://github.com/nodejs/node/blob/master/lib/child_process.js#L90 - https://github.com/nodejs/node/blob/master/lib/child_process.js#L99 Electron patches `child_process.execFile` to add support for `asar` archives by injecting logic that extracts the required files from the `asar` to a temporary location before delegating the work to the original `child_process.execFile`. In order to decide whether to inject the custom `asar` extracting logic, Electron makes use of a helper function called `splitPath()`. See: - https://github.com/electron/electron/blob/master/lib/common/asar.js#L37 If the first argument of the returned array equals `true`, means that the path is considered to be an `asar` archive, and thus the extraction logic takes place. The problem is that if the command passed to `child_process.execFile` *contains* a path to an asar archive, padded with other commands/arguments, `splitPath()` will consider it to be an `asar` archive, and will try to extract it, throwing a rightfully `Invalid package` error. Fixes: https://github.com/electron/electron/issues/5571 Signed-off-by: Juan Cruz Viotti --- diff --git a/lib/common/asar.js b/lib/common/asar.js index 2624128..1d8474d 100644 --- a/lib/common/asar.js +++ b/lib/common/asar.js @@ -589,6 +589,23 @@ return mkdirSync(p, mode) } } + + // Executing a command string containing a path to an asar + // archive confuses `child_process.execFile`, which is internally + // called by `child_process.{exec,execSync}`, causing + // Electron to consider the full command as a single path + // to an archive. + [ 'exec', 'execSync' ].forEach(function (functionName) { + var old = child_process[functionName] + child_process[functionName] = function () { + var processNoAsarOriginalValue = process.noAsar + process.noAsar = true + var result = old.apply(this, arguments) + process.noAsar = processNoAsarOriginalValue + return result + } + }) + overrideAPI(fs, 'open') overrideAPI(child_process, 'execFile') overrideAPISync(process, 'dlopen', 1) diff --git a/spec/asar-spec.js b/spec/asar-spec.js index f9c4e98..ac0779d 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -555,6 +555,30 @@ describe('asar package', function () { }) }) + describe('child_process.exec', function () { + var child_process = require('child_process'); + var echo = path.join(fixtures, 'asar', 'echo.asar', 'echo') + + it('should not try to extract the command if there is a reference to a file inside an .asar', function (done) { + child_process.exec('echo ' + echo + ' foo bar', function (error, stdout) { + assert.equal(error, null) + assert.equal(stdout.toString().replace(/\r/g, ''), echo + ' foo bar\n') + done() + }) + }) + }) + + describe('child_process.execSync', function () { + var child_process = require('child_process'); + var echo = path.join(fixtures, 'asar', 'echo.asar', 'echo') + + it('should not try to extract the command if there is a reference to a file inside an .asar', function (done) { + var stdout = child_process.execSync('echo ' + echo + ' foo bar') + assert.equal(stdout.toString().replace(/\r/g, ''), echo + ' foo bar\n') + done() + }) + }) + describe('child_process.execFile', function () { var echo, execFile, execFileSync, ref2 if (process.platform !== 'darwin') {