mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Fix buggy partial startup on macOS due to flag added by Gatekeeper/XProtect (#21861)
macOS Gatekeeper adds a flag ("-psn_0_[six or seven digits here]") when it intercepts Atom launches.
This happens for fresh downloads, new installs, or first launches after upgrading).
We don't need this flag, and yargs interprets it as many short flags. So, we filter it out.
This commit is contained in:
@@ -724,7 +724,7 @@ describe('AtomApplication', function() {
|
||||
});
|
||||
|
||||
it('opens a file to a specific line number and column', async function() {
|
||||
await scenario.open(parseCommandLine('b/2.md:12:5'));
|
||||
await scenario.open(parseCommandLine(['b/2.md:12:5']));
|
||||
await scenario.assert('[_ 2.md]');
|
||||
|
||||
const w = scenario.getWindow(0);
|
||||
@@ -750,7 +750,7 @@ describe('AtomApplication', function() {
|
||||
});
|
||||
|
||||
it('truncates trailing whitespace and colons', async function() {
|
||||
await scenario.open(parseCommandLine('b/2.md:: '));
|
||||
await scenario.open(parseCommandLine(['b/2.md:: ']));
|
||||
await scenario.assert('[_ 2.md]');
|
||||
|
||||
const w = scenario.getWindow(0);
|
||||
|
||||
@@ -21,6 +21,65 @@ describe('parseCommandLine', () => {
|
||||
]);
|
||||
assert.deepEqual(args.pathsToOpen, ['/some/path']);
|
||||
});
|
||||
|
||||
// The "underscore flag" with no "non-flag argument" after it
|
||||
// is the minimal reproducer for the macOS Gatekeeper startup bug.
|
||||
// By default, it causes the addition of boolean "true"s into yargs' "non-flag argument" array: `argv._`
|
||||
// Whereas we do string-only operations on these arguments, expecting them to be paths or URIs.
|
||||
describe('and --_ or -_ are passed', () => {
|
||||
it('does not attempt to parse booleans as paths or URIs', () => {
|
||||
const args = parseCommandLine([
|
||||
'--_',
|
||||
'/some/path',
|
||||
'-_',
|
||||
'-_',
|
||||
'some/other/path',
|
||||
'atom://test/url',
|
||||
'--_',
|
||||
'atom://other/url',
|
||||
'-_',
|
||||
'./another-path.file',
|
||||
'-_',
|
||||
'-_',
|
||||
'-_'
|
||||
]);
|
||||
assert.deepEqual(args.urlsToOpen, [
|
||||
'atom://test/url',
|
||||
'atom://other/url'
|
||||
]);
|
||||
assert.deepEqual(args.pathsToOpen, [
|
||||
'/some/path',
|
||||
'some/other/path',
|
||||
'./another-path.file'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('and a non-flag number is passed as an argument', () => {
|
||||
it('does not attempt to parse numbers as paths or URIs', () => {
|
||||
const args = parseCommandLine([
|
||||
'43',
|
||||
'/some/path',
|
||||
'22',
|
||||
'97',
|
||||
'some/other/path',
|
||||
'atom://test/url',
|
||||
'885',
|
||||
'atom://other/url',
|
||||
'42',
|
||||
'./another-path.file'
|
||||
]);
|
||||
assert.deepEqual(args.urlsToOpen, [
|
||||
'atom://test/url',
|
||||
'atom://other/url'
|
||||
]);
|
||||
assert.deepEqual(args.pathsToOpen, [
|
||||
'/some/path',
|
||||
'some/other/path',
|
||||
'./another-path.file'
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when --uri-handler is passed', () => {
|
||||
@@ -41,4 +100,33 @@ describe('parseCommandLine', () => {
|
||||
assert.deepEqual(args.pathsToOpen, []);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when evil macOS Gatekeeper flag "-psn_0_[six or seven digits here]" is passed', () => {
|
||||
it('ignores any arguments starting with "-psn_"', () => {
|
||||
const getPsnFlag = () => {
|
||||
return `-psn_0_${Math.floor(Math.random() * 10_000_000)}`;
|
||||
};
|
||||
const args = parseCommandLine([
|
||||
getPsnFlag(),
|
||||
'/some/path',
|
||||
getPsnFlag(),
|
||||
getPsnFlag(),
|
||||
'some/other/path',
|
||||
'atom://test/url',
|
||||
getPsnFlag(),
|
||||
'atom://other/url',
|
||||
'-psn_ Any argument starting with "-psn_" should be ignored, even this one.',
|
||||
'./another-path.file'
|
||||
]);
|
||||
assert.deepEqual(args.urlsToOpen, [
|
||||
'atom://test/url',
|
||||
'atom://other/url'
|
||||
]);
|
||||
assert.deepEqual(args.pathsToOpen, [
|
||||
'/some/path',
|
||||
'some/other/path',
|
||||
'./another-path.file'
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,12 @@ const yargs = require('yargs');
|
||||
const { app } = require('electron');
|
||||
|
||||
module.exports = function parseCommandLine(processArgs) {
|
||||
const options = yargs(processArgs).wrap(yargs.terminalWidth());
|
||||
// macOS Gatekeeper adds a flag ("-psn_0_[six or seven digits here]") when it intercepts Atom launches.
|
||||
// (This happens for fresh downloads, new installs, or first launches after upgrading).
|
||||
// We don't need this flag, and yargs interprets it as many short flags. So, we filter it out.
|
||||
const filteredArgs = processArgs.filter(arg => !arg.startsWith('-psn_'));
|
||||
|
||||
const options = yargs(filteredArgs).wrap(yargs.terminalWidth());
|
||||
const version = app.getVersion();
|
||||
options.usage(
|
||||
dedent`Atom Editor v${version}
|
||||
@@ -187,6 +192,11 @@ module.exports = function parseCommandLine(processArgs) {
|
||||
let devMode = args['dev'];
|
||||
|
||||
for (const path of args._) {
|
||||
if (typeof path !== 'string') {
|
||||
// Sometimes non-strings (such as numbers or boolean true) get into args._
|
||||
// In the next block, .startsWith() only works on strings. So, skip non-string arguments.
|
||||
continue;
|
||||
}
|
||||
if (path.startsWith('atom://')) {
|
||||
urlsToOpen.push(path);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user