@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+32
+20
src/infrastructure/markup/PhabricatorMarkupEngine.php
··· 46 46 private $engineCaches = array(); 47 47 private $auxiliaryConfig = array(); 48 48 49 + private static $engineStack = array(); 50 + 49 51 50 52 /* -( Markup Pipeline )---------------------------------------------------- */ 51 53 ··· 103 105 * @task markup 104 106 */ 105 107 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() { 106 126 $keys = array(); 107 127 foreach ($this->objects as $key => $info) { 108 128 if (!isset($info['markup'])) {
+12
src/infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php
··· 126 126 return $this->renderObjectTagForMail($name, $href, $handle); 127 127 } 128 128 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 + 129 135 return $this->renderObjectEmbed($object, $handle, $options); 130 136 } 131 137 ··· 133 139 $object, 134 140 PhabricatorObjectHandle $handle, 135 141 $options) { 142 + return $this->renderDefaultObjectEmbed($object, $handle); 143 + } 144 + 145 + final protected function renderDefaultObjectEmbed( 146 + $object, 147 + PhabricatorObjectHandle $handle) { 136 148 137 149 $name = $handle->getFullName(); 138 150 $href = $handle->getURI();