Skip to content

Commit 67500b7

Browse files
Escape tag in githubErrorFormatter (#4198)
1 parent cabe851 commit 67500b7

File tree

5 files changed

+33
-15
lines changed

5 files changed

+33
-15
lines changed

src/Command/ErrorFormatter/GithubErrorFormatter.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPStan\File\RelativePathHelper;
1010
use function array_walk;
1111
use function implode;
12+
use function preg_replace;
1213
use function sprintf;
1314
use function str_replace;
1415

@@ -40,9 +41,7 @@ public function formatErrors(AnalysisResult $analysisResult, Output $output): in
4041
});
4142

4243
$message = $fileSpecificError->getMessage();
43-
// newlines need to be encoded
44-
// see https://github.com/actions/starter-workflows/issues/68#issuecomment-581479448
45-
$message = str_replace("\n", '%0A', $message);
44+
$message = $this->formatMessage($message);
4645

4746
$line = sprintf('::error %s::%s', implode(',', $metas), $message);
4847

@@ -51,9 +50,7 @@ public function formatErrors(AnalysisResult $analysisResult, Output $output): in
5150
}
5251

5352
foreach ($analysisResult->getNotFileSpecificErrors() as $notFileSpecificError) {
54-
// newlines need to be encoded
55-
// see https://github.com/actions/starter-workflows/issues/68#issuecomment-581479448
56-
$notFileSpecificError = str_replace("\n", '%0A', $notFileSpecificError);
53+
$notFileSpecificError = $this->formatMessage($notFileSpecificError);
5754

5855
$line = sprintf('::error ::%s', $notFileSpecificError);
5956

@@ -62,8 +59,7 @@ public function formatErrors(AnalysisResult $analysisResult, Output $output): in
6259
}
6360

6461
foreach ($analysisResult->getWarnings() as $warning) {
65-
// newlines need to be encoded
66-
// see https://github.com/actions/starter-workflows/issues/68#issuecomment-581479448
62+
$warning = $this->formatMessage($warning);
6763
$warning = str_replace("\n", '%0A', $warning);
6864

6965
$line = sprintf('::warning ::%s', $warning);
@@ -75,4 +71,13 @@ public function formatErrors(AnalysisResult $analysisResult, Output $output): in
7571
return $analysisResult->hasErrors() ? 1 : 0;
7672
}
7773

74+
private function formatMessage(string $message): string
75+
{
76+
// newlines need to be encoded
77+
// see https://github.com/actions/starter-workflows/issues/68#issuecomment-581479448
78+
$message = str_replace("\n", '%0A', $message);
79+
80+
return preg_replace('/(^|\s)@([a-zA-Z0-9_\-]+)(\s|$)/', '$1`@$2`$3', $message) ?? $message;
81+
}
82+
7883
}

src/Testing/ErrorFormatterTestCase.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ protected function getAnalysisResult(array|int $numFileErrors, int $numGenericEr
8989
[$offsetFileErrors, $numFileErrors] = $numFileErrors;
9090
}
9191

92-
if (!in_array($numFileErrors, range(0, 6), true) ||
93-
!in_array($offsetFileErrors, range(0, 6), true) ||
92+
if (!in_array($numFileErrors, range(0, 7), true) ||
93+
!in_array($offsetFileErrors, range(0, 7), true) ||
9494
!in_array($numGenericErrors, range(0, 2), true)
9595
) {
9696
throw new ShouldNotHappenException();
@@ -103,6 +103,7 @@ protected function getAnalysisResult(array|int $numFileErrors, int $numGenericEr
103103
new Error("Bar\nBar2", self::DIRECTORY_PATH . '/folder with unicode 😃/file name with "spaces" and unicode 😃.php', 2),
104104
new Error("Bar\nBar2", self::DIRECTORY_PATH . '/foo.php', null),
105105
new Error('Foobar\\Buz', self::DIRECTORY_PATH . '/foo.php', 5, tip: 'a tip', identifier: 'foobar.buz'),
106+
new Error('Error with @param or @phpstan-param and class@anonymous in the message.', self::DIRECTORY_PATH . '/bar.php', 5),
106107
], $offsetFileErrors, $numFileErrors);
107108

108109
$genericErrors = array_slice([

tests/PHPStan/Command/ErrorFormatter/GithubErrorFormatterTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,27 @@ public static function dataFormatterOutputProvider(): iterable
7272
::error file=foo.php,line=5,col=0::Bar%0ABar2
7373
::error ::first generic error
7474
::error ::second generic<error>
75+
',
76+
];
77+
78+
yield [
79+
'One file, with @ tags',
80+
1,
81+
[6, 1],
82+
0,
83+
'::error file=bar.php,line=5,col=0::Error with `@param` or `@phpstan-param` and class@anonymous in the message.
7584
',
7685
];
7786
}
7887

88+
/**
89+
* @param array{int, int}|int $numFileErrors
90+
*/
7991
#[DataProvider('dataFormatterOutputProvider')]
8092
public function testFormatErrors(
8193
string $message,
8294
int $exitCode,
83-
int $numFileErrors,
95+
array|int $numFileErrors,
8496
int $numGenericErrors,
8597
string $expected,
8698
): void

tests/PHPStan/Command/ErrorFormatter/RawErrorFormatterTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public static function dataFormatterOutputProvider(): iterable
8484
yield [
8585
'message' => 'One file error with tip',
8686
'exitCode' => 1,
87-
'numFileErrors' => [5, 6],
87+
'numFileErrors' => [5, 1],
8888
'numGenericErrors' => 0,
8989
'verbose' => false,
9090
'expected' => '/data/folder/with space/and unicode 😃/project/foo.php:5:Foobar\Buz
@@ -94,7 +94,7 @@ public static function dataFormatterOutputProvider(): iterable
9494
yield [
9595
'message' => 'One file error with tip and verbose',
9696
'exitCode' => 1,
97-
'numFileErrors' => [5, 6],
97+
'numFileErrors' => [5, 1],
9898
'numGenericErrors' => 0,
9999
'verbose' => true,
100100
'expected' => '/data/folder/with space/and unicode 😃/project/foo.php:5:Foobar\Buz [identifier=foobar.buz]

tests/PHPStan/Command/ErrorFormatter/TableErrorFormatterTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ public static function dataFormatterOutputProvider(): iterable
190190
yield [
191191
'message' => 'One file error with tip',
192192
'exitCode' => 1,
193-
'numFileErrors' => [5, 6],
193+
'numFileErrors' => [5, 1],
194194
'numGenericErrors' => 0,
195195
'verbose' => false,
196196
'extraEnvVars' => [],
@@ -211,7 +211,7 @@ public static function dataFormatterOutputProvider(): iterable
211211
yield [
212212
'message' => 'One file error with tip and verbose',
213213
'exitCode' => 1,
214-
'numFileErrors' => [5, 6],
214+
'numFileErrors' => [5, 1],
215215
'numGenericErrors' => 0,
216216
'verbose' => true,
217217
'extraEnvVars' => [],

0 commit comments

Comments
 (0)