Merge pull request #17628 from brettle/master

Fix getEnvFromShell() to correctly handle newlines in env vars
This commit is contained in:
Sadick 2021-09-03 22:28:46 +03:00 committed by GitHub
commit d04abd683a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 26 deletions

View File

@ -6,7 +6,6 @@ import {
updateProcessEnv,
shouldGetEnvFromShell
} from '../src/update-process-env';
import dedent from 'dedent';
import mockSpawn from 'mock-spawn';
const temp = require('temp').track();
@ -258,19 +257,19 @@ describe('updateProcessEnv(launchEnv)', function() {
spawn.setDefault(
spawn.simple(
0,
dedent`
FOO=BAR=BAZ=QUUX
TERM=xterm-something
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path
`
'FOO=BAR=BAZ=QUUX\0MULTILINE\nNAME=multiline\nvalue\0TERM=xterm-something\0PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
)
);
await updateProcessEnv(process.env);
expect(spawn.calls.length).toBe(1);
expect(spawn.calls[0].command).toBe('/my/custom/bash');
expect(spawn.calls[0].args).toEqual(['-ilc', 'command env']);
expect(spawn.calls[0].args).toEqual([
'-ilc',
'command awk \'BEGIN{for(v in ENVIRON) printf("%s=%s%c", v, ENVIRON[v], 0)}\''
]);
expect(process.env).toEqual({
FOO: 'BAR=BAZ=QUUX',
'MULTILINE\nNAME': 'multiline\nvalue',
TERM: 'xterm-something',
PATH: '/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
});
@ -289,19 +288,19 @@ describe('updateProcessEnv(launchEnv)', function() {
spawn.setDefault(
spawn.simple(
0,
dedent`
FOO=BAR=BAZ=QUUX
TERM=xterm-something
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path
`
'FOO=BAR=BAZ=QUUX\0MULTILINE\nNAME=multiline\nvalue\0TERM=xterm-something\0PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
)
);
await updateProcessEnv(process.env);
expect(spawn.calls.length).toBe(1);
expect(spawn.calls[0].command).toBe('/my/custom/bash');
expect(spawn.calls[0].args).toEqual(['-ilc', 'command env']);
expect(spawn.calls[0].args).toEqual([
'-ilc',
'command awk \'BEGIN{for(v in ENVIRON) printf("%s=%s%c", v, ENVIRON[v], 0)}\''
]);
expect(process.env).toEqual({
FOO: 'BAR=BAZ=QUUX',
'MULTILINE\nNAME': 'multiline\nvalue',
TERM: 'xterm-something',
PATH: '/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
});

View File

@ -10,6 +10,12 @@ const ENVIRONMENT_VARIABLES_TO_PRESERVE = new Set([
const PLATFORMS_KNOWN_TO_WORK = new Set(['darwin', 'linux']);
// Shell command that returns env var=value lines separated by \0s so that
// newlines are handled properly. Note: need to use %c to inject the \0s
// to work with some non GNU awks.
const ENV_COMMAND =
'command awk \'BEGIN{for(v in ENVIRON) printf("%s=%s%c", v, ENVIRON[v], 0)}\'';
async function updateProcessEnv(launchEnv) {
let envToAssign;
if (launchEnv) {
@ -78,7 +84,7 @@ async function getEnvFromShell(env) {
setTimeout(() => {
cleanup();
}, 5000);
child = childProcess.spawn(env.SHELL, ['-ilc', 'command env'], {
child = childProcess.spawn(env.SHELL, ['-ilc', ENV_COMMAND], {
encoding: 'utf8',
detached: true,
stdio: ['ignore', 'pipe', process.stderr]
@ -109,7 +115,9 @@ async function getEnvFromShell(env) {
console.log(
'warning: ' +
env.SHELL +
' -ilc "command env" failed with signal (' +
' -ilc "' +
ENV_COMMAND +
'" failed with signal (' +
error.signal +
')'
);
@ -121,22 +129,13 @@ async function getEnvFromShell(env) {
}
let result = {};
let skip = false;
for (let line of stdout.split('\n')) {
// start of shell function definition: skip full definition
if (line.includes('=() {')) {
skip = true;
}
if (!skip && line.includes('=')) {
for (let line of stdout.split('\0')) {
if (line.includes('=')) {
let components = line.split('=');
let key = components.shift();
let value = components.join('=');
result[key] = value;
}
// end of shell function definition
if (line === '}') {
skip = false;
}
}
return result;
}