diff -Nru composer-2.8.8/debian/changelog composer-2.8.8/debian/changelog
--- composer-2.8.8/debian/changelog	2025-12-30 16:35:23.000000000 +0100
+++ composer-2.8.8/debian/changelog	2026-04-15 10:50:08.000000000 +0200
@@ -1,3 +1,12 @@
+composer (2.8.8-1+deb13u2) trixie; urgency=medium
+
+  * Fix command injection via malicious Perforce repository definition
+    [CVE-2026-40261]
+  * Fix command injection via malicious Perforce source reference/url
+    [CVE-2026-40176]
+
+ -- David Prévot <taffit@debian.org>  Wed, 15 Apr 2026 10:50:08 +0200
+
 composer (2.8.8-1+deb13u1) trixie; urgency=medium
 
   * Backport fix from composer 2.9.3:
diff -Nru composer-2.8.8/debian/patches/0018-Merge-commit-from-fork.patch composer-2.8.8/debian/patches/0018-Merge-commit-from-fork.patch
--- composer-2.8.8/debian/patches/0018-Merge-commit-from-fork.patch	1970-01-01 01:00:00.000000000 +0100
+++ composer-2.8.8/debian/patches/0018-Merge-commit-from-fork.patch	2026-04-15 10:50:08.000000000 +0200
@@ -0,0 +1,47 @@
+From: Jordi Boggiano <j.boggiano@seld.be>
+Date: Tue, 14 Apr 2026 10:34:08 +0200
+Subject: Merge commit from fork
+
+Origin: upstream, https://github.com/composer/composer/commit/91f077050c13e49e22554b991c81378ce8b5ee16
+Bug: https://github.com/composer/composer/security/advisories/GHSA-gqw4-4w2p-838q
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2026-40261
+---
+ src/Composer/Util/Perforce.php            | 2 +-
+ tests/Composer/Test/Util/PerforceTest.php | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/Composer/Util/Perforce.php b/src/Composer/Util/Perforce.php
+index bfed834..3b6ff9f 100644
+--- a/src/Composer/Util/Perforce.php
++++ b/src/Composer/Util/Perforce.php
+@@ -354,7 +354,7 @@ class Perforce
+         chdir($this->path);
+         $p4SyncCommand = $this->generateP4Command('sync -f ');
+         if (null !== $sourceReference) {
+-            $p4SyncCommand .= '@' . $sourceReference;
++            $p4SyncCommand .= ProcessExecutor::escape('@' . $sourceReference);
+         }
+         $this->executeCommand($p4SyncCommand);
+         chdir($prevDir);
+diff --git a/tests/Composer/Test/Util/PerforceTest.php b/tests/Composer/Test/Util/PerforceTest.php
+index 99a908c..53e3b31 100644
+--- a/tests/Composer/Test/Util/PerforceTest.php
++++ b/tests/Composer/Test/Util/PerforceTest.php
+@@ -539,7 +539,7 @@ class PerforceTest extends TestCase
+     public function testSyncCodeBaseWithoutStream(): void
+     {
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot -p port sync -f @label'],
++            ['p4 -u user -c composer_perforce_TEST_depot -p port sync -f \'@label\''],
+             true
+         );
+ 
+@@ -551,7 +551,7 @@ class PerforceTest extends TestCase
+         $this->setPerforceToStream();
+ 
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot_branch -p port sync -f @label'],
++            ['p4 -u user -c composer_perforce_TEST_depot_branch -p port sync -f \'@label\''],
+             true
+         );
+ 
diff -Nru composer-2.8.8/debian/patches/0019-Merge-commit-from-fork.patch composer-2.8.8/debian/patches/0019-Merge-commit-from-fork.patch
--- composer-2.8.8/debian/patches/0019-Merge-commit-from-fork.patch	1970-01-01 01:00:00.000000000 +0100
+++ composer-2.8.8/debian/patches/0019-Merge-commit-from-fork.patch	2026-04-15 10:50:08.000000000 +0200
@@ -0,0 +1,236 @@
+From: Jordi Boggiano <j.boggiano@seld.be>
+Date: Tue, 14 Apr 2026 10:41:57 +0200
+Subject: Merge commit from fork
+
+Co-authored-by: Stephan Vock <stephan.vock@gmail.com>
+
+Origin: upstream, https://github.com/composer/composer/commit/4f02616e6fba3b1baf8d45725f847841b44fc15c
+Bug: https://github.com/composer/composer/security/advisories/GHSA-wg36-wvj6-r67p
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2026-40176
+---
+ src/Composer/Util/Perforce.php            |  6 +--
+ tests/Composer/Test/Util/PerforceTest.php | 82 ++++++++++++++++++++++++-------
+ 2 files changed, 67 insertions(+), 21 deletions(-)
+
+diff --git a/src/Composer/Util/Perforce.php b/src/Composer/Util/Perforce.php
+index 3b6ff9f..331daf3 100644
+--- a/src/Composer/Util/Perforce.php
++++ b/src/Composer/Util/Perforce.php
+@@ -311,11 +311,11 @@ class Perforce
+     public function generateP4Command(string $command, bool $useClient = true): string
+     {
+         $p4Command = $this->getP4Executable().' ';
+-        $p4Command .= '-u ' . $this->getUser() . ' ';
++        $p4Command .= '-u ' . ProcessExecutor::escape($this->getUser()) . ' ';
+         if ($useClient) {
+-            $p4Command .= '-c ' . $this->getClient() . ' ';
++            $p4Command .= '-c ' . ProcessExecutor::escape($this->getClient()) . ' ';
+         }
+-        $p4Command .= '-p ' . $this->getPort() . ' ' . $command;
++        $p4Command .= '-p ' . ProcessExecutor::escape($this->getPort()) . ' ' . $command;
+ 
+         return $p4Command;
+     }
+diff --git a/tests/Composer/Test/Util/PerforceTest.php b/tests/Composer/Test/Util/PerforceTest.php
+index 53e3b31..752079c 100644
+--- a/tests/Composer/Test/Util/PerforceTest.php
++++ b/tests/Composer/Test/Util/PerforceTest.php
+@@ -128,10 +128,56 @@ class PerforceTest extends TestCase
+     {
+         $command = 'do something';
+         $p4Command = $this->perforce->generateP4Command($command);
+-        $expected = 'p4 -u user -c composer_perforce_TEST_depot -p port do something';
++        $expected = "p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port' do something";
+         self::assertEquals($expected, $p4Command);
+     }
+ 
++    public function testGenerateP4CommandEscapesPortInjection(): void
++    {
++        $perforce = new Perforce(
++            ['depot' => 'depot', 'branch' => 'branch', 'p4user' => 'user', 'unique_perforce_client_name' => 'TEST'],
++            'localhost:1666; touch /tmp/pwned',
++            'path',
++            $this->processExecutor,
++            false,
++            $this->io
++        );
++        $command = $perforce->generateP4Command('login -s', false);
++        self::assertStringNotContainsString('-p localhost:1666; touch /tmp/pwned', $command);
++        self::assertStringContainsString('-p '.ProcessExecutor::escape('localhost:1666; touch /tmp/pwned'), $command);
++    }
++
++    public function testGenerateP4CommandEscapesUserInjection(): void
++    {
++        $perforce = new Perforce(
++            ['depot' => 'depot', 'branch' => 'branch', 'p4user' => 'user; id', 'unique_perforce_client_name' => 'TEST'],
++            'port',
++            'path',
++            $this->processExecutor,
++            false,
++            $this->io
++        );
++        $command = $perforce->generateP4Command('login -s', false);
++        self::assertStringNotContainsString('-u user; id', $command);
++        self::assertStringContainsString('-u '.ProcessExecutor::escape('user; id'), $command);
++    }
++
++    public function testGenerateP4CommandEscapesClientInjection(): void
++    {
++        $perforce = new Perforce(
++            ['depot' => 'foo; id #', 'branch' => 'branch', 'p4user' => 'user', 'unique_perforce_client_name' => 'TEST'],
++            'port',
++            'path',
++            $this->processExecutor,
++            false,
++            $this->io
++        );
++        $command = $perforce->generateP4Command('do something');
++        $expectedClient = 'composer_perforce_TEST_foo; id #';
++        self::assertStringNotContainsString('-c '.$expectedClient.' ', $command);
++        self::assertStringContainsString('-c '.ProcessExecutor::escape($expectedClient), $command);
++    }
++
+     public function testQueryP4UserWithUserAlreadySet(): void
+     {
+         $this->perforce->queryP4user();
+@@ -319,7 +365,7 @@ class PerforceTest extends TestCase
+     public function testIsLoggedIn(): void
+     {
+         $this->processExecutor->expects(
+-            [['cmd' => 'p4 -u user -p port login -s']],
++            [['cmd' => "p4 -u 'user' -p 'port' login -s"]],
+             true
+         );
+         $this->perforce->isLoggedIn();
+@@ -328,7 +374,7 @@ class PerforceTest extends TestCase
+     public function testConnectClient(): void
+     {
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot -p port client -i < '.ProcessExecutor::escape('path/composer_perforce_TEST_depot.p4.spec')],
++            ["p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port' client -i < ".ProcessExecutor::escape('path/composer_perforce_TEST_depot.p4.spec')],
+             true
+         );
+ 
+@@ -342,11 +388,11 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot_branch -p port streams '.ProcessExecutor::escape('//depot/...'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port' streams ".ProcessExecutor::escape('//depot/...'),
+                     'stdout' => 'Stream //depot/branch mainline none \'branch\'' . PHP_EOL,
+                 ],
+                 [
+-                    'cmd' => 'p4 -u user -p port changes '.ProcessExecutor::escape('//depot/branch/...'),
++                    'cmd' => "p4 -u 'user' -p 'port' changes ".ProcessExecutor::escape('//depot/branch/...'),
+                     'stdout' => 'Change 1234 on 2014/03/19 by Clark.Stuth@Clark.Stuth_test_client \'test changelist\'',
+                 ],
+             ],
+@@ -362,7 +408,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -p port changes '.ProcessExecutor::escape('//depot/...'),
++                    'cmd' => "p4 -u 'user' -p 'port' changes ".ProcessExecutor::escape('//depot/...'),
+                     'stdout' => 'Change 5678 on 2014/03/19 by Clark.Stuth@Clark.Stuth_test_client \'test changelist\'',
+                 ],
+             ],
+@@ -378,7 +424,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot -p port labels',
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port' labels",
+                     'stdout' => 'Label 0.0.1 2013/07/31 \'First Label!\'' . PHP_EOL . 'Label 0.0.2 2013/08/01 \'Second Label!\'' . PHP_EOL,
+                 ],
+             ],
+@@ -397,7 +443,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot_branch -p port labels',
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port' labels",
+                     'stdout' => 'Label 0.0.1 2013/07/31 \'First Label!\'' . PHP_EOL . 'Label 0.0.2 2013/08/01 \'Second Label!\'' . PHP_EOL,
+                 ],
+             ],
+@@ -421,7 +467,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -p port depots',
++                    'cmd' => "p4 -u 'user' -p 'port' depots",
+                     'stdout' => 'Depot depot 2013/06/25 stream /p4/1/depots/depot/... \'Created by Me\'',
+                 ],
+             ],
+@@ -438,7 +484,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot -p port  print '.ProcessExecutor::escape('//depot/composer.json'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port'  print ".ProcessExecutor::escape('//depot/composer.json'),
+                     'stdout' => PerforceTest::getComposerJson(),
+                 ],
+             ],
+@@ -460,11 +506,11 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -p port  files '.ProcessExecutor::escape('//depot/composer.json@0.0.1'),
++                    'cmd' => "p4 -u 'user' -p 'port'  files ".ProcessExecutor::escape('//depot/composer.json@0.0.1'),
+                     'stdout' => '//depot/composer.json#1 - branch change 10001 (text)',
+                 ],
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot -p port  print '.ProcessExecutor::escape('//depot/composer.json@10001'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port'  print ".ProcessExecutor::escape('//depot/composer.json@10001'),
+                     'stdout' => PerforceTest::getComposerJson(),
+                 ],
+             ],
+@@ -489,7 +535,7 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot_branch -p port  print '.ProcessExecutor::escape('//depot/branch/composer.json'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port'  print ".ProcessExecutor::escape('//depot/branch/composer.json'),
+                     'stdout' => PerforceTest::getComposerJson(),
+                 ],
+             ],
+@@ -512,11 +558,11 @@ class PerforceTest extends TestCase
+         $this->processExecutor->expects(
+             [
+                 [
+-                    'cmd' => 'p4 -u user -p port  files '.ProcessExecutor::escape('//depot/branch/composer.json@0.0.1'),
++                    'cmd' => "p4 -u 'user' -p 'port'  files ".ProcessExecutor::escape('//depot/branch/composer.json@0.0.1'),
+                     'stdout' => '//depot/composer.json#1 - branch change 10001 (text)',
+                 ],
+                 [
+-                    'cmd' => 'p4 -u user -c composer_perforce_TEST_depot_branch -p port  print '.ProcessExecutor::escape('//depot/branch/composer.json@10001'),
++                    'cmd' => "p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port'  print ".ProcessExecutor::escape('//depot/branch/composer.json@10001'),
+                     'stdout' => PerforceTest::getComposerJson(),
+                 ],
+             ],
+@@ -539,7 +585,7 @@ class PerforceTest extends TestCase
+     public function testSyncCodeBaseWithoutStream(): void
+     {
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot -p port sync -f \'@label\''],
++            ["p4 -u 'user' -c 'composer_perforce_TEST_depot' -p 'port' sync -f '@label'"],
+             true
+         );
+ 
+@@ -551,7 +597,7 @@ class PerforceTest extends TestCase
+         $this->setPerforceToStream();
+ 
+         $this->processExecutor->expects(
+-            ['p4 -u user -c composer_perforce_TEST_depot_branch -p port sync -f \'@label\''],
++            ["p4 -u 'user' -c 'composer_perforce_TEST_depot_branch' -p 'port' sync -f '@label'"],
+             true
+         );
+ 
+@@ -649,7 +695,7 @@ class PerforceTest extends TestCase
+ 
+         $testClient = $this->perforce->getClient();
+         $this->processExecutor->expects(
+-            ['p4 -u ' . self::TEST_P4USER . ' -p ' . self::TEST_PORT . ' client -d ' . ProcessExecutor::escape($testClient)],
++            ["p4 -u '" . self::TEST_P4USER . "' -p '" . self::TEST_PORT . "' client -d " . ProcessExecutor::escape($testClient)],
+             true
+         );
+ 
diff -Nru composer-2.8.8/debian/patches/series composer-2.8.8/debian/patches/series
--- composer-2.8.8/debian/patches/series	2025-12-30 16:33:32.000000000 +0100
+++ composer-2.8.8/debian/patches/series	2026-04-15 10:50:08.000000000 +0200
@@ -15,3 +15,5 @@
 0015-Revert-Fix-regression-from-12233-in-InstalledVersion.patch
 0016-Modernize-PHPUnit-syntax.patch
 0017-Merge-commit-from-fork.patch
+0018-Merge-commit-from-fork.patch
+0019-Merge-commit-from-fork.patch
