From 9c73d62c446613551fe5cbee4d618b982a7f5f0a Mon Sep 17 00:00:00 2001 From: Pppery Date: Sat, 23 Nov 2024 16:04:38 -0500 Subject: [PATCH] Rewrite regex for project names to be not prone to catastrophic backtracking Summary: Fixes T15371 Test Plan: - Save the text `{{#translation:}}` in remarkup and see that it renders. - Create a project or projects with the hashtags `a`, `b`, `ab`, `foo`, `f.o.o`. - Observe that both before and after this patch you can link to all of them by hashtag. - Create a project or projects with the hashtags `a.`, `.b`, `.foo`, `foo.`. - Observe that both before and after this patch you can link to none of them by hashtag. Reviewers: O1 Blessed Committers, aklapper Reviewed By: O1 Blessed Committers, aklapper Subscribers: aklapper, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15371 Differential Revision: https://we.phorge.it/D25838 --- .../project/remarkup/ProjectRemarkupRule.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/applications/project/remarkup/ProjectRemarkupRule.php b/src/applications/project/remarkup/ProjectRemarkupRule.php index 96092bab86..6f251d54ac 100644 --- a/src/applications/project/remarkup/ProjectRemarkupRule.php +++ b/src/applications/project/remarkup/ProjectRemarkupRule.php @@ -22,8 +22,8 @@ final class ProjectRemarkupRule extends PhabricatorObjectRemarkupRule { } protected function getObjectIDPattern() { - // NOTE: The latter half of this rule matches monograms with internal - // periods, like `#domain.com`, but does not match monograms with terminal + // NOTE: This rule matches monograms with internal periods, + // like `#domain.com`, but does not match monograms with terminal // periods, because they're probably just punctuation. // Broadly, this will not match every possible project monogram, and we @@ -39,12 +39,14 @@ final class ProjectRemarkupRule extends PhabricatorObjectRemarkupRule { // These characters may not appear at the edge of the string. $never_edge = '.'; - return - '[^'.$never_edge.$never.']+'. - '(?:'. - '[^'.$never.']*'. - '[^'.$never_edge.$never.']+'. - ')*'; + return '(?:'. + // Short project name with one or two characters not in $never_edge or + '[^'.$never_edge.$never.']{1,2}|'. + // A single character not in $never or $never_edge, + // then any number of characters not in $never then a single character + // not in $never or $never_edge + '[^'.$never_edge.$never.'][^'.$never.']+[^'.$never_edge.$never.']'. + ')'; } protected function loadObjects(array $ids) {