From 46c203f382b73a2575d043e49a17073d3c808fad Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 2 Nov 2024 14:14:29 +0100 Subject: [PATCH 1/6] [Process] Return built-in cmd.exe commands directly in ExecutableFinder --- ExecutableFinder.php | 12 ++++++++++++ Tests/ExecutableFinderTest.php | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/ExecutableFinder.php b/ExecutableFinder.php index 2293595c..1604b6f0 100644 --- a/ExecutableFinder.php +++ b/ExecutableFinder.php @@ -20,6 +20,13 @@ class ExecutableFinder { private $suffixes = ['.exe', '.bat', '.cmd', '.com']; + private const CMD_BUILTINS = [ + 'assoc', 'break', 'call', 'cd', 'chdir', 'cls', 'color', 'copy', 'date', + 'del', 'dir', 'echo', 'endlocal', 'erase', 'exit', 'for', 'ftype', 'goto', + 'help', 'if', 'label', 'md', 'mkdir', 'mklink', 'move', 'path', 'pause', + 'popd', 'prompt', 'pushd', 'rd', 'rem', 'ren', 'rename', 'rmdir', 'set', + 'setlocal', 'shift', 'start', 'time', 'title', 'type', 'ver', 'vol', + ]; /** * Replaces default suffixes of executable. @@ -48,6 +55,11 @@ public function addSuffix(string $suffix) */ public function find(string $name, ?string $default = null, array $extraDirs = []) { + // windows built-in commands that are present in cmd.exe should not be resolved using PATH as they do not exist as exes + if ('\\' === \DIRECTORY_SEPARATOR && \in_array(strtolower($name), self::CMD_BUILTINS, true)) { + return $name; + } + $dirs = array_merge( explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), $extraDirs diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index c4876e47..adb5556d 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -159,6 +159,18 @@ public function testEmptyDirInPath() unlink('executable'); } + public function testFindBuiltInCommandOnWindows() + { + if ('\\' !== \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Can be only tested on windows'); + } + + $finder = new ExecutableFinder(); + $this->assertSame('rmdir', $finder->find('RMDIR')); + $this->assertSame('cd', $finder->find('cd')); + $this->assertSame('move', $finder->find('MoVe')); + } + private function assertSamePath($expected, $tested) { if ('\\' === \DIRECTORY_SEPARATOR) { From b61fb1c70392905d5f5f99824324983124a1dd08 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 4 Nov 2024 09:44:46 +0100 Subject: [PATCH 2/6] [Process] Improve test cleanup by unlinking in a `finally` block --- Tests/ExecutableFinderTest.php | 36 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index c4876e47..3995e73a 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -125,18 +125,20 @@ public function testFindBatchExecutableOnWindows() $target = tempnam(sys_get_temp_dir(), 'example-windows-executable'); - touch($target); - touch($target.'.BAT'); - - $this->assertFalse(is_executable($target)); + try { + touch($target); + touch($target.'.BAT'); - putenv('PATH='.sys_get_temp_dir()); + $this->assertFalse(is_executable($target)); - $finder = new ExecutableFinder(); - $result = $finder->find(basename($target), false); + putenv('PATH='.sys_get_temp_dir()); - unlink($target); - unlink($target.'.BAT'); + $finder = new ExecutableFinder(); + $result = $finder->find(basename($target), false); + } finally { + unlink($target); + unlink($target.'.BAT'); + } $this->assertSamePath($target.'.BAT', $result); } @@ -148,15 +150,17 @@ public function testEmptyDirInPath() { putenv(sprintf('PATH=%s:', \dirname(\PHP_BINARY))); - touch('executable'); - chmod('executable', 0700); - - $finder = new ExecutableFinder(); - $result = $finder->find('executable'); + try { + touch('executable'); + chmod('executable', 0700); - $this->assertSame('./executable', $result); + $finder = new ExecutableFinder(); + $result = $finder->find('executable'); - unlink('executable'); + $this->assertSame('./executable', $result); + } finally { + unlink('executable'); + } } private function assertSamePath($expected, $tested) From a56fe7b6066efd82037aedfbd1c657e3bcce1810 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 4 Nov 2024 10:27:52 +0100 Subject: [PATCH 3/6] ignore case of built-in cmd.exe commands --- Tests/ExecutableFinderTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index adb5556d..e335e47c 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -166,9 +166,9 @@ public function testFindBuiltInCommandOnWindows() } $finder = new ExecutableFinder(); - $this->assertSame('rmdir', $finder->find('RMDIR')); - $this->assertSame('cd', $finder->find('cd')); - $this->assertSame('move', $finder->find('MoVe')); + $this->assertSame('rmdir', strtolower($finder->find('RMDIR'))); + $this->assertSame('cd', strtolower($finder->find('cd'))); + $this->assertSame('move', strtolower($finder->find('MoVe'))); } private function assertSamePath($expected, $tested) From 7be8366a553b0ea5ec03d01f68c2214b1ce82e89 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 4 Nov 2024 10:25:02 +0100 Subject: [PATCH 4/6] fix the directory separator being used --- Tests/ExecutableFinderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index c4876e47..f85d8c9a 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -146,7 +146,7 @@ public function testFindBatchExecutableOnWindows() */ public function testEmptyDirInPath() { - putenv(sprintf('PATH=%s:', \dirname(\PHP_BINARY))); + putenv(sprintf('PATH=%s%s', \dirname(\PHP_BINARY), \PATH_SEPARATOR)); touch('executable'); chmod('executable', 0700); From 81e1a0cdac68330b5acec27c427cf59be49c73f7 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 4 Nov 2024 11:01:19 +0100 Subject: [PATCH 5/6] fix the path separator being used --- Tests/ExecutableFinderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index 4a6c2c4b..fbeb7f07 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -157,7 +157,7 @@ public function testEmptyDirInPath() $finder = new ExecutableFinder(); $result = $finder->find('executable'); - $this->assertSame('./executable', $result); + $this->assertSame(sprintf('.%sexecutable', \PATH_SEPARATOR), $result); } finally { unlink('executable'); } From 72baf6b0591f07b051450bdf2608f93fb5c0a6e5 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 4 Nov 2024 11:14:40 +0100 Subject: [PATCH 6/6] fix the constant being used --- Tests/ExecutableFinderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index fbeb7f07..4aadd9b2 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -157,7 +157,7 @@ public function testEmptyDirInPath() $finder = new ExecutableFinder(); $result = $finder->find('executable'); - $this->assertSame(sprintf('.%sexecutable', \PATH_SEPARATOR), $result); + $this->assertSame(sprintf('.%sexecutable', \DIRECTORY_SEPARATOR), $result); } finally { unlink('executable'); }