:fix: bad handling of newlines in env vars

Fix #17627 by using awk to portably separate env vars with \0 instead
of \n.
This commit is contained in:
Dean Brettle
2018-07-04 22:09:27 -07:00
parent 55fc576003
commit 9cd14d3603
2 changed files with 13 additions and 15 deletions

View File

@@ -220,17 +220,14 @@ describe('updateProcessEnv(launchEnv)', function () {
process.platform = 'darwin'
process.env.SHELL = '/my/custom/bash'
spawn.setDefault(spawn.simple(0, dedent`
FOO=BAR=BAZ=QUUX
TERM=xterm-something
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path
`))
spawn.setDefault(spawn.simple(0, '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\\0",v,ENVIRON[v])}\''])
expect(process.env).toEqual({
FOO: 'BAR=BAZ=QUUX',
'MULTILINE\nNAME': 'multiline\nvalue',
TERM: 'xterm-something',
PATH: '/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
})
@@ -246,17 +243,14 @@ describe('updateProcessEnv(launchEnv)', function () {
process.platform = 'linux'
process.env.SHELL = '/my/custom/bash'
spawn.setDefault(spawn.simple(0, dedent`
FOO=BAR=BAZ=QUUX
TERM=xterm-something
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path
`))
spawn.setDefault(spawn.simple(0, '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\\0",v,ENVIRON[v])}\''])
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

@@ -13,6 +13,10 @@ const PLATFORMS_KNOWN_TO_WORK = new Set([
'linux'
])
// Shell command that returns env var=value lines separated by \0s so that
// newlines are handled properly
const ENV_COMMAND = 'command awk \'BEGIN{for(v in ENVIRON) printf("%s=%s\\0",v,ENVIRON[v])}\''
async function updateProcessEnv (launchEnv) {
let envToAssign
if (launchEnv) {
@@ -74,7 +78,7 @@ async function getEnvFromShell (env) {
setTimeout(() => {
cleanup()
}, 5000)
child = childProcess.spawn(env.SHELL, ['-ilc', 'command env'], {encoding: 'utf8', detached: true, stdio: ['ignore', 'pipe', process.stderr]})
child = childProcess.spawn(env.SHELL, ['-ilc', ENV_COMMAND], {encoding: 'utf8', detached: true, stdio: ['ignore', 'pipe', process.stderr]})
const buffers = []
child.on('error', (e) => {
done = true
@@ -98,7 +102,7 @@ async function getEnvFromShell (env) {
if (error.handle) {
error.handle()
}
console.log('warning: ' + env.SHELL + ' -ilc "command env" failed with signal (' + error.signal + ')')
console.log('warning: ' + env.SHELL + ' -ilc "' + ENV_COMMAND + '" failed with signal (' + error.signal + ')')
console.log(error)
}
@@ -107,7 +111,7 @@ async function getEnvFromShell (env) {
}
let result = {}
for (let line of stdout.split('\n')) {
for (let line of stdout.split('\0')) {
if (line.includes('=')) {
let components = line.split('=')
let key = components.shift()