48 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			48 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| // See http://www.robvanderwoude.com/escapechars.php
 | |
| const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
 | |
| 
 | |
| function escapeCommand(arg) {
 | |
|     // Escape meta chars
 | |
|     arg = arg.replace(metaCharsRegExp, '^$1');
 | |
| 
 | |
|     return arg;
 | |
| }
 | |
| 
 | |
| function escapeArgument(arg, doubleEscapeMetaChars) {
 | |
|     // Convert to string
 | |
|     arg = `${arg}`;
 | |
| 
 | |
|     // Algorithm below is based on https://qntm.org/cmd
 | |
|     // It's slightly altered to disable JS backtracking to avoid hanging on specially crafted input
 | |
|     // Please see https://github.com/moxystudio/node-cross-spawn/pull/160 for more information
 | |
| 
 | |
|     // Sequence of backslashes followed by a double quote:
 | |
|     // double up all the backslashes and escape the double quote
 | |
|     arg = arg.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"');
 | |
| 
 | |
|     // Sequence of backslashes followed by the end of the string
 | |
|     // (which will become a double quote later):
 | |
|     // double up all the backslashes
 | |
|     arg = arg.replace(/(?=(\\+?)?)\1$/, '$1$1');
 | |
| 
 | |
|     // All other backslashes occur literally
 | |
| 
 | |
|     // Quote the whole thing:
 | |
|     arg = `"${arg}"`;
 | |
| 
 | |
|     // Escape meta chars
 | |
|     arg = arg.replace(metaCharsRegExp, '^$1');
 | |
| 
 | |
|     // Double escape meta chars if necessary
 | |
|     if (doubleEscapeMetaChars) {
 | |
|         arg = arg.replace(metaCharsRegExp, '^$1');
 | |
|     }
 | |
| 
 | |
|     return arg;
 | |
| }
 | |
| 
 | |
| module.exports.command = escapeCommand;
 | |
| module.exports.argument = escapeArgument;
 |