mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52: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:
parent
a640a4a493
commit
01253d533b
2 changed files with 32 additions and 0 deletions
|
@ -46,6 +46,8 @@ final class PhabricatorMarkupEngine extends Phobject {
|
|||
private $engineCaches = array();
|
||||
private $auxiliaryConfig = array();
|
||||
|
||||
private static $engineStack = array();
|
||||
|
||||
|
||||
/* -( Markup Pipeline )---------------------------------------------------- */
|
||||
|
||||
|
@ -103,6 +105,24 @@ final class PhabricatorMarkupEngine extends Phobject {
|
|||
* @task markup
|
||||
*/
|
||||
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();
|
||||
foreach ($this->objects as $key => $info) {
|
||||
if (!isset($info['markup'])) {
|
||||
|
|
|
@ -126,6 +126,12 @@ abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule {
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -133,6 +139,12 @@ abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule {
|
|||
$object,
|
||||
PhabricatorObjectHandle $handle,
|
||||
$options) {
|
||||
return $this->renderDefaultObjectEmbed($object, $handle);
|
||||
}
|
||||
|
||||
final protected function renderDefaultObjectEmbed(
|
||||
$object,
|
||||
PhabricatorObjectHandle $handle) {
|
||||
|
||||
$name = $handle->getFullName();
|
||||
$href = $handle->getURI();
|
||||
|
|
Loading…
Reference in a new issue