Skip to content

Commit

Permalink
fix: shell escaping (#511)
Browse files Browse the repository at this point in the history
* fix: shell escaping on non windows platforms

* fix: refactor shell escaping, only on windows and escape cmd/pwsh args
  • Loading branch information
YOU54F authored May 29, 2024
1 parent af76abd commit 3829d20
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 28 deletions.
14 changes: 10 additions & 4 deletions bin/pact-broker.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
#!/usr/bin/env node

import childProcess = require('child_process');
import rubyStandalone from '../src/pact-standalone';
import {
standalone,
standaloneUseShell,
setStandaloneArgs,
} from '../src/pact-standalone';

const args = process.argv.slice(2);
const opts = standaloneUseShell ? { shell: true } : {};
const { error, status } = childProcess.spawnSync(
rubyStandalone.brokerFullPath,
process.argv.slice(2),
standalone().brokerFullPath,
setStandaloneArgs(args, standaloneUseShell),
{
stdio: 'inherit',
shell: true,
...opts,
}
);
if (error) throw error;
Expand Down
15 changes: 11 additions & 4 deletions bin/pact-message.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/usr/bin/env node

import childProcess = require('child_process');
import rubyStandalone from '../src/pact-standalone';
import {
standalone,
standaloneUseShell,
setStandaloneArgs,
} from '../src/pact-standalone';

const args = process.argv.slice(2);
const opts = standaloneUseShell ? { shell: true } : {};

const { error, status } = childProcess.spawnSync(
rubyStandalone.messageFullPath,
process.argv.slice(2),
standalone().messageFullPath,
setStandaloneArgs(args, standaloneUseShell),
{
stdio: 'inherit',
shell: true,
...opts,
}
);
if (error) throw error;
Expand Down
15 changes: 11 additions & 4 deletions bin/pact-mock-service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/usr/bin/env node

import childProcess = require('child_process');
import rubyStandalone from '../src/pact-standalone';
import {
standalone,
standaloneUseShell,
setStandaloneArgs,
} from '../src/pact-standalone';

const args = process.argv.slice(2);
const opts = standaloneUseShell ? { shell: true } : {};

const { error, status } = childProcess.spawnSync(
rubyStandalone.mockServiceFullPath,
process.argv.slice(2),
standalone().mockServiceFullPath,
setStandaloneArgs(args, standaloneUseShell),
{
stdio: 'inherit',
shell: true,
...opts,
}
);
if (error) throw error;
Expand Down
15 changes: 11 additions & 4 deletions bin/pact-provider-verifier.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/usr/bin/env node

import childProcess = require('child_process');
import rubyStandalone from '../src/pact-standalone';
import {
standalone,
standaloneUseShell,
setStandaloneArgs,
} from '../src/pact-standalone';

const args = process.argv.slice(2);
const opts = standaloneUseShell ? { shell: true } : {};

const { error, status } = childProcess.spawnSync(
rubyStandalone.verifierFullPath,
process.argv.slice(2),
standalone().verifierFullPath,
setStandaloneArgs(args, standaloneUseShell),
{
stdio: 'inherit',
shell: true,
...opts,
}
);
if (error) throw error;
Expand Down
15 changes: 11 additions & 4 deletions bin/pact-stub-service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/usr/bin/env node

import childProcess = require('child_process');
import rubyStandalone from '../src/pact-standalone';
import {
standalone,
standaloneUseShell,
setStandaloneArgs,
} from '../src/pact-standalone';

const args = process.argv.slice(2);
const opts = standaloneUseShell ? { shell: true } : {};

const { error, status } = childProcess.spawnSync(
rubyStandalone.stubFullPath,
process.argv.slice(2),
standalone().stubFullPath,
setStandaloneArgs(args, standaloneUseShell),
{
stdio: 'inherit',
shell: true,
...opts,
}
);
if (error) throw error;
Expand Down
15 changes: 11 additions & 4 deletions bin/pact.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/usr/bin/env node

import childProcess = require('child_process');
import rubyStandalone from '../src/pact-standalone';
import {
standalone,
standaloneUseShell,
setStandaloneArgs,
} from '../src/pact-standalone';

const args = process.argv.slice(2);
const opts = standaloneUseShell ? { shell: true } : {};

const { error, status } = childProcess.spawnSync(
rubyStandalone.pactFullPath,
process.argv.slice(2),
standalone().pactFullPath,
setStandaloneArgs(args, standaloneUseShell),
{
stdio: 'inherit',
shell: true,
...opts,
}
);
if (error) throw error;
Expand Down
15 changes: 11 additions & 4 deletions bin/pactflow.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/usr/bin/env node

import childProcess = require('child_process');
import rubyStandalone from '../src/pact-standalone';
import {
standalone,
standaloneUseShell,
setStandaloneArgs,
} from '../src/pact-standalone';

const args = process.argv.slice(2);
const opts = standaloneUseShell ? { shell: true } : {};

const { error, status } = childProcess.spawnSync(
rubyStandalone.pactflowFullPath,
process.argv.slice(2),
standalone().pactflowPath,
setStandaloneArgs(args, standaloneUseShell),
{
stdio: 'inherit',
shell: true,
...opts,
}
);
if (error) throw error;
Expand Down
45 changes: 45 additions & 0 deletions src/pact-standalone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,49 @@ export const standalone = (
};
};

const isWindows = process.platform === 'win32';

function quoteCmdArg(arg: string) {
return `"${arg.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
}

function quotePwshArg(arg: string) {
return `'${arg.replace(/'/g, "''")}'`;
}

function quotePosixShArg(arg: string) {
return `'${arg.replace(/'/g, "'\\''")}'`;
}

function testWindowsExe(cmd: string, file: string) {
return new RegExp(`^(?:.*\\\\)?${cmd}(?:\\.exe)?$`, 'i').test(file);
}

function parseArgs(unparsed_args: string[]) {
if (isWindows === true) {
const file = process.env['comspec'] || 'cmd.exe';
if (testWindowsExe('cmd', file) === true) {
return unparsed_args.map((i) => quoteCmdArg(i));
}
if (testWindowsExe('(powershell|pwsh)', file) || file.endsWith('/pwsh')) {
return unparsed_args.map((i) => quotePwshArg(i));
}
return unparsed_args;
}
return unparsed_args.map((i) => quotePosixShArg(i));
}

export function setStandaloneArgs(
unparsed_args: string[],
shell: boolean
): string[] {
let parsedArgs = unparsed_args;
if (shell === true) {
parsedArgs = parseArgs(unparsed_args);
}
return parsedArgs;
}

export const standaloneUseShell = isWindows;

export default standalone();

0 comments on commit 3829d20

Please sign in to comment.