Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: symfony/process
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v6.4.7
Choose a base ref
...
head repository: symfony/process
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v6.4.14
Choose a head ref

Commits on May 6, 2024

  1. Copy the full SHA
    b3da76c View commit details

Commits on May 7, 2024

  1. Return false in isTtySupported() when open_basedir restrictions preve…

    …nt access to /dev/tty.
    
    If open_basedir restrictions are in effect, checking if the file /dev/tty is writable will prevent setting tty mode on the process, and avoid failing to create a Process.
    mjauvin authored May 7, 2024
    Copy the full SHA
    1393de6 View commit details

Commits on May 17, 2024

  1. Merge branch '5.4' into 6.4

    * 5.4:
      [PropertyInfo] Update DoctrineExtractor for new DBAL 4 BIGINT type
      Update security.nl.xlf
      [Validator] IBAN Check digits should always between 2 and 98
      [Security] Populate translations for trans-unit 20
      add missing plural translation messages
      filter out empty HTTP header parts
      [String] Fix folded in compat mode
      Remove calls to `getMockForAbstractClass()`
      [ErrorHandler] Do not call xdebug_get_function_stack() with xdebug >= 3.0 when not in develop mode
      [Serializer] Fix type for missing property
      add test for JSON response with null as content
      [Filesystem] Fix dumpFile `stat failed` error hitting custom handler
      Remove calls to `TestCase::iniSet()` and calls to deprecated methods of `MockBuilder`
      [PhpUnitBridge] Fix `DeprecationErrorHandler` with PhpUnit 10
    fabpot committed May 17, 2024
    Copy the full SHA
    64b6202 View commit details

Commits on May 31, 2024

  1. Revert "minor #54653 Auto-close PRs on subtree-splits (nicolas-grekas)"

    This reverts commit 2c9352dd91ebaf37b8a3e3c26fd8e1306df2fb73, reversing
    changes made to 18c3e87f1512be2cc50e90235b144b13bc347258.
    fabpot committed May 31, 2024
    Copy the full SHA
    deedcb3 View commit details
  2. Merge branch '5.4' into 6.4

    * 5.4:
      Revert "minor #54653 Auto-close PRs on subtree-splits (nicolas-grekas)"
    fabpot committed May 31, 2024
    Copy the full SHA
    8d92dd7 View commit details

Commits on Sep 5, 2024

  1. Copy the full SHA
    32354f6 View commit details

Commits on Sep 8, 2024

  1. Merge branch '5.4' into 6.4

    * 5.4:
      Mitigate PHPUnit deprecations
      [TwigBundle] Add support for resetting globals between HTTP requests
      [Validator] Add Catalan and Spanish translation for `Week` constraint
      Don't use is_resource() on non-streams
      [Ldap] Fix extension deprecation
    derrabus committed Sep 8, 2024
    Copy the full SHA
    8c567a2 View commit details

Commits on Sep 11, 2024

  1. Copy the full SHA
    6fd79ab View commit details

Commits on Sep 17, 2024

  1. Copy the full SHA
    6f16c62 View commit details
  2. [Process] minor fix

    nicolas-grekas committed Sep 17, 2024
    Copy the full SHA
    1b9fa82 View commit details
  3. Merge branch '5.4' into 6.4

    * 5.4:
      [Process] minor fix
      [Process] Fix finding executables independently of open_basedir
      [HttpKernel] Skip logging uncaught exceptions in ErrorHandler, assume $kernel->terminateWithException() will do it
      parse empty sequence elements as null
    nicolas-grekas committed Sep 17, 2024
    Copy the full SHA
    3f94e5f View commit details

Commits on Sep 25, 2024

  1. Copy the full SHA
    95f3f19 View commit details
  2. Merge branch '5.4' into 6.4

    * 5.4:
      Add PR template and auto-close PR on subtree split repositories
    nicolas-grekas committed Sep 25, 2024
    Copy the full SHA
    1f9f59b View commit details

Commits on Oct 30, 2024

  1. Copy the full SHA
    e2d11b6 View commit details

