Browse files

merged branch jfsimon/finder-access-denied-exception (PR #7256)

This PR was merged into the master branch.

Discussion
----------

[Finder] Adds AccessDeniedException

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | yes
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #6981

Commits
-------

714ace8 [finder] Introduced AccessDeniedException
  • Loading branch information...
2 parents 2f7a9fd + 714ace8 commit e5be0ded50da2d4dca18978fd7e559ce59409ae3 @fabpot fabpot committed Mar 23, 2013
View
5 src/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Finder\Adapter;
+use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\Finder\Iterator;
use Symfony\Component\Finder\Shell\Shell;
use Symfony\Component\Finder\Expression\Expression;
@@ -91,6 +92,10 @@ public function searchInDirectory($dir)
$this->buildSorting($command, $this->sort);
}
+ $command->setErrorHandler(function ($stderr) {
+ throw new AccessDeniedException($stderr);
+ });
+
$paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
$iterator = new Iterator\FilePathsIterator($paths, $dir);
View
10 src/Symfony/Component/Finder/Exception/AccessDeniedException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace Symfony\Component\Finder\Exception;
+
+/**
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ */
+class AccessDeniedException extends \UnexpectedValueException
+{
+}
View
15 src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Finder\Iterator;
+use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\Finder\SplFileInfo;
/**
@@ -38,4 +39,18 @@ public function current()
{
return new SplFileInfo(parent::current()->getPathname(), $this->getSubPath(), $this->getSubPathname());
}
+
+ /**
+ * @return mixed object
+ *
+ * @throws AccessDeniedException
+ */
+ public function getChildren()
+ {
+ try {
+ return parent::getChildren();
+ } catch (\UnexpectedValueException $e) {
+ throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
}
View
38 src/Symfony/Component/Finder/Shell/Command.php
@@ -32,6 +32,11 @@ class Command
private $labels;
/**
+ * @var \Closure|null
+ */
+ private $errorHandler;
+
+ /**
* Constructor.
*
* @param Command $parent Parent command
@@ -215,6 +220,26 @@ public function length()
}
/**
+ * @param \Closure $errorHandler
+ *
+ * @return Command
+ */
+ public function setErrorHandler(\Closure $errorHandler)
+ {
+ $this->errorHandler = $errorHandler;
+
+ return $this;
+ }
+
+ /**
+ * @return callable|null
+ */
+ public function getErrorHandler()
+ {
+ return $this->errorHandler;
+ }
+
+ /**
* Executes current command.
*
* @return array The command result
@@ -223,10 +248,17 @@ public function length()
*/
public function execute()
{
- exec($this->join(), $output, $code);
+ if (null === $this->errorHandler) {
+ exec($this->join(), $output);
+ } else {
+ $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
+ $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);
+
+ if ($error = stream_get_contents($pipes[2])) {
+ call_user_func($this->errorHandler, $error);
+ }
- if (0 !== $code) {
- throw new \RuntimeException('Execution failed with return code: '.$code.'.');
+ proc_close($process);
}
return $output ?: array();
View
21 src/Symfony/Component/Finder/Tests/FinderTest.php
@@ -717,6 +717,27 @@ public function getTestPathData()
return $this->buildTestData($tests);
}
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAccessDeniedException(Adapter\AdapterInterface $adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->in(self::$tmpDir);
+
+ // make 'foo' directory non-openable
+ chmod(self::$tmpDir.DIRECTORY_SEPARATOR.'foo', 0333);
+
+ try {
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->getIterator());
+ $this->fail('Finder should throw an exception when opening a non-readable directory.');
+ } catch (\Exception $e) {
+ $this->assertEquals('Symfony\\Component\\Finder\\Exception\\AccessDeniedException', get_class($e));
+ }
+
+ chmod(self::$tmpDir.DIRECTORY_SEPARATOR.'foo', 0777);
+ }
+
private function buildTestData(array $tests)
{
$data = array();

0 comments on commit e5be0de

Please sign in to comment.