Page MenuHomePhabricator

D18981.id.diff
No OneTemporary

D18981.id.diff

diff --git a/src/filesystem/FileFinder.php b/src/filesystem/FileFinder.php
--- a/src/filesystem/FileFinder.php
+++ b/src/filesystem/FileFinder.php
@@ -58,7 +58,7 @@
* @task config
*/
public function withSuffix($suffix) {
- $this->suffix[] = '*.'.$suffix;
+ $this->suffix[] = $suffix;
return $this;
}
@@ -128,8 +128,10 @@
if ($this->suffix) {
$matches = false;
- foreach ($this->suffix as $curr_suffix) {
- if (fnmatch($curr_suffix, $file)) {
+ foreach ($this->suffix as $suffix) {
+ $suffix = addcslashes($suffix, '\\?*');
+ $suffix = '*.'.$suffix;
+ if (fnmatch($suffix, $file)) {
$matches = true;
break;
}
@@ -248,11 +250,11 @@
}
if ($this->name) {
- $command[] = $this->generateList('name', $this->name);
+ $command[] = $this->generateList('name', $this->name, 'name');
}
if ($this->suffix) {
- $command[] = $this->generateList('name', $this->suffix);
+ $command[] = $this->generateList('name', $this->suffix, 'suffix');
}
if ($this->paths) {
@@ -307,11 +309,29 @@
/**
* @task internal
*/
- private function generateList($flag, array $items) {
- $items = array_map('escapeshellarg', $items);
+ private function generateList(
+ $flag,
+ array $items,
+ $mode = 'path') {
+
foreach ($items as $key => $item) {
- $items[$key] = '-'.$flag.' '.$item;
+ // If the mode is not "path" mode, we're going to escape glob characters
+ // in the pattern. Otherwise, we escape only backslashes.
+ if ($mode === 'path') {
+ $item = addcslashes($item, '\\');
+ } else {
+ $item = addcslashes($item, '\\*?');
+ }
+
+ if ($mode === 'suffix') {
+ $item = '*.'.$item;
+ }
+
+ $item = (string)csprintf('%s %s', '-'.$flag, $item);
+
+ $items[$key] = $item;
}
+
$items = implode(' -o ', $items);
return '"(" '.$items.' ")"';
}
diff --git a/src/filesystem/__tests__/FileFinderTestCase.php b/src/filesystem/__tests__/FileFinderTestCase.php
--- a/src/filesystem/__tests__/FileFinderTestCase.php
+++ b/src/filesystem/__tests__/FileFinderTestCase.php
@@ -2,8 +2,12 @@
final class FileFinderTestCase extends PhutilTestCase {
- private function newFinder() {
- return id(new FileFinder(dirname(__FILE__).'/data'))
+ private function newFinder($directory = null) {
+ if (!$directory) {
+ $directory = dirname(__FILE__).'/data';
+ }
+
+ return id(new FileFinder($directory))
->excludePath('./exclude')
->excludePath('subdir.txt');
}
@@ -120,6 +124,68 @@
));
}
+ public function testFinderWithGlobMagic() {
+ // Fill a temporary directory with all this magic garbage so we don't have
+ // to check a bunch of files with backslashes in their names into version
+ // control.
+ $tmp_dir = Filesystem::createTemporaryDirectory();
+
+ $crazy_magic = array(
+ 'backslash\\.\\*',
+ 'star-*.*',
+ 'star-*.txt',
+ 'star.t*t',
+ 'star.tesseract',
+ );
+
+ foreach ($crazy_magic as $sketchy_path) {
+ Filesystem::writeFile($tmp_dir.'/'.$sketchy_path, '.');
+ }
+
+ $this->assertFinder(
+ pht('Glob Magic, Literal .t*t'),
+ $this->newFinder($tmp_dir)
+ ->withType('f')
+ ->withSuffix('t*t'),
+ array(
+ 'star.t*t',
+ ));
+
+ $this->assertFinder(
+ pht('Glob Magic, .tesseract'),
+ $this->newFinder($tmp_dir)
+ ->withType('f')
+ ->withSuffix('tesseract'),
+ array(
+ 'star.tesseract',
+ ));
+
+ $this->assertFinder(
+ pht('Glob Magic, Name'),
+ $this->newFinder($tmp_dir)
+ ->withType('f')
+ ->withName('star-*'),
+ array());
+
+ $this->assertFinder(
+ pht('Glob Magic, Name + Suffix'),
+ $this->newFinder($tmp_dir)
+ ->withType('f')
+ ->withName('star-*.*'),
+ array(
+ 'star-*.*',
+ ));
+
+ $this->assertFinder(
+ pht('Glob Magic, Backslash Suffix'),
+ $this->newFinder($tmp_dir)
+ ->withType('f')
+ ->withSuffix('\\*'),
+ array(
+ 'backslash\\.\\*',
+ ));
+ }
+
private function assertFinder($label, FileFinder $finder, $expect) {
$modes = array(
'php',

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 22, 11:23 AM (6 d, 14 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
9037833
Default Alt Text
D18981.id.diff (4 KB)

Event Timeline