Skip to content

Commit 962f152

Browse files
Merge branch '11.5' into 12.5
* 11.5: Do not run PHPT test when its temporary file for code coverage information exists We do not need to unserialize() objects here Extract method Fix CS/WS issue
2 parents 79dee3d + 72c74a0 commit 962f152

File tree

6 files changed

+79
-1
lines changed

6 files changed

+79
-1
lines changed

ChangeLog-12.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 12.5 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
44

5+
## [12.5.8] - 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
## [12.5.7] - 2026-01-24
612

713
### Fixed
@@ -69,6 +75,7 @@ All notable changes of the PHPUnit 12.5 release series are documented in this fi
6975
* [#6380](https://github.com/sebastianbergmann/phpunit/pull/6380): Allow `Throwable` in `expectExceptionObject()`
7076
* A PHPUnit notice is now emitted for test methods that create a mock object but do not configure an expectation for it
7177

78+
[12.5.8]: https://github.com/sebastianbergmann/phpunit/compare/12.5.7...12.5
7279
[12.5.7]: https://github.com/sebastianbergmann/phpunit/compare/12.5.6...12.5.7
7380
[12.5.6]: https://github.com/sebastianbergmann/phpunit/compare/12.5.5...12.5.6
7481
[12.5.5]: https://github.com/sebastianbergmann/phpunit/compare/12.5.4...12.5.5
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Runner;
11+
12+
use RuntimeException;
13+
14+
/**
15+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
16+
*
17+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
18+
*/
19+
final class CodeCoverageFileExistsException extends RuntimeException implements Exception
20+
{
21+
}

src/Runner/Phpt/TestCase.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use function dirname;
1818
use function explode;
1919
use function extension_loaded;
20+
use function file_exists;
2021
use function file_get_contents;
2122
use function is_array;
2223
use function is_file;
@@ -49,6 +50,7 @@
4950
use PHPUnit\Framework\SelfDescribing;
5051
use PHPUnit\Framework\Test;
5152
use PHPUnit\Runner\CodeCoverage;
53+
use PHPUnit\Runner\CodeCoverageFileExistsException;
5254
use PHPUnit\Runner\Exception;
5355
use PHPUnit\Util\PHP\Job;
5456
use PHPUnit\Util\PHP\JobRunnerRegistry;
@@ -83,6 +85,8 @@
8385
public function __construct(string $filename)
8486
{
8587
$this->filename = $filename;
88+
89+
$this->ensureCoverageFileDoesNotExist();
8690
}
8791

8892
public function count(): int
@@ -467,7 +471,7 @@ private function cleanupForCoverage(): RawCodeCoverageData
467471
}
468472

469473
if ($buffer !== false) {
470-
$coverage = @unserialize($buffer);
474+
$coverage = @unserialize($buffer, ['allowed_classes' => false]);
471475

472476
if ($coverage === false) {
473477
/**
@@ -706,4 +710,22 @@ private function triggerRunnerWarningOnPhpErrors(string $section, string $output
706710
);
707711
}
708712
}
713+
714+
/**
715+
* @throws CodeCoverageFileExistsException
716+
*/
717+
private function ensureCoverageFileDoesNotExist(): void
718+
{
719+
$files = $this->coverageFiles();
720+
721+
if (file_exists($files['coverage'])) {
722+
throw new CodeCoverageFileExistsException(
723+
sprintf(
724+
'File %s exists, PHPT test %s will not be executed',
725+
$files['coverage'],
726+
$this->filename,
727+
),
728+
);
729+
}
730+
}
709731
}

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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
12+
--EXPECTF--
13+
PHPUnit %s by Sebastian Bergmann and contributors.
14+
15+
Runtime: %s
16+
17+
There was 1 PHPUnit test runner warning:
18+
19+
1) File %stest.coverage exists, PHPT test %stest.phpt will not be executed
20+
21+
No tests executed!

0 commit comments

Comments
 (0)