Skip to content

Commit 6f16c62

Browse files
BlackbitDevsnicolas-grekas
authored andcommitted
[Process] Fix finding executables independently of open_basedir
1 parent 32354f6 commit 6f16c62

File tree

3 files changed

+21
-63
lines changed

3 files changed

+21
-63
lines changed

ExecutableFinder.php

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,10 @@ public function addSuffix(string $suffix)
4848
*/
4949
public function find(string $name, ?string $default = null, array $extraDirs = [])
5050
{
51-
if (\ini_get('open_basedir')) {
52-
$searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs);
53-
$dirs = [];
54-
foreach ($searchPath as $path) {
55-
// Silencing against https://bugs.php.net/69240
56-
if (@is_dir($path)) {
57-
$dirs[] = $path;
58-
} else {
59-
if (basename($path) == $name && @is_executable($path)) {
60-
return $path;
61-
}
62-
}
63-
}
64-
} else {
65-
$dirs = array_merge(
66-
explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
67-
$extraDirs
68-
);
69-
}
51+
$dirs = array_merge(
52+
explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
53+
$extraDirs
54+
);
7055

7156
$suffixes = [''];
7257
if ('\\' === \DIRECTORY_SEPARATOR) {
@@ -78,9 +63,18 @@ public function find(string $name, ?string $default = null, array $extraDirs = [
7863
if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
7964
return $file;
8065
}
66+
67+
if (!@is_dir($dir) && basename($dir) === $name.$suffix && @is_executable($dir)) {
68+
return $dir;
69+
}
8170
}
8271
}
8372

73+
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --';
74+
if (\function_exists('exec') && ($executablePath = strtok(@exec($command.' '.escapeshellarg($name)), \PHP_EOL)) && is_executable($executablePath)) {
75+
return $executablePath;
76+
}
77+
8478
return $default;
8579
}
8680
}

PhpExecutableFinder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function find(bool $includeArgs = true)
3636
if ($php = getenv('PHP_BINARY')) {
3737
if (!is_executable($php)) {
3838
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --';
39-
if ($php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) {
39+
if (\function_exists('exec') && $php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) {
4040
if (!is_executable($php)) {
4141
return false;
4242
}

Tests/ExecutableFinderTest.php

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,9 @@
1919
*/
2020
class ExecutableFinderTest extends TestCase
2121
{
22-
private $path;
23-
2422
protected function tearDown(): void
2523
{
26-
if ($this->path) {
27-
// Restore path if it was changed.
28-
putenv('PATH='.$this->path);
29-
}
30-
}
31-
32-
private function setPath($path)
33-
{
34-
$this->path = getenv('PATH');
35-
putenv('PATH='.$path);
24+
putenv('PATH='.($_SERVER['PATH'] ?? $_SERVER['Path']));
3625
}
3726

3827
public function testFind()
@@ -41,7 +30,7 @@ public function testFind()
4130
$this->markTestSkipped('Cannot test when open_basedir is set');
4231
}
4332

44-
$this->setPath(\dirname(\PHP_BINARY));
33+
putenv('PATH='.\dirname(\PHP_BINARY));
4534

4635
$finder = new ExecutableFinder();
4736
$result = $finder->find($this->getPhpBinaryName());
@@ -57,7 +46,7 @@ public function testFindWithDefault()
5746

5847
$expected = 'defaultValue';
5948

60-
$this->setPath('');
49+
putenv('PATH=');
6150

6251
$finder = new ExecutableFinder();
6352
$result = $finder->find('foo', $expected);
@@ -71,7 +60,7 @@ public function testFindWithNullAsDefault()
7160
$this->markTestSkipped('Cannot test when open_basedir is set');
7261
}
7362

74-
$this->setPath('');
63+
putenv('PATH=');
7564

7665
$finder = new ExecutableFinder();
7766

@@ -86,7 +75,7 @@ public function testFindWithExtraDirs()
8675
$this->markTestSkipped('Cannot test when open_basedir is set');
8776
}
8877

89-
$this->setPath('');
78+
putenv('PATH=');
9079

9180
$extraDirs = [\dirname(\PHP_BINARY)];
9281

@@ -109,6 +98,7 @@ public function testFindWithOpenBaseDir()
10998
$this->markTestSkipped('Cannot test when open_basedir is set');
11099
}
111100

101+
putenv('PATH='.\dirname(\PHP_BINARY));
112102
$initialOpenBaseDir = ini_set('open_basedir', \dirname(\PHP_BINARY).\PATH_SEPARATOR.'/');
113103

114104
try {
@@ -121,32 +111,6 @@ public function testFindWithOpenBaseDir()
121111
}
122112
}
123113

124-
/**
125-
* @runInSeparateProcess
126-
*/
127-
public function testFindProcessInOpenBasedir()
128-
{
129-
if (\ini_get('open_basedir')) {
130-
$this->markTestSkipped('Cannot test when open_basedir is set');
131-
}
132-
if ('\\' === \DIRECTORY_SEPARATOR) {
133-
$this->markTestSkipped('Cannot run test on windows');
134-
}
135-
136-
$this->setPath('');
137-
138-
$initialOpenBaseDir = ini_set('open_basedir', \PHP_BINARY.\PATH_SEPARATOR.'/');
139-
140-
try {
141-
$finder = new ExecutableFinder();
142-
$result = $finder->find($this->getPhpBinaryName(), false);
143-
144-
$this->assertSamePath(\PHP_BINARY, $result);
145-
} finally {
146-
ini_set('open_basedir', $initialOpenBaseDir);
147-
}
148-
}
149-
150114
public function testFindBatchExecutableOnWindows()
151115
{
152116
if (\ini_get('open_basedir')) {
@@ -163,7 +127,7 @@ public function testFindBatchExecutableOnWindows()
163127

164128
$this->assertFalse(is_executable($target));
165129

166-
$this->setPath(sys_get_temp_dir());
130+
putenv('PATH='.sys_get_temp_dir());
167131

168132
$finder = new ExecutableFinder();
169133
$result = $finder->find(basename($target), false);

0 commit comments

Comments
 (0)