diff --git a/spec/app/project-spec.coffee b/spec/app/project-spec.coffee index 0fa2045bc..e1bd3c48b 100644 --- a/spec/app/project-spec.coffee +++ b/spec/app/project-spec.coffee @@ -135,3 +135,10 @@ describe "Project", -> path: project.resolve('a') match: ['aa', 'a'] range: [[1, 3], [1, 5]] + + it "works on evil filenames", -> + project.setPath(require.resolve('fixtures/evil-files')) + waitsForPromise -> + project.scan /(a)+/, ({path, match, range}) -> + matches.push({path, match, range}) + diff --git a/spec/extensions/tree-view-spec.coffee b/spec/extensions/tree-view-spec.coffee index 12aa90cd1..467d70757 100644 --- a/spec/extensions/tree-view-spec.coffee +++ b/spec/extensions/tree-view-spec.coffee @@ -31,12 +31,12 @@ describe "TreeView", -> expect(treeView.root.find('> .header .name')).toHaveText('fixtures/') rootEntries = treeView.root.find('.entries') - subdir1 = rootEntries.find('> li:eq(0)') - expect(subdir1.find('.disclosure-arrow')).toHaveText('▸') - expect(subdir1.find('.name')).toHaveText('dir/') - expect(subdir1.find('.entries')).not.toExist() + subdir0 = rootEntries.find('> li:eq(0)') + expect(subdir0.find('.disclosure-arrow')).toHaveText('▸') + expect(subdir0.find('.name')).toHaveText('dir/') + expect(subdir0.find('.entries')).not.toExist() - subdir2 = rootEntries.find('> li:eq(1)') + subdir2 = rootEntries.find('> li:eq(2)') expect(subdir2.find('.disclosure-arrow')).toHaveText('▸') expect(subdir2.find('.name')).toHaveText('zed/') expect(subdir2.find('.entries')).not.toExist() diff --git a/spec/fixtures/evil-files/file with spaces.txt b/spec/fixtures/evil-files/file with spaces.txt new file mode 100644 index 000000000..e69de29bb diff --git "a/spec/fixtures/evil-files/goddam\nlinefeeds" "b/spec/fixtures/evil-files/goddam\nlinefeeds" new file mode 100644 index 000000000..9092125e2 --- /dev/null +++ "b/spec/fixtures/evil-files/goddam\nlinefeeds" @@ -0,0 +1 @@ +you know how we do it diff --git "a/spec/fixtures/evil-files/quote\".js" "b/spec/fixtures/evil-files/quote\".js" new file mode 100644 index 000000000..fc0196531 --- /dev/null +++ "b/spec/fixtures/evil-files/quote\".js" @@ -0,0 +1 @@ +// I am evil because there's a " in my filename. Why you do that!? \ No newline at end of file diff --git a/spec/fixtures/evil-files/utfă.md b/spec/fixtures/evil-files/utfă.md new file mode 100644 index 000000000..aca94adc6 --- /dev/null +++ b/spec/fixtures/evil-files/utfă.md @@ -0,0 +1,3 @@ +# Hello Word + +This is markdown. diff --git a/src/app/project.coffee b/src/app/project.coffee index 9098c7e26..d7050a1c2 100644 --- a/src/app/project.coffee +++ b/src/app/project.coffee @@ -138,13 +138,13 @@ class Project scan: (regex, iterator) -> regex = new RegExp(regex.source, 'g') - commands = [ - "find \"#{@getPath()}\" -type f" - "grep --perl-regexp --invert-match --regexp=\"#{@ignorePathRegex()}\"" - "xargs grep --null --perl-regexp --with-filename --line-number --recursive --regexp=\"#{regex.source}\"" - ] + command = [ + "find \"#{@getPath()}\" -type f -print0" # find all paths in the project's working directory + "grep --text --perl-regexp --invert-match --regexp=\"#{@ignorePathRegex()}\"" # accept only non-ignored paths, separated by \0 (find doesn't support pcre) + "perl -0pi -e 's/\n$//'" # delete grep's trailing newline because it screws up xargs + "xargs -0 grep --null --perl-regexp --with-filename --line-number --recursive --regexp=\"#{regex.source}\"" # run grep on each filtered file + ].join(" | ") - command = commands.join(" | ") ChildProcess.exec command, bufferLines: true, stdout: (data) -> for grepLine in data.split('\n') when grepLine.length nullCharIndex = grepLine.indexOf('\0')