Skip to content

Commit 593ecb8

Browse files
Merge branch '5.4' into 6.4
* 5.4: [Process] Properly deal with not-found executables on Windows [Process] Fix handling empty path found in the PATH env var with ExecutableFinder
2 parents 1f9f59b + 32dfba3 commit 593ecb8

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

ExecutableFinder.php

+11-2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ public function find(string $name, ?string $default = null, array $extraDirs = [
6262
}
6363
foreach ($suffixes as $suffix) {
6464
foreach ($dirs as $dir) {
65+
if ('' === $dir) {
66+
$dir = '.';
67+
}
6568
if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
6669
return $file;
6770
}
@@ -72,8 +75,14 @@ public function find(string $name, ?string $default = null, array $extraDirs = [
7275
}
7376
}
7477

75-
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --';
76-
if (\function_exists('exec') && ($executablePath = strtok(@exec($command.' '.escapeshellarg($name)), \PHP_EOL)) && @is_executable($executablePath)) {
78+
if (!\function_exists('exec') || \strlen($name) !== strcspn($name, '/'.\DIRECTORY_SEPARATOR)) {
79+
return $default;
80+
}
81+
82+
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where %s 2> NUL' : 'command -v -- %s';
83+
$execResult = exec(\sprintf($command, escapeshellarg($name)));
84+
85+
if (($executablePath = substr($execResult, 0, strpos($execResult, \PHP_EOL) ?: null)) && @is_executable($executablePath)) {
7786
return $executablePath;
7887
}
7988

PhpExecutableFinder.php

+10-6
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ public function find(bool $includeArgs = true): string|false
3333
{
3434
if ($php = getenv('PHP_BINARY')) {
3535
if (!is_executable($php)) {
36-
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --';
37-
if (\function_exists('exec') && $php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) {
38-
if (!is_executable($php)) {
39-
return false;
40-
}
41-
} else {
36+
if (!\function_exists('exec') || \strlen($php) !== strcspn($php, '/'.\DIRECTORY_SEPARATOR)) {
37+
return false;
38+
}
39+
40+
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where %s 2> NUL' : 'command -v -- %s';
41+
$execResult = exec(\sprintf($command, escapeshellarg($php)));
42+
if (!$php = substr($execResult, 0, strpos($execResult, \PHP_EOL) ?: null)) {
43+
return false;
44+
}
45+
if (!is_executable($php)) {
4246
return false;
4347
}
4448
}

Tests/ExecutableFinderTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ public function testFindWithOpenBaseDir()
111111
}
112112
}
113113

114+
/**
115+
* @runInSeparateProcess
116+
*/
114117
public function testFindBatchExecutableOnWindows()
115118
{
116119
if (\ini_get('open_basedir')) {
@@ -138,6 +141,24 @@ public function testFindBatchExecutableOnWindows()
138141
$this->assertSamePath($target.'.BAT', $result);
139142
}
140143

144+
/**
145+
* @runInSeparateProcess
146+
*/
147+
public function testEmptyDirInPath()
148+
{
149+
putenv(sprintf('PATH=%s:', \dirname(\PHP_BINARY)));
150+
151+
touch('executable');
152+
chmod('executable', 0700);
153+
154+
$finder = new ExecutableFinder();
155+
$result = $finder->find('executable');
156+
157+
$this->assertSame('./executable', $result);
158+
159+
unlink('executable');
160+
}
161+
141162
private function assertSamePath($expected, $tested)
142163
{
143164
if ('\\' === \DIRECTORY_SEPARATOR) {

0 commit comments

Comments
 (0)