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

Prevent embedded remarkup content from cycling when it contains embedded self-references

Summary: Ref T13678. When remarkup content embeds other remarkup content, detect and degrade if the references have nesting depth greater than 1. This is a coarse cycle detector, since rendering shallow (but technically non-cycling) trees doesn't seem valuable.

Test Plan: Created various objects with self-references, saw everything degrade properly (after one level of embedding) when embedded in itself and in other contexts. See attached screenshot.

Maniphest Tasks: T13678

Differential Revision: https://secure.phabricator.com/D21810
This commit is contained in:
epriestley 2022-05-09 11:18:13 -07:00
parent a640a4a493
commit 01253d533b
2 changed files with 32 additions and 0 deletions

View file

@ -46,6 +46,8 @@ final class PhabricatorMarkupEngine extends Phobject {
private $engineCaches = array(); private $engineCaches = array();
private $auxiliaryConfig = array(); private $auxiliaryConfig = array();
private static $engineStack = array();
/* -( Markup Pipeline )---------------------------------------------------- */ /* -( Markup Pipeline )---------------------------------------------------- */
@ -103,6 +105,24 @@ final class PhabricatorMarkupEngine extends Phobject {
* @task markup * @task markup
*/ */
public function process() { public function process() {
self::$engineStack[] = $this;
try {
$result = $this->execute();
} finally {
array_pop(self::$engineStack);
}
return $result;
}
public static function isRenderingEmbeddedContent() {
// See T13678. This prevents cycles when rendering embedded content that
// itself has remarkup fields.
return (count(self::$engineStack) > 1);
}
private function execute() {
$keys = array(); $keys = array();
foreach ($this->objects as $key => $info) { foreach ($this->objects as $key => $info) {
if (!isset($info['markup'])) { if (!isset($info['markup'])) {

View file

@ -126,6 +126,12 @@ abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule {
return $this->renderObjectTagForMail($name, $href, $handle); return $this->renderObjectTagForMail($name, $href, $handle);
} }
// See T13678. If we're already rendering embedded content, render a
// default reference instead to avoid cycles.
if (PhabricatorMarkupEngine::isRenderingEmbeddedContent()) {
return $this->renderDefaultObjectEmbed($object, $handle);
}
return $this->renderObjectEmbed($object, $handle, $options); return $this->renderObjectEmbed($object, $handle, $options);
} }
@ -133,6 +139,12 @@ abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule {
$object, $object,
PhabricatorObjectHandle $handle, PhabricatorObjectHandle $handle,
$options) { $options) {
return $this->renderDefaultObjectEmbed($object, $handle);
}
final protected function renderDefaultObjectEmbed(
$object,
PhabricatorObjectHandle $handle) {
$name = $handle->getFullName(); $name = $handle->getFullName();
$href = $handle->getURI(); $href = $handle->getURI();