launch-editor
Advanced tools
Comparing version 2.8.2 to 2.9.0
@@ -10,11 +10,18 @@ module.exports = { | ||
gvim: 'gvim', | ||
idea: 'idea', | ||
'idea.sh': 'idea', | ||
phpstorm: 'phpstorm', | ||
'phpstorm.sh': 'phpstorm', | ||
pycharm: 'pycharm', | ||
'pycharm.sh': 'pycharm', | ||
rubymine: 'rubymine', | ||
'rubymine.sh': 'rubymine', | ||
sublime_text: 'subl', | ||
vim: 'vim', | ||
webstorm: 'webstorm', | ||
'webstorm.sh': 'webstorm', | ||
goland: 'goland', | ||
'goland.sh': 'goland', | ||
rider: 'rider' | ||
'rider.sh': 'rider' | ||
} |
86
index.js
@@ -100,32 +100,2 @@ /** | ||
// cmd.exe on Windows is vulnerable to RCE attacks given a file name of the | ||
// form "C:\Users\myusername\Downloads\& curl 172.21.93.52". Use a safe file | ||
// name pattern to validate user-provided file names. This doesn't cover the | ||
// entire range of valid file names but should cover almost all of them in practice. | ||
// (Backport of | ||
// https://github.com/facebook/create-react-app/pull/4866 | ||
// and | ||
// https://github.com/facebook/create-react-app/pull/5431) | ||
// Allows alphanumeric characters, periods, dashes, slashes, underscores, plus and space. | ||
const WINDOWS_CMD_SAFE_FILE_NAME_PATTERN = /^([A-Za-z]:[/\\])?[\p{L}0-9/.\-\\_+ \[\]]+$/u | ||
if ( | ||
process.platform === 'win32' && | ||
!WINDOWS_CMD_SAFE_FILE_NAME_PATTERN.test(fileName.trim()) | ||
) { | ||
console.log() | ||
console.log( | ||
colors.red('Could not open ' + path.basename(fileName) + ' in the editor.') | ||
) | ||
console.log() | ||
console.log( | ||
'When running on Windows, file names are checked against a safe file name ' + | ||
'pattern to protect against remote code execution attacks. File names ' + | ||
'may consist only of alphanumeric characters (all languages), periods, ' + | ||
'dashes, slashes, and underscores.' | ||
); | ||
console.log() | ||
return | ||
} | ||
if (lineNumber) { | ||
@@ -146,9 +116,51 @@ const extraArgs = getArgumentsForPosition(editor, fileName, lineNumber, columnNumber) | ||
if (process.platform === 'win32') { | ||
// On Windows, launch the editor in a shell because spawn can only | ||
// launch .exe files. | ||
_childProcess = childProcess.spawn( | ||
'cmd.exe', | ||
['/C', editor].concat(args), | ||
{ stdio: 'inherit' } | ||
) | ||
// On Windows, we need to use `exec` with the `shell: true` option, | ||
// and some more sanitization is required. | ||
// However, CMD.exe on Windows is vulnerable to RCE attacks given a file name of the | ||
// form "C:\Users\myusername\Downloads\& curl 172.21.93.52". | ||
// `create-react-app` used a safe file name pattern to validate user-provided file names: | ||
// - https://github.com/facebook/create-react-app/pull/4866 | ||
// - https://github.com/facebook/create-react-app/pull/5431 | ||
// But that's not a viable solution for this package because | ||
// it's depended on by so many meta frameworks that heavily rely on | ||
// special characters in file names for filesystem-based routing. | ||
// We need to at least: | ||
// - Support `+` because it's used in SvelteKit and Vike | ||
// - Support `$` because it's used in Remix | ||
// - Support `(` and `)` because they are used in Analog, SolidStart, and Vike | ||
// - Support `@` because it's used in Vike | ||
// - Support `[` and `]` because they are widely used for [slug] | ||
// So here we choose to use `^` to escape special characters instead. | ||
// According to https://ss64.com/nt/syntax-esc.html, | ||
// we can use `^` to escape `&`, `<`, `>`, `|`, `%`, and `^` | ||
// I'm not sure if we have to escape all of these, but let's do it anyway | ||
function escapeCmdArgs (cmdArgs) { | ||
return cmdArgs.replace(/([&|<>,;=^])/g, '^$1') | ||
} | ||
// Need to double quote the editor path in case it contains spaces; | ||
// If the fileName contains spaces, we also need to double quote it in the arguments | ||
// However, there's a case that it's concatenated with line number and column number | ||
// which is separated by `:`. We need to double quote the whole string in this case. | ||
// Also, if the string contains the escape character `^`, it needs to be quoted, too. | ||
function doubleQuoteIfNeeded(str) { | ||
if (str.includes('^')) { | ||
// If a string includes an escaped character, not only does it need to be quoted, | ||
// but the quotes need to be escaped too. | ||
return `^"${str}^"` | ||
} else if (str.includes(' ')) { | ||
return `"${str}"` | ||
} | ||
return str | ||
} | ||
const launchCommand = [editor, ...args.map(escapeCmdArgs)] | ||
.map(doubleQuoteIfNeeded) | ||
.join(' ') | ||
_childProcess = childProcess.exec(launchCommand, { | ||
stdio: 'inherit', | ||
shell: true | ||
}) | ||
} else { | ||
@@ -155,0 +167,0 @@ _childProcess = childProcess.spawn(editor, args, { stdio: 'inherit' }) |
{ | ||
"name": "launch-editor", | ||
"version": "2.8.2", | ||
"version": "2.9.0", | ||
"description": "launch editor from node.js", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17065
426