From d9079978ed21c314f07913a37e087c0d43fc7dd0 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 15 Jun 2026 11:14:06 +0000 Subject: [PATCH] parallel-make-check: percent-encode warn() workflow-command data A config name comes from JSON and is only checked for emptiness and a '/', so it can carry %, CR or LF. Passed straight into the ::warning:: workflow command those would truncate the annotation or be parsed as a second command, so escape them in the GitHub branch of warn() per GitHub's documented command-data encoding (% first). Local output is unchanged. --- .github/scripts/parallel-make-check.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/scripts/parallel-make-check.py b/.github/scripts/parallel-make-check.py index 95c04ca1ea..c88fff12ab 100755 --- a/.github/scripts/parallel-make-check.py +++ b/.github/scripts/parallel-make-check.py @@ -247,7 +247,14 @@ def dump(title: str, path: Path) -> None: def warn(msg: str) -> None: # GitHub surfaces ::warning:: as an annotation at the top of the run; # locally it is just a line. Informational only - never fails the run. - print(f"::warning::{msg}" if ON_GITHUB else f"WARNING: {msg}") + if ON_GITHUB: + # Percent-encode the command data (GitHub's documented escaping) so + # a stray %, CR or LF - e.g. from a config name out of the JSON - + # can't truncate the annotation or be read as a second command. + msg = msg.replace("%", "%25").replace("\r", "%0D").replace("\n", "%0A") + print(f"::warning::{msg}") + else: + print(f"WARNING: {msg}") def stale_estimate(cfg: Config, minutes: float) -> bool: