6
abstract class PhutilRemarkupRule {
9
private $replaceCallback;
11
public function setEngine(PhutilRemarkupEngine $engine) {
12
$this->engine = $engine;
16
public function getEngine() {
20
public function getPriority() {
24
abstract public function apply($text);
26
public function getPostprocessKey() {
27
return spl_object_hash($this);
30
public function didMarkupText() {
34
protected function replaceHTML($pattern, $callback, $text) {
35
$this->replaceCallback = $callback;
36
return phutil_safe_html(preg_replace_callback(
38
array($this, 'replaceHTMLCallback'),
39
phutil_escape_html($text)));
42
private function replaceHTMLCallback($match) {
43
return phutil_escape_html(call_user_func(
44
$this->replaceCallback,
45
array_map('phutil_safe_html', $match)));
50
* Safely generate a tag.
52
* In Remarkup contexts, it's not safe to use arbitrary text in tag
53
* attributes: even though it will be escaped, it may contain replacement
54
* tokens which are then replaced with markup.
56
* This method acts as @{function:phutil_tag}, but checks attributes before
59
* @param string Tag name.
60
* @param dict<string, wild> Tag attributes.
61
* @param wild Tag content.
62
* @return PhutilSafeHTML Tag object.
64
protected function newTag($name, array $attrs, $content = null) {
65
foreach ($attrs as $key => $attr) {
67
$attrs[$key] = $this->assertFlatText($attr);
71
return phutil_tag($name, $attrs, $content);
75
* Assert that a text token is flat (it contains no replacement tokens).
77
* Because tokens can be replaced with markup, it is dangerous to use
78
* arbitrary input text in tag attributes. Normally, rule precedence should
79
* prevent this. Asserting that text is flat before using it as an attribute
80
* provides an extra layer of security.
82
* Normally, you can call @{method:newTag} rather than calling this method
83
* directly. @{method:newTag} will check attributes for you.
85
* @param wild Ostensibly flat text.
86
* @return string Flat text.
88
protected function assertFlatText($text) {
89
$text = (string)hsprintf('%s', phutil_safe_html($text));
90
$rich = (strpos($text, PhutilRemarkupBlockStorage::MAGIC_BYTE) !== false);
94
'Remarkup rule precedence is dangerous: rendering text with tokens '.
102
* Check whether text is flat (contains no replacement tokens) or not.
104
* @param wild Ostensibly flat text.
105
* @return bool True if the text is flat.
107
protected function isFlatText($text) {
108
$text = (string)hsprintf('%s', phutil_safe_html($text));
109
return (strpos($text, PhutilRemarkupBlockStorage::MAGIC_BYTE) === false);