Skip to content

Commit

Permalink
Fix Composer autoloader being hijackable by script/plugin event handl…
Browse files Browse the repository at this point in the history
…ers, fixes composer#11940
  • Loading branch information
Seldaek committed Apr 28, 2024
1 parent 0d5549f commit 73c3a9c
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/Composer/EventDispatcher/EventDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ protected function doDispatch(Event $event)

$this->pushEvent($event);

$autoloadersBefore = spl_autoload_functions();

try {
$returnMax = 0;
foreach ($listeners as $callable) {
Expand Down Expand Up @@ -411,6 +413,24 @@ protected function doDispatch(Event $event)
}
} finally {
$this->popEvent();

$knownIdentifiers = [];
foreach ($autoloadersBefore as $key => $cb) {

Check failure on line 418 in src/Composer/EventDispatcher/EventDispatcher.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.2, false)

Argument of an invalid type array<int, callable>|false supplied for foreach, only iterables are supported.
$knownIdentifiers[$this->getCallbackIdentifier($cb)] = ['key' => $key, 'callback' => $cb];
}
foreach (spl_autoload_functions() as $cb) {

Check failure on line 421 in src/Composer/EventDispatcher/EventDispatcher.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.2, false)

Argument of an invalid type array<int, callable>|false supplied for foreach, only iterables are supported.
// once we get to the first known autoloader, we can leave any appended autoloader without problems
if (isset($knownIdentifiers[$this->getCallbackIdentifier($cb)]) && $knownIdentifiers[$this->getCallbackIdentifier($cb)]['key'] === 0) {
break;
}
if ($cb instanceof ClassLoader) {
$cb->unregister();
$cb->register(false);
} else {
spl_autoload_unregister($cb);
spl_autoload_register($cb);
}
}
}

return $returnMax;
Expand Down Expand Up @@ -638,4 +658,20 @@ private function ensureBinDirIsInPath(): void
}
}
}

private function getCallbackIdentifier(callable $cb): string
{
if (is_string($cb)) {
return 'fn:'.$cb;
}
if (is_object($cb)) {
return 'obj:'.spl_object_hash($cb);
}
if (is_array($cb)) {
return 'array:'.(is_string($cb[0]) ? $cb[0] : get_class($cb[0]) .'#'.spl_object_hash($cb[0])).'::'.$cb[1];
}

// not great but also do not want to break everything here
return 'unsupported';
}
}

0 comments on commit 73c3a9c

Please sign in to comment.