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