Commits on Oct 31, 2024

  1. Copy the full SHA
    651830b View commit details
  2. bug #58723 [Process] Properly deal with not-found executables on Wind…

    …ows (nicolas-grekas)
    
    This PR was merged into the 5.4 branch.
    
    Discussion
    ----------
    
    [Process] Properly deal with not-found executables on Windows
    
    | Q             | A
    | ------------- | ---
    | Branch?       | 5.4
    | Bug fix?      | yes
    | New feature?  | no
    | Deprecations? | no
    | Issues        | -
    | License       | MIT
    
    Removing the unexpected notices that we see on appveyor:
    
    Before:
    ![image](https://github.com/user-attachments/assets/d9c788ad-7b29-4b0c-9170-aa08953a5ca2)
    
    After:
    ![image](https://github.com/user-attachments/assets/a3dc1cc7-ce4c-4fd0-b422-1a6c745bc3d9)
    
    Commits
    -------
    
    73140eb44e1 [Process] Properly deal with not-found executables on Windows
    nicolas-grekas committed Oct 31, 2024
    Copy the full SHA
    32dfba3 View commit details
  3. 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
    nicolas-grekas committed Oct 31, 2024
    Copy the full SHA
    593ecb8 View commit details

Commits on Nov 2, 2024

  1. Copy the full SHA
    46c203f View commit details

Commits on Nov 4, 2024

  1. Copy the full SHA
    b61fb1c View commit details
  2. Copy the full SHA
    a56fe7b View commit details
  3. Copy the full SHA
    7be8366 View commit details
  4. minor #58746 [Process] Improve test cleanup by unlinking in a `finall…

    …y` block (alexandre-daubois)
    
    This PR was merged into the 5.4 branch.
    
    Discussion
    ----------
    
    [Process] Improve test cleanup by unlinking in a `finally` block
    
    | Q             | A
    | ------------- | ---
    | Branch?       | 5.4
    | Bug fix?      | no
    | New feature?  | no
    | Deprecations? | no
    | Issues        | -
    | License       | MIT
    
    Follwup for #58711, I realized afterwards that we may unlink in `finally` block to ensure proper test clean up in case something goes wrong.
    
    Commits
    -------
    
    5c547c958b9 [Process] Improve test cleanup by unlinking in a `finally` block
    nicolas-grekas committed Nov 4, 2024
    Copy the full SHA
    5cdd400 View commit details
  5. minor #58747 [Process] fix the directory separator being used (xabbuh)

    This PR was merged into the 5.4 branch.
    
    Discussion
    ----------
    
    [Process] fix the directory separator being used
    
    | Q             | A
    | ------------- | ---
    | Branch?       | 5.4
    | Bug fix?      | no
    | New feature?  | no
    | Deprecations? | no
    | Issues        |
    | License       | MIT
    
    Commits
    -------
    
    2526495eb75 fix the directory separator being used
    nicolas-grekas committed Nov 4, 2024
    Copy the full SHA
    d67303e View commit details
  6. 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
    xabbuh committed Nov 4, 2024
    Copy the full SHA
    250ae06 View commit details
  7. Copy the full SHA
    81e1a0c View commit details
  8. fix the constant being used

    xabbuh committed Nov 4, 2024
    Copy the full SHA
    72baf6b View commit details
  9. Merge branch '5.4' into 6.4

    * 5.4:
      fix the constant being used
      fix the path separator being used
    xabbuh committed Nov 4, 2024
    Copy the full SHA
    836d34f View commit details
  10. Copy the full SHA
    d94dda5 View commit details
  11. Merge branch '5.4' into 6.4

    * 5.4:
      [Validator] Fix 58691 (missing plural-options in serbian language translation)
      profiler form data collector extart value property if it is setted
      [Process] Fix escaping /X arguments on Windows
      [Config] Handle Phar absolute path in `FileLocator`
    nicolas-grekas committed Nov 4, 2024
    Copy the full SHA
    0776b99 View commit details
  12. Copy the full SHA
    05c2ccc View commit details

Commits on Nov 5, 2024

  1. security #cve-2024-51736 [Process] Use %PATH% before %CD% to load the…

    … shell on Windows (nicolas-grekas)
    
    This PR was merged into the 5.4 branch.
    nicolas-grekas committed Nov 5, 2024
    Copy the full SHA
    ee75984 View commit details
  2. Merge branch '5.4' into 6.4

    * 5.4:
      Do not read from argv on non-CLI SAPIs
      [Process] Use %PATH% before %CD% to load the shell on Windows
      [HttpFoundation] Reject URIs that contain invalid characters
      [HttpClient] Filter private IPs before connecting when Host == IP
    nicolas-grekas committed Nov 5, 2024
    Copy the full SHA
    88638b9 View commit details

Commits on Nov 6, 2024

  1. [Process] Fix test

    nicolas-grekas committed Nov 6, 2024
    Copy the full SHA
    0190687 View commit details
  2. Merge branch '5.4' into 6.4

    * 5.4:
      [Process] Fix test
    nicolas-grekas committed Nov 6, 2024
    Copy the full SHA
    25214ad View commit details
Showing with 125 additions and 73 deletions.
  1. +0 −37 .github/workflows/check-subtree-split.yml
  2. +20 −0 .github/workflows/close-pull-request.yml
  3. +0 −1 CHANGELOG.md
  4. +28 −5 ExecutableFinder.php
  5. +2 −9 PhpExecutableFinder.php
  6. +1 −1 PhpSubprocess.php
  7. +13 −5 Process.php
  8. +55 −14 Tests/ExecutableFinderTest.php
  9. +6 −1 Tests/ProcessTest.php
37 changes: 0 additions & 37 deletions .github/workflows/check-subtree-split.yml

This file was deleted.

20 changes: 20 additions & 0 deletions .github/workflows/close-pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Close Pull Request

on:
pull_request_target:
types: [opened]

jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Thanks for your Pull Request! We love contributions.
However, you should instead open your PR on the main repository:
https://github.com/symfony/symfony
This repository is what we call a "subtree split": a read-only subset of that main repository.
We're looking forward to your PR there!
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@ CHANGELOG
* Add `PhpSubprocess` to handle PHP subprocesses that take over the
configuration from their parent
* Add `RunProcessMessage` and `RunProcessMessageHandler`
* Support using `Process::findExecutable()` independently of `open_basedir`

5.2.0
-----
33 changes: 28 additions & 5 deletions ExecutableFinder.php
Original file line number Diff line number Diff line change
@@ -19,7 +19,15 @@
*/
class ExecutableFinder
{
private array $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',
];

private array $suffixes = [];

/**
* Replaces default suffixes of executable.
@@ -50,18 +58,28 @@ public function addSuffix(string $suffix)
*/
public function find(string $name, ?string $default = null, array $extraDirs = []): ?string
{
// 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
);

$suffixes = [''];
$suffixes = [];
if ('\\' === \DIRECTORY_SEPARATOR) {
$pathExt = getenv('PATHEXT');
$suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
$suffixes = $this->suffixes;
$suffixes = array_merge($suffixes, $pathExt ? explode(\PATH_SEPARATOR, $pathExt) : ['.exe', '.bat', '.cmd', '.com']);
}
$suffixes = '' !== pathinfo($name, PATHINFO_EXTENSION) ? array_merge([''], $suffixes) : array_merge($suffixes, ['']);
foreach ($suffixes as $suffix) {
foreach ($dirs as $dir) {
if ('' === $dir) {
$dir = '.';
}
if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
return $file;
}
@@ -72,8 +90,13 @@ public function find(string $name, ?string $default = null, array $extraDirs = [
}
}

$command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --';
if (\function_exists('exec') && ($executablePath = strtok(@exec($command.' '.escapeshellarg($name)), \PHP_EOL)) && @is_executable($executablePath)) {
if ('\\' === \DIRECTORY_SEPARATOR || !\function_exists('exec') || \strlen($name) !== strcspn($name, '/'.\DIRECTORY_SEPARATOR)) {
return $default;
}

$execResult = exec('command -v -- '.escapeshellarg($name));

if (($executablePath = substr($execResult, 0, strpos($execResult, \PHP_EOL) ?: null)) && @is_executable($executablePath)) {
return $executablePath;
}

11 changes: 2 additions & 9 deletions PhpExecutableFinder.php
Original file line number Diff line number Diff line change
@@ -32,15 +32,8 @@ public function __construct()
public function find(bool $includeArgs = true): string|false
{
if ($php = getenv('PHP_BINARY')) {
if (!is_executable($php)) {
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --';
if (\function_exists('exec') && $php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) {
if (!is_executable($php)) {
return false;
}
} else {
return false;
}
if (!is_executable($php) && !$php = $this->executableFinder->find($php)) {
return false;
}

if (@is_dir($php)) {
2 changes: 1 addition & 1 deletion PhpSubprocess.php
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ private function writeTmpIni(array $iniFiles, string $tmpDir): string
throw new RuntimeException('Unable to read ini: '.$file);
}
// Check and remove directives after HOST and PATH sections
if (preg_match('/^\s*\[(?:PATH|HOST)\s*=/mi', $data, $matches)) {
if (preg_match('/^\s*\[(?:PATH|HOST)\s*=/mi', $data, $matches, \PREG_OFFSET_CAPTURE)) {
$data = substr($data, 0, $matches[0][1]);
}

18 changes: 13 additions & 5 deletions Process.php
Original file line number Diff line number Diff line change
@@ -346,7 +346,7 @@ public function start(?callable $callback = null, array $env = [])

$process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options);

if (!\is_resource($process)) {
if (!$process) {
throw new RuntimeException('Unable to launch a new process.');
}
$this->process = $process;
@@ -1211,7 +1211,7 @@ public static function isTtySupported(): bool
{
static $isTtySupported;

return $isTtySupported ??= ('/' === \DIRECTORY_SEPARATOR && stream_isatty(\STDOUT));
return $isTtySupported ??= ('/' === \DIRECTORY_SEPARATOR && stream_isatty(\STDOUT) && @is_writable('/dev/tty'));
}

/**
@@ -1400,8 +1400,9 @@ private function readPipes(bool $blocking, bool $close): void
private function close(): int
{
$this->processPipes->close();
if (\is_resource($this->process)) {
if ($this->process) {
proc_close($this->process);
$this->process = null;
}
$this->exitcode = $this->processInformation['exitcode'];
$this->status = self::STATUS_TERMINATED;
@@ -1535,7 +1536,14 @@ function ($m) use (&$env, $uid) {
$cmd
);

$cmd = 'cmd /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')';
static $comSpec;

if (!$comSpec && $comSpec = (new ExecutableFinder())->find('cmd.exe')) {
// Escape according to CommandLineToArgvW rules
$comSpec = '"'.preg_replace('{(\\\\*+)"}', '$1$1\"', $comSpec) .'"';
}

$cmd = ($comSpec ?? 'cmd').' /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')';
foreach ($this->processPipes->getFiles() as $offset => $filename) {
$cmd .= ' '.$offset.'>"'.$filename.'"';
}
@@ -1581,7 +1589,7 @@ private function escapeArgument(?string $argument): string
if (str_contains($argument, "\0")) {
$argument = str_replace("\0", '?', $argument);
}
if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) {
if (!preg_match('/[()%!^"<>&|\s]/', $argument)) {
return $argument;
}
$argument = preg_replace('/(\\\\+)$/', '$1$1', $argument);
69 changes: 55 additions & 14 deletions Tests/ExecutableFinderTest.php
Original file line number Diff line number Diff line change
@@ -99,14 +99,21 @@ public function testFindWithOpenBaseDir()
}

putenv('PATH='.\dirname(\PHP_BINARY));
$this->iniSet('open_basedir', \dirname(\PHP_BINARY).\PATH_SEPARATOR.'/');
$initialOpenBaseDir = ini_set('open_basedir', \dirname(\PHP_BINARY).\PATH_SEPARATOR.'/');

$finder = new ExecutableFinder();
$result = $finder->find($this->getPhpBinaryName());
try {
$finder = new ExecutableFinder();
$result = $finder->find($this->getPhpBinaryName());

$this->assertSamePath(\PHP_BINARY, $result);
$this->assertSamePath(\PHP_BINARY, $result);
} finally {
ini_set('open_basedir', $initialOpenBaseDir);
}
}

/**
* @runInSeparateProcess
*/
public function testFindBatchExecutableOnWindows()
{
if (\ini_get('open_basedir')) {
@@ -116,24 +123,58 @@ public function testFindBatchExecutableOnWindows()
$this->markTestSkipped('Can be only tested on windows');
}

$target = tempnam(sys_get_temp_dir(), 'example-windows-executable');
$target = str_replace('.tmp', '_tmp', tempnam(sys_get_temp_dir(), 'example-windows-executable'));

touch($target);
touch($target.'.BAT');
try {
touch($target);
touch($target.'.BAT');

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

putenv('PATH='.sys_get_temp_dir());
putenv('PATH='.sys_get_temp_dir());

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

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);
}

/**
* @runInSeparateProcess
*/
public function testEmptyDirInPath()
{
putenv(sprintf('PATH=%s%s', \dirname(\PHP_BINARY), \PATH_SEPARATOR));

try {
touch('executable');
chmod('executable', 0700);

$finder = new ExecutableFinder();
$result = $finder->find('executable');

$this->assertSame(sprintf('.%sexecutable', \DIRECTORY_SEPARATOR), $result);
} finally {
unlink('executable');
}
}

public function testFindBuiltInCommandOnWindows()
{
if ('\\' !== \DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Can be only tested on windows');
}

$finder = new ExecutableFinder();
$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)
{
if ('\\' === \DIRECTORY_SEPARATOR) {
7 changes: 6 additions & 1 deletion Tests/ProcessTest.php
Original file line number Diff line number Diff line change
@@ -1436,7 +1436,12 @@ public function testGetCommandLine()
{
$p = new Process(['/usr/bin/php']);

$expected = '\\' === \DIRECTORY_SEPARATOR ? '"/usr/bin/php"' : "'/usr/bin/php'";
$expected = '\\' === \DIRECTORY_SEPARATOR ? '/usr/bin/php' : "'/usr/bin/php'";
$this->assertSame($expected, $p->getCommandLine());

$p = new Process(['cd', '/d']);

$expected = '\\' === \DIRECTORY_SEPARATOR ? 'cd /d' : "'cd' '/d'";
$this->assertSame($expected, $p->getCommandLine());
}