codekingpro/portable-devtools
114k
1'use strict'
2
3// this code adapted from: https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/
4const cmd = (input, doubleEscape) => {
5 if (!input.length) {
6 return '""'
7 }
8
9 let result
10 if (!/[ \t\n\v"]/.test(input)) {
11 result = input
12 } else {
13 result = '"'
14 for (let i = 0; i <= input.length; ++i) {
15 let slashCount = 0
16 while (input[i] === '\\') {
17 ++i
18 ++slashCount
19 }
20
21 if (i === input.length) {
22 result += '\\'.repeat(slashCount * 2)
23 break
24 }
25
26 if (input[i] === '"') {
27 result += '\\'.repeat(slashCount * 2 + 1)
28 result += input[i]
29 } else {
30 result += '\\'.repeat(slashCount)
31 result += input[i]
32 }
33 }
34 result += '"'
35 }
36
37 // and finally, prefix shell meta chars with a ^
38 result = result.replace(/[ !%^&()<>|"]/g, '^$&')
39 if (doubleEscape) {
40 result = result.replace(/[ !%^&()<>|"]/g, '^$&')
41 }
42
43 return result
44}
45
46const sh = (input) => {
47 if (!input.length) {
48 return `''`
49 }
50
51 if (!/[\t\n\r "#$&'()*;<>?\\`|~]/.test(input)) {
52 return input
53 }
54
55 // replace single quotes with '\'' and wrap the whole result in a fresh set of quotes
56 const result = `'${input.replace(/'/g, `'\\''`)}'`
57 // if the input string already had single quotes around it, clean those up
58 .replace(/^(?:'')+(?!$)/, '')
59 .replace(/\\'''/g, `\\'`)
60
61 return result
62}
63
64module.exports = {
65 cmd,
66 sh,
67}
68 