mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 14:00:56 +01:00
Fix an issue where the "%%%" parser could match too many lines in unterminated blocks
Summary: Fixes T13530. The block parser could match too many lines in an unterminated "%%%" literal block. Adjust the logic to stop doing this (and hopefully be a little easier to read). Test Plan: Added a failing test, made it pass. Maniphest Tasks: T13530 Differential Revision: https://secure.phabricator.com/D21208
This commit is contained in:
parent
b2cfcda114
commit
6f09edeb91
3 changed files with 58 additions and 34 deletions
|
@ -22,51 +22,69 @@ final class PhutilRemarkupLiteralBlockRule extends PhutilRemarkupBlockRule {
|
||||||
// output text and assists automated escaping of blocks coming into the
|
// output text and assists automated escaping of blocks coming into the
|
||||||
// system.
|
// system.
|
||||||
|
|
||||||
$num_lines = 0;
|
$start_pattern = '(^\s*%%%)';
|
||||||
while (preg_match('/^\s*%%%/', $lines[$cursor])) {
|
$end_pattern = '(%%%\s*$)';
|
||||||
$num_lines++;
|
$trivial_pattern = '(^\s*%%%\s*$)';
|
||||||
|
|
||||||
// If the line has ONLY "%%%", the block opener doesn't get to double
|
if (!preg_match($start_pattern, $lines[$cursor])) {
|
||||||
// up as a block terminator.
|
return 0;
|
||||||
if (preg_match('/^\s*%%%\s*\z/', $lines[$cursor])) {
|
|
||||||
$num_lines++;
|
|
||||||
$cursor++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (isset($lines[$cursor])) {
|
$start_cursor = $cursor;
|
||||||
if (!preg_match('/%%%\s*$/', $lines[$cursor])) {
|
|
||||||
$num_lines++;
|
|
||||||
$cursor++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$cursor++;
|
|
||||||
|
|
||||||
$found_empty = false;
|
$found_empty = false;
|
||||||
while (isset($lines[$cursor])) {
|
$block_start = null;
|
||||||
if (!strlen(trim($lines[$cursor]))) {
|
while (true) {
|
||||||
$num_lines++;
|
if (!isset($lines[$cursor])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$line = $lines[$cursor];
|
||||||
|
|
||||||
|
if ($block_start === null) {
|
||||||
|
$is_start = preg_match($start_pattern, $line);
|
||||||
|
|
||||||
|
// If we've matched a block and then consumed one or more empty lines
|
||||||
|
// after it, stop merging more blocks into the match.
|
||||||
|
if ($found_empty) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_start) {
|
||||||
|
$block_start = $cursor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($block_start !== null) {
|
||||||
|
$is_end = preg_match($end_pattern, $line);
|
||||||
|
|
||||||
|
// If a line contains only "%%%", it will match both the start and
|
||||||
|
// end patterns, but it only counts as a block start.
|
||||||
|
if ($is_end && ($cursor === $block_start)) {
|
||||||
|
$is_trivial = preg_match($trivial_pattern, $line);
|
||||||
|
if ($is_trivial) {
|
||||||
|
$is_end = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_end) {
|
||||||
|
$block_start = null;
|
||||||
$cursor++;
|
$cursor++;
|
||||||
$found_empty = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($found_empty) {
|
if ($block_start === null) {
|
||||||
// If there's an empty line after the block, stop merging blocks.
|
if (strlen(trim($line))) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($lines[$cursor])) {
|
|
||||||
// If we're at the end of the input, stop looking for more lines.
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
$found_empty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $num_lines;
|
$cursor++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($cursor - $start_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function markupText($text, $children) {
|
public function markupText($text, $children) {
|
||||||
|
|
|
@ -204,6 +204,7 @@ final class PhutilRemarkupEngine extends PhutilMarkupEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
$cursor += $num_lines;
|
$cursor += $num_lines;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
%%%xyz
|
||||||
|
~~~~~~~~~~
|
||||||
|
<p class="remarkup-literal">xyz</p>
|
||||||
|
~~~~~~~~~~
|
||||||
|
xyz
|
Loading…
Reference in a new issue