From 99d3d5e8117b364e7d0b206e26d32bbfbba80a54 Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Mon, 29 Nov 2021 04:47:47 +0200 Subject: [PATCH] Escape GHA output Refs Roave/BackwardCompatibilityCheck#342 Thanks @staabm for highlighting this issue. --- src/Psalm/Report/GithubActionsReport.php | 48 ++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/Psalm/Report/GithubActionsReport.php b/src/Psalm/Report/GithubActionsReport.php index aa0afa314f3..36eae063739 100644 --- a/src/Psalm/Report/GithubActionsReport.php +++ b/src/Psalm/Report/GithubActionsReport.php @@ -5,6 +5,7 @@ use Psalm\Report; use function sprintf; +use function strtr; class GithubActionsReport extends Report { @@ -13,17 +14,58 @@ public function create(): string $output = ''; foreach ($this->issues_data as $issue_data) { $issue_reference = $issue_data->link ? ' (see ' . $issue_data->link . ')' : ''; - $output .= sprintf( - '::%1$s file=%2$s,line=%3$s,col=%4$s,title=%5$s::%2$s:%3$s:%4$s: %5$s: %6$s', - ($issue_data->severity === Config::REPORT_ERROR ? 'error' : 'warning'), + $properties = sprintf( + 'file=%1$s,line=%2$d,col=%3$d,title=%4$s', + $this->escapeProperty($issue_data->file_name), + $this->escapeProperty($issue_data->line_from), + $this->escapeProperty($issue_data->column_from), + $this->escapeProperty($issue_data->type) + ); + + $data = $this->escapeData(sprintf( + '%1$s:%2$d:%3$d: %4$s: %5$s', $issue_data->file_name, $issue_data->line_from, $issue_data->column_from, $issue_data->type, $issue_data->message . $issue_reference + )); + + $output .= sprintf( + '::%1$s %2$s::%3$s', + ($issue_data->severity === Config::REPORT_ERROR ? 'error' : 'warning'), + $properties, + $data ) . "\n"; } return $output; } + + private function escapeData(string $data): string + { + return strtr( + $data, + [ + '%' => '%25', + "\r" => '%0D', + "\n" => '%0A', + ] + ); + } + + /** @param mixed $value */ + private function escapeProperty($value): string + { + return strtr( + (string) $value, + [ + '%' => '%25', + "\r" => '%0D', + "\n" => '%0A', + ':' => '%3A', + ',' => '%2C', + ] + ); + } }