Skip to content

Commit 01253d5

Browse files
author
epriestley
committed
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
1 parent a640a4a commit 01253d5

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/infrastructure/markup/PhabricatorMarkupEngine.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ final class PhabricatorMarkupEngine extends Phobject {
4646
private $engineCaches = array();
4747
private $auxiliaryConfig = array();
4848

49+
private static $engineStack = array();
50+
4951

5052
/* -( Markup Pipeline )---------------------------------------------------- */
5153

@@ -103,6 +105,24 @@ public function addObject(PhabricatorMarkupInterface $object, $field) {
103105
* @task markup
104106
*/
105107
public function process() {
108+
self::$engineStack[] = $this;
109+
110+
try {
111+
$result = $this->execute();
112+
} finally {
113+
array_pop(self::$engineStack);
114+
}
115+
116+
return $result;
117+
}
118+
119+
public static function isRenderingEmbeddedContent() {
120+
// See T13678. This prevents cycles when rendering embedded content that
121+
// itself has remarkup fields.
122+
return (count(self::$engineStack) > 1);
123+
}
124+
125+
private function execute() {
106126
$keys = array();
107127
foreach ($this->objects as $key => $info) {
108128
if (!isset($info['markup'])) {

src/infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,25 @@ protected function renderObjectEmbedForAnyMedia(
126126
return $this->renderObjectTagForMail($name, $href, $handle);
127127
}
128128

129+
// See T13678. If we're already rendering embedded content, render a
130+
// default reference instead to avoid cycles.
131+
if (PhabricatorMarkupEngine::isRenderingEmbeddedContent()) {
132+
return $this->renderDefaultObjectEmbed($object, $handle);
133+
}
134+
129135
return $this->renderObjectEmbed($object, $handle, $options);
130136
}
131137

132138
protected function renderObjectEmbed(
133139
$object,
134140
PhabricatorObjectHandle $handle,
135141
$options) {
142+
return $this->renderDefaultObjectEmbed($object, $handle);
143+
}
144+
145+
final protected function renderDefaultObjectEmbed(
146+
$object,
147+
PhabricatorObjectHandle $handle) {
136148

137149
$name = $handle->getFullName();
138150
$href = $handle->getURI();

0 commit comments

Comments
 (0)