Page MenuHomePhabricator

D18981.id45515.diff
No OneTemporary

D18981.id45515.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,8 @@
final class FileFinderTestCase extends PhutilTestCase {
- private function newFinder() {
- return id(new FileFinder(dirname(__FILE__).'/data'))
+ private function newFinder($directory = 'data') {
+ return id(new FileFinder(dirname(__FILE__).'/'.$directory))
->excludePath('./exclude')
->excludePath('subdir.txt');
}
@@ -120,6 +120,52 @@
));
}
+ public function testFinderWithGlobMagic() {
+ $this->assertFinder(
+ pht('Glob Magic, Literal .t*t'),
+ $this->newFinder('glob-magic')
+ ->withType('f')
+ ->withSuffix('t*t'),
+ array(
+ 'star.t*t',
+ ));
+
+ $this->assertFinder(
+ pht('Glob Magic, .tesseract'),
+ $this->newFinder('glob-magic')
+ ->withType('f')
+ ->withSuffix('tesseract'),
+ array(
+ 'star.tesseract',
+ ));
+
+ $this->assertFinder(
+ pht('Glob Magic, Name'),
+ $this->newFinder('glob-magic')
+ ->withType('f')
+ ->withName('star-*'),
+ array());
+
+ $this->assertFinder(
+ pht('Glob Magic, Name + Suffix'),
+ $this->newFinder('glob-magic')
+ ->withType('f')
+ ->withName('star-*.*'),
+ array(
+ 'star-*.*',
+ ));
+
+ $this->assertFinder(
+ pht('Glob Magic, Backslash Suffix'),
+ $this->newFinder('glob-magic')
+ ->withType('f')
+ ->withSuffix('\\*'),
+ array(
+ 'backslash\\.\\*',
+ ));
+
+ }
+
private function assertFinder($label, FileFinder $finder, $expect) {
$modes = array(
'php',
diff --git a/src/filesystem/__tests__/glob-magic/backslash\.\* b/src/filesystem/__tests__/glob-magic/backslash\.\*
new file mode 100644
--- /dev/null
+++ b/src/filesystem/__tests__/glob-magic/backslash\.\*
@@ -0,0 +1 @@
+Rigel
diff --git a/src/filesystem/__tests__/glob-magic/star-*.* b/src/filesystem/__tests__/glob-magic/star-*.*
new file mode 100644
--- /dev/null
+++ b/src/filesystem/__tests__/glob-magic/star-*.*
@@ -0,0 +1 @@
+Regulus
diff --git a/src/filesystem/__tests__/glob-magic/star-*.txt b/src/filesystem/__tests__/glob-magic/star-*.txt
new file mode 100644
--- /dev/null
+++ b/src/filesystem/__tests__/glob-magic/star-*.txt
@@ -0,0 +1 @@
+Alpha Centauri
diff --git a/src/filesystem/__tests__/glob-magic/star.t*t b/src/filesystem/__tests__/glob-magic/star.t*t
new file mode 100644
--- /dev/null
+++ b/src/filesystem/__tests__/glob-magic/star.t*t
@@ -0,0 +1 @@
+Levo
diff --git a/src/filesystem/__tests__/glob-magic/star.tesseract b/src/filesystem/__tests__/glob-magic/star.tesseract
new file mode 100644
--- /dev/null
+++ b/src/filesystem/__tests__/glob-magic/star.tesseract
@@ -0,0 +1 @@
+Yemuro

File Metadata

Mime Type
text/plain
Expires
Oct 27 2025, 6:07 PM (24 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
12841907
Default Alt Text
D18981.id45515.diff (4 KB)

Event Timeline