Skip to content

Commit 250ae06

Browse files
committed
Merge branch '5.4' into 6.4
* 5.4: fix the directory separator being used ignore case of built-in cmd.exe commands [Process] Improve test cleanup by unlinking in a `finally` block [Process] Return built-in cmd.exe commands directly in ExecutableFinder
2 parents 593ecb8 + d67303e commit 250ae06

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

ExecutableFinder.php

+12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@
2020
class ExecutableFinder
2121
{
2222
private array $suffixes = ['.exe', '.bat', '.cmd', '.com'];
23+
private const CMD_BUILTINS = [
24+
'assoc', 'break', 'call', 'cd', 'chdir', 'cls', 'color', 'copy', 'date',
25+
'del', 'dir', 'echo', 'endlocal', 'erase', 'exit', 'for', 'ftype', 'goto',
26+
'help', 'if', 'label', 'md', 'mkdir', 'mklink', 'move', 'path', 'pause',
27+
'popd', 'prompt', 'pushd', 'rd', 'rem', 'ren', 'rename', 'rmdir', 'set',
28+
'setlocal', 'shift', 'start', 'time', 'title', 'type', 'ver', 'vol',
29+
];
2330

2431
/**
2532
* Replaces default suffixes of executable.
@@ -50,6 +57,11 @@ public function addSuffix(string $suffix)
5057
*/
5158
public function find(string $name, ?string $default = null, array $extraDirs = []): ?string
5259
{
60+
// windows built-in commands that are present in cmd.exe should not be resolved using PATH as they do not exist as exes
61+
if ('\\' === \DIRECTORY_SEPARATOR && \in_array(strtolower($name), self::CMD_BUILTINS, true)) {
62+
return $name;
63+
}
64+
5365
$dirs = array_merge(
5466
explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
5567
$extraDirs

Tests/ExecutableFinderTest.php

+32-16
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,20 @@ public function testFindBatchExecutableOnWindows()
125125

126126
$target = tempnam(sys_get_temp_dir(), 'example-windows-executable');
127127

128-
touch($target);
129-
touch($target.'.BAT');
130-
131-
$this->assertFalse(is_executable($target));
128+
try {
129+
touch($target);
130+
touch($target.'.BAT');
132131

133-
putenv('PATH='.sys_get_temp_dir());
132+
$this->assertFalse(is_executable($target));
134133

135-
$finder = new ExecutableFinder();
136-
$result = $finder->find(basename($target), false);
134+
putenv('PATH='.sys_get_temp_dir());
137135

138-
unlink($target);
139-
unlink($target.'.BAT');
136+
$finder = new ExecutableFinder();
137+
$result = $finder->find(basename($target), false);
138+
} finally {
139+
unlink($target);
140+
unlink($target.'.BAT');
141+
}
140142

141143
$this->assertSamePath($target.'.BAT', $result);
142144
}
@@ -146,17 +148,31 @@ public function testFindBatchExecutableOnWindows()
146148
*/
147149
public function testEmptyDirInPath()
148150
{
149-
putenv(sprintf('PATH=%s:', \dirname(\PHP_BINARY)));
151+
putenv(sprintf('PATH=%s%s', \dirname(\PHP_BINARY), \PATH_SEPARATOR));
150152

151-
touch('executable');
152-
chmod('executable', 0700);
153+
try {
154+
touch('executable');
155+
chmod('executable', 0700);
153156

154-
$finder = new ExecutableFinder();
155-
$result = $finder->find('executable');
157+
$finder = new ExecutableFinder();
158+
$result = $finder->find('executable');
156159

157-
$this->assertSame('./executable', $result);
160+
$this->assertSame('./executable', $result);
161+
} finally {
162+
unlink('executable');
163+
}
164+
}
158165

159-
unlink('executable');
166+
public function testFindBuiltInCommandOnWindows()
167+
{
168+
if ('\\' !== \DIRECTORY_SEPARATOR) {
169+
$this->markTestSkipped('Can be only tested on windows');
170+
}
171+
172+
$finder = new ExecutableFinder();
173+
$this->assertSame('rmdir', strtolower($finder->find('RMDIR')));
174+
$this->assertSame('cd', strtolower($finder->find('cd')));
175+
$this->assertSame('move', strtolower($finder->find('MoVe')));
160176
}
161177

162178
private function assertSamePath($expected, $tested)

0 commit comments

Comments
 (0)