Differential D18666 Diff 44820 src/markup/engine/remarkup/markuprule/PhutilRemarkupHyperlinkRule.php
Changeset View
Changeset View
Standalone View
Standalone View
src/markup/engine/remarkup/markuprule/PhutilRemarkupHyperlinkRule.php
Show All 26 Lines | $text = preg_replace_callback( | ||||
'@(\w{3,}://[^\s'.PhutilRemarkupBlockStorage::MAGIC_BYTE.']+)@', | '@(\w{3,}://[^\s'.PhutilRemarkupBlockStorage::MAGIC_BYTE.']+)@', | ||||
array($this, 'markupHyperlinkUngreedy'), | array($this, 'markupHyperlinkUngreedy'), | ||||
$text); | $text); | ||||
return $text; | return $text; | ||||
} | } | ||||
protected function markupHyperlink(array $matches) { | protected function markupHyperlink(array $matches) { | ||||
try { | |||||
$uri = new PhutilURI($matches[1]); | |||||
} catch (Exception $ex) { | |||||
return $matches[0]; | |||||
} | |||||
$protocol = $uri->getProtocol(); | |||||
$protocols = $this->getEngine()->getConfig( | $protocols = $this->getEngine()->getConfig( | ||||
'uri.allowed-protocols', | 'uri.allowed-protocols', | ||||
array()); | array()); | ||||
$protocol = id(new PhutilURI($matches[1]))->getProtocol(); | |||||
if (!idx($protocols, $protocol)) { | if (!idx($protocols, $protocol)) { | ||||
// If this URI doesn't use a whitelisted protocol, don't link it. This | // If this URI doesn't use a whitelisted protocol, don't link it. This | ||||
// is primarily intended to prevent javascript:// silliness. | // is primarily intended to prevent javascript:// silliness. | ||||
return $this->getEngine()->storeText($matches[1]); | return $this->getEngine()->storeText($matches[1]); | ||||
} | } | ||||
return $this->storeRenderedHyperlink($matches[1]); | return $this->storeRenderedHyperlink($matches[1]); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | protected function markupHyperlinkUngreedy($matches) { | ||||
// | // | ||||
// We could apply a craftier heuristic here which tries to actually balance | // We could apply a craftier heuristic here which tries to actually balance | ||||
// the parens, but this is probably sufficient. | // the parens, but this is probably sufficient. | ||||
if (preg_match('/\\)$/', $match) && !preg_match('/\\(/', $match)) { | if (preg_match('/\\)$/', $match) && !preg_match('/\\(/', $match)) { | ||||
$tail = ')'.$tail; | $tail = ')'.$tail; | ||||
$match = substr($match, 0, -1); | $match = substr($match, 0, -1); | ||||
} | } | ||||
try { | |||||
$uri = new PhutilURI($match); | |||||
} catch (Exception $ex) { | |||||
return $matches[0]; | |||||
} | |||||
return hsprintf('%s%s', $this->markupHyperlink(array(null, $match)), $tail); | return hsprintf('%s%s', $this->markupHyperlink(array(null, $match)), $tail); | ||||
} | } | ||||
} | } |