Skip to content

Commit 8c7ea57

Browse files
committed
fix(self-update): use realpath via Safe namespace for global scope checks
1 parent 090f944 commit 8c7ea57

1 file changed

Lines changed: 19 additions & 2 deletions

File tree

src/SelfUpdate/ComposerSelfUpdateScopeResolver.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
use FastForward\DevTools\Environment\EnvironmentInterface;
2323
use FastForward\DevTools\Path\DevToolsPathResolver;
2424
use Symfony\Component\Filesystem\Path;
25+
use Throwable;
26+
27+
use function Safe\realpath;
2528

2629
/**
2730
* Detects Composer global DevTools installations from known Composer home paths.
@@ -44,10 +47,10 @@ public function __construct(
4447
*/
4548
public function isGlobalInstallation(): bool
4649
{
47-
$packagePath = Path::canonicalize($this->packagePath ?? DevToolsPathResolver::getPackagePath());
50+
$packagePath = $this->normalizePath($this->packagePath ?? DevToolsPathResolver::getPackagePath());
4851

4952
foreach ($this->getComposerHomeCandidates() as $composerHome) {
50-
$globalPackagePath = Path::canonicalize(Path::join($composerHome, self::PACKAGE_PATH));
53+
$globalPackagePath = $this->normalizePath(Path::join($composerHome, self::PACKAGE_PATH));
5154

5255
if ($packagePath === $globalPackagePath || str_starts_with(
5356
$packagePath,
@@ -96,4 +99,18 @@ private function getComposerHomeCandidates(): array
9699

97100
return array_values(array_unique($candidates));
98101
}
102+
103+
/**
104+
* Safely canonicalizes a path, resolving symlinks when available.
105+
*
106+
* @param string $path
107+
*/
108+
private function normalizePath(string $path): string
109+
{
110+
try {
111+
return Path::canonicalize(realpath($path));
112+
} catch (Throwable) {
113+
return Path::canonicalize($path);
114+
}
115+
}
99116
}

0 commit comments

Comments
 (0)