Skip to content

Commit

Permalink
[BUGFIX] Prevent infinite loops caused by symlinks
Browse files Browse the repository at this point in the history
  • Loading branch information
s2b committed Aug 26, 2019
1 parent 218e7ae commit d53c9c6
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 7 deletions.
21 changes: 15 additions & 6 deletions Classes/Utility/ComponentLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,12 @@ public function findComponentsInNamespace(string $namespace, string $ext = '.htm
return [];
}

$scannedPaths = [];
return $this->scanForComponents(
$this->namespaces[$namespace],
$ext,
$namespace
$namespace,
$scannedPaths
);
}

Expand All @@ -152,20 +154,27 @@ public function findComponentsInNamespace(string $namespace, string $ext = '.htm
* @param string $path
* @param string $ext
* @param string $namespace
* @param array $scannedPaths Collection of paths that have already been scanned for components;
* this prevents infinite loops caused by circular symlinks
* @return array
*/
protected function scanForComponents(string $path, string $ext, string $namespace): array
protected function scanForComponents(string $path, string $ext, string $namespace, array &$scannedPaths): array
{
$components = [];

$componentCandidates = scandir($path);
foreach ($componentCandidates as $componentName) {
$componentPath = $path . DIRECTORY_SEPARATOR . $componentName;
// Skip relative links
if ($componentName === '.' || $componentName === '..') {
continue;
}

// Only search for directories
if ($componentName === '.' || $componentName === '..' || !is_dir($componentPath)) {
// Only search for directories and prevent infinite loops
$componentPath = realpath($path . DIRECTORY_SEPARATOR . $componentName);
if (!is_dir($componentPath) || isset($scannedPaths[$componentPath])) {
continue;
}
$scannedPaths[$componentPath] = true;

$componentNamespace = $namespace . '\\' . $componentName;
$componentFile = $componentPath . DIRECTORY_SEPARATOR . $componentName . $ext;
Expand All @@ -178,7 +187,7 @@ protected function scanForComponents(string $path, string $ext, string $namespac
// Continue recursively
$components = array_merge(
$components,
$this->scanForComponents($componentPath, $ext, $componentNamespace)
$this->scanForComponents($componentPath, $ext, $componentNamespace, $scannedPaths)
);
}

Expand Down
1 change: 1 addition & 0 deletions Tests/Fixtures/ComponentLoader/Atom/ComponentLoaderSymlink
1 change: 1 addition & 0 deletions Tests/Fixtures/ComponentLoader/Molecule/Circular
1 change: 1 addition & 0 deletions Tests/Fixtures/ComponentLoader/Molecule/Example
Empty file.
3 changes: 2 additions & 1 deletion Tests/Unit/ComponentLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ protected function setUp()

protected function getFixturePath($fixtureName)
{
return dirname(__FILE__) . '/../Fixtures/' . $fixtureName;
return realpath(dirname(__FILE__) . '/../Fixtures/' . $fixtureName);
}

public function addNamespaceProvider()
Expand Down Expand Up @@ -177,6 +177,7 @@ public function findComponentsInNamespaceProvider()
'.html',
[
'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Button' => $this->getFixturePath('ComponentLoader/Atom/Button/Button.html'),
'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\ComponentLoaderSymlink' => $this->getFixturePath('ComponentLoader/Atom/ComponentLoaderSymlink/ComponentLoaderSymlink.html'),
'Sitegeist\\Fixtures\\ComponentLoader\\Atom\\Link' => $this->getFixturePath('ComponentLoader/Atom/Link/Link.html'),
'Sitegeist\\Fixtures\\ComponentLoader\\Example' => $this->getFixturePath('ComponentLoader/Example/Example.html'),
'Sitegeist\\Fixtures\\ComponentLoader\\Molecule\\Teaser' => $this->getFixturePath('ComponentLoader/Molecule/Teaser/Teaser.html'),
Expand Down

0 comments on commit d53c9c6

Please sign in to comment.