@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make InterpreterBlockRule regex only match on valid interpreter names

Summary:
With this patch, the underlying exception described in T15372#8537 still remains. However, with this patch, the bug is more contained as it is not triggered when not calling an interpreter (`cowsay`, `figlet`), so Phorge does not crash rendering `noValidInterpreter {{{foo}}} bar` lines but renders them as is (for whatever reasons such lines may exist).

See T15372

Test Plan:
Enter strings into a comment:
* `invalid {{{saysay}}} foo` now renders as plain text instead of crashing
* `invalid (invalid) {{{saysay}}} foo` now renders as plain text instead of crashing
* `cowsay (invalid) {{{saysay}}} foo` will still crash as before

Reviewers: O1 Blessed Committers, valerio.bozzolan

Reviewed By: O1 Blessed Committers, valerio.bozzolan

Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno

Differential Revision: https://we.phorge.it/D25415

+26 -4
+26 -4
src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php
··· 2 2 3 3 final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule { 4 4 5 - const START_BLOCK_PATTERN = '/^([\w]+)\s*(?:\(([^)]+)\)\s*)?{{{/'; 5 + /** 6 + * Second part of the regex to find stuff like: 7 + * interpreterName {{{ stuff }}} 8 + * interpreterName (options) {{{ stuff }}} 9 + * You have found the kernel of cowsay and figlet. 10 + */ 6 11 const END_BLOCK_PATTERN = '/}}}\s*$/'; 7 12 13 + /** 14 + * Constructs the first part of the regex to find stuff like: 15 + * interpreterName {{{ stuff }}} 16 + * interpreterName (options) {{{ stuff }}} 17 + * The exact regex is constructed from the available interpreters. 18 + * @return string First part of interpreters regex 19 + */ 20 + private function getStartBlockPattern() { 21 + $interpreters = id(new PhutilClassMapQuery()) 22 + ->setAncestorClass('PhutilRemarkupBlockInterpreter') 23 + ->execute(); 24 + $interpreters_regex = mpull($interpreters, 'getInterpreterName'); 25 + $interpreters_regex = array_map('preg_quote', $interpreters_regex); 26 + $interpreters_regex = implode('|', $interpreters_regex); 27 + return "/^($interpreters_regex)\s*(?:\(([^)]+)\)\s*)?{{{/"; 28 + } 29 + 8 30 public function getMatchingLineCount(array $lines, $cursor) { 9 31 $num_lines = 0; 10 32 11 - if (preg_match(self::START_BLOCK_PATTERN, $lines[$cursor])) { 33 + if (preg_match(self::getStartBlockPattern(), $lines[$cursor])) { 12 34 $num_lines++; 13 35 14 36 while (isset($lines[$cursor])) { ··· 33 55 } 34 56 $matches = null; 35 57 36 - preg_match(self::START_BLOCK_PATTERN, head($lines), $matches); 58 + preg_match(self::getStartBlockPattern(), head($lines), $matches); 37 59 38 60 $argv = array(); 39 61 if (isset($matches[2])) { ··· 49 71 } 50 72 51 73 $lines[$first_key] = preg_replace( 52 - self::START_BLOCK_PATTERN, 74 + self::getStartBlockPattern(), 53 75 '', 54 76 $lines[$first_key]); 55 77 $lines[$last_key] = preg_replace(