@theia/process
Version:
Theia process support.
177 lines (168 loc) • 8.44 kB
text/typescript
// *****************************************************************************
// Copyright (C) 2020 Ericsson and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
import { expect } from 'chai';
import { escapeForShell, BashQuotingFunctions, ShellQuoting, CmdQuotingFunctions, PowershellQuotingFunctions } from './shell-quoting';
describe('Shell arguments escaping:', () => {
// Procedurally execute tests from this list of data.
const testData = {
bash: {
// https://www.gnu.org/software/bash/manual/html_node/Quoting.html
quotingFunctions: BashQuotingFunctions,
data: {
[ShellQuoting.Escape]: [
{ input: 'abc', expected: 'abc' },
{ input: 'ab c', expected: 'ab\\ c' },
{ input: 'ab"c', expected: 'ab\\"c' },
{ input: 'ab\'c', expected: 'ab\\\'c' },
{ input: 'ab\\ c\\', expected: 'ab\\\\\\ c\\\\' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: 'setTimeout\\(\\(\\)\\ =\\>\\ \\{\\ console.log\\(1,\\ \\"2\\\'3\\"\\)\\;\\ \\},\\ 100\\)',
},
],
[ShellQuoting.Strong]: [
{ input: 'abc', expected: '\'abc\'' },
{ input: 'ab c', expected: '\'ab c\'' },
{ input: 'ab"c', expected: '\'ab"c\'' },
{ input: 'ab\'c', expected: '\'ab\'"\'"\'c\'' },
{ input: 'ab\\ c\\', expected: '\'ab\\ c\\\'' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: '\'setTimeout(() => { console.log(1, "2\'"\'"\'3"); }, 100)\'',
},
],
[ShellQuoting.Weak]: [
{ input: 'abc', expected: '"abc"' },
{ input: 'ab c', expected: '"ab c"' },
{ input: 'ab"c', expected: '"ab\\"c"' },
{ input: 'ab\'c', expected: '"ab\'c"' },
{ input: 'ab\\ c\\', expected: '"ab\\ c\\\\"' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: '"setTimeout(() => { console.log(1, \\"2\'3\\"); }, 100)"',
},
]
},
},
cmd: {
// https://ss64.com/nt/syntax-esc.html
quotingFunctions: CmdQuotingFunctions,
data: {
[ShellQuoting.Escape]: [
{ input: 'abc', expected: 'abc' },
{ input: 'ab c', expected: 'ab" "c' },
{ input: 'ab"c', expected: 'ab\\"c' },
{ input: 'ab\'c', expected: 'ab\'c' },
{ input: 'ab^ c^', expected: 'ab^^" "c^^' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: 'setTimeout^(^(^)" "=^>" "{" "console.log^(1," "\\"2\'3\\"^);" "}," "100^)',
},
{
input: 'console.log("%PATH%")',
expected: 'console.log^(\\"^%PATH^%\\"^)',
},
],
[ShellQuoting.Strong]: [
{ input: 'abc', expected: '"abc"' },
{ input: 'ab c', expected: '"ab c"' },
{ input: 'ab"c', expected: '"ab\\"c"' },
{ input: 'ab\'c', expected: '"ab\'c"' },
{ input: 'ab^ c^', expected: '"ab^^ c^^"' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: '"setTimeout^(^(^) =^> { console.log^(1, \\"2\'3\\"^); }, 100^)"',
},
{
input: 'console.log("%PATH%")',
expected: '"console.log^(\\""%"PATH"%"\\"^)"',
},
],
[ShellQuoting.Weak]: [
{ input: 'abc', expected: '"abc"' },
{ input: 'ab c', expected: '"ab c"' },
{ input: 'ab"c', expected: '"ab\\"c"' },
{ input: 'ab\'c', expected: '"ab\'c"' },
{ input: 'ab^ c^', expected: '"ab^^ c^^"' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: '"setTimeout^(^(^) =^> { console.log^(1, \\"2\'3\\"^); }, 100^)"',
},
{
input: 'console.log("%PATH%")',
expected: '"console.log^(\\"%PATH%\\"^)"',
},
]
},
},
powershell: {
// https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules?view=powershell-6
quotingFunctions: PowershellQuotingFunctions,
data: {
[ShellQuoting.Escape]: [
{ input: 'abc', expected: 'abc' },
{ input: 'ab c', expected: 'ab` c' },
{ input: 'ab"c', expected: 'ab`"c' },
{ input: 'ab\'c', expected: 'ab`\'c' },
{ input: 'ab` c`', expected: 'ab``` c``' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: 'setTimeout`(`(`)` =`>` `{` console.log`(1,` `"2`\'3`"`)`;` `},` 100`)',
},
],
[ShellQuoting.Strong]: [
{ input: 'abc', expected: '\'abc\'' },
{ input: 'ab c', expected: '\'ab c\'' },
{ input: 'ab"c', expected: '\'ab"c\'' },
{ input: 'ab\'c', expected: '\'ab\'\'c\'' },
{ input: 'ab` c`', expected: '\'ab` c`\'' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: '\'setTimeout(() => { console.log(1, "2\'\'3"); }, 100)\'',
},
],
[ShellQuoting.Weak]: [
{ input: 'abc', expected: '"abc"' },
{ input: 'ab c', expected: '"ab c"' },
{ input: 'ab"c', expected: '"ab`"c"' },
{ input: 'ab\'c', expected: '"ab\'c"' },
{ input: 'ab` c`', expected: '"ab` c``"' },
{
input: 'setTimeout(() => { console.log(1, "2\'3"); }, 100)',
expected: '"setTimeout(() => { console.log(1, `"2\'3`"); }, 100)"',
},
]
},
}
} as const;
// Iter through each runtime (bash/cmd/powershell):
for (const runtime of Object.keys(testData)) {
const testInfo = testData[runtime as keyof typeof testData];
// Get all quoting types (escape/strong/weak):
for (const quotingType of Object.keys(testInfo.data)) {
const testInput = testInfo.data[quotingType as keyof typeof testInfo['data']];
// Run the test for each input:
it(`${runtime}/${quotingType}`, () => {
for (const test of testInput) {
expect(escapeForShell({
quoting: quotingType as ShellQuoting,
value: test.input,
}, testInfo.quotingFunctions)).equal(test.expected);
}
});
}
}
});