1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 06:42:42 +01:00

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
This commit is contained in:
Andre Klapper 2023-08-19 20:18:45 +02:00
parent dc10a7e69e
commit 7868ab3754

View file

@ -2,13 +2,35 @@
final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule { final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule {
const START_BLOCK_PATTERN = '/^([\w]+)\s*(?:\(([^)]+)\)\s*)?{{{/'; /**
* Second part of the regex to find stuff like:
* interpreterName {{{ stuff }}}
* interpreterName (options) {{{ stuff }}}
* You have found the kernel of cowsay and figlet.
*/
const END_BLOCK_PATTERN = '/}}}\s*$/'; const END_BLOCK_PATTERN = '/}}}\s*$/';
/**
* Constructs the first part of the regex to find stuff like:
* interpreterName {{{ stuff }}}
* interpreterName (options) {{{ stuff }}}
* The exact regex is constructed from the available interpreters.
* @return string First part of interpreters regex
*/
private function getStartBlockPattern() {
$interpreters = id(new PhutilClassMapQuery())
->setAncestorClass('PhutilRemarkupBlockInterpreter')
->execute();
$interpreters_regex = mpull($interpreters, 'getInterpreterName');
$interpreters_regex = array_map('preg_quote', $interpreters_regex);
$interpreters_regex = implode('|', $interpreters_regex);
return "/^($interpreters_regex)\s*(?:\(([^)]+)\)\s*)?{{{/";
}
public function getMatchingLineCount(array $lines, $cursor) { public function getMatchingLineCount(array $lines, $cursor) {
$num_lines = 0; $num_lines = 0;
if (preg_match(self::START_BLOCK_PATTERN, $lines[$cursor])) { if (preg_match(self::getStartBlockPattern(), $lines[$cursor])) {
$num_lines++; $num_lines++;
while (isset($lines[$cursor])) { while (isset($lines[$cursor])) {
@ -33,7 +55,7 @@ final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule {
} }
$matches = null; $matches = null;
preg_match(self::START_BLOCK_PATTERN, head($lines), $matches); preg_match(self::getStartBlockPattern(), head($lines), $matches);
$argv = array(); $argv = array();
if (isset($matches[2])) { if (isset($matches[2])) {
@ -49,7 +71,7 @@ final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule {
} }
$lines[$first_key] = preg_replace( $lines[$first_key] = preg_replace(
self::START_BLOCK_PATTERN, self::getStartBlockPattern(),
'', '',
$lines[$first_key]); $lines[$first_key]);
$lines[$last_key] = preg_replace( $lines[$last_key] = preg_replace(