Skip to content

Commit 3141742

Browse files
Do not run PHPT test when its temporary file for code coverage information exists
1 parent 0b3170a commit 3141742

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

ChangeLog-8.5.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes of the PHPUnit 8.5 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
44

5+
## [8.5.52] - 2026-MM-DD
6+
7+
### Changed
8+
9+
* To prevent Poisoned Pipeline Execution (PPE) attacks using prepared `.coverage` files in pull requests, a PHPT test will no longer be run if the temporary file for writing code coverage information already exists before the test runs
10+
511
## [8.5.51] - 2026-01-24
612

713
### Changed
@@ -374,6 +380,7 @@ All notable changes of the PHPUnit 8.5 release series are documented in this fil
374380
* [#3967](https://github.com/sebastianbergmann/phpunit/issues/3967): Cannot double interface that extends interface that extends `\Throwable`
375381
* [#3968](https://github.com/sebastianbergmann/phpunit/pull/3968): Test class run in a separate PHP process are passing when `exit` called inside
376382

383+
[8.5.52]: https://github.com/sebastianbergmann/phpunit/compare/8.5.51...8.5
377384
[8.5.51]: https://github.com/sebastianbergmann/phpunit/compare/8.5.50...8.5.51
378385
[8.5.50]: https://github.com/sebastianbergmann/phpunit/compare/8.5.49...8.5.50
379386
[8.5.49]: https://github.com/sebastianbergmann/phpunit/compare/8.5.48...8.5.49

src/Runner/PhptTestCase.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,10 @@ public function __construct(string $filename, ?AbstractPhpProcess $phpUtil = nul
9393
$this->ensureFileExists($filename);
9494

9595
$this->filename = $filename;
96-
$this->phpUtil = $phpUtil ?: AbstractPhpProcess::factory();
96+
97+
$this->ensureCoverageFileDoesNotExist();
98+
99+
$this->phpUtil = $phpUtil ?: AbstractPhpProcess::factory();
97100
}
98101

99102
/**
@@ -829,4 +832,22 @@ private function ensureFileExists(string $filename): void
829832
);
830833
}
831834
}
835+
836+
/**
837+
* @throws Exception
838+
*/
839+
private function ensureCoverageFileDoesNotExist(): void
840+
{
841+
$files = $this->getCoverageFiles();
842+
843+
if (file_exists($files['coverage'])) {
844+
throw new Exception(
845+
sprintf(
846+
'File %s exists, PHPT test %s will not be executed',
847+
$files['coverage'],
848+
$this->filename
849+
)
850+
);
851+
}
852+
}
832853
}

tests/end-to-end/_files/phpt-coverage-file-exists/test.coverage

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--TEST--
2+
test
3+
--FILE--
4+
<?php declare(strict_types=1);
5+
print 'test';
6+
--EXPECT--
7+
test
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Error when code coverage file exists
3+
--FILE--
4+
<?php declare(strict_types=1);
5+
$_SERVER['argv'][] = '--do-not-cache-result';
6+
$_SERVER['argv'][] = '--no-configuration';
7+
$_SERVER['argv'][] = \realpath(__DIR__ . '/../_files/phpt-coverage-file-exists/test.phpt');
8+
9+
require_once __DIR__ . '/../../bootstrap.php';
10+
11+
PHPUnit\TextUI\Command::main();
12+
--EXPECTF--
13+
Fatal error: Uncaught PHPUnit\Runner\Exception: File %stest.coverage exists, PHPT test %stest.phpt will not be executed%A

0 commit comments

Comments
 (0)