Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2892764
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
5 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/infrastructure/markup/markuprule/PhutilRemarkupHexColorCodeRule.php b/src/infrastructure/markup/markuprule/PhutilRemarkupHexColorCodeRule.php
index 4c5a048e13..76dd2fcb38 100644
--- a/src/infrastructure/markup/markuprule/PhutilRemarkupHexColorCodeRule.php
+++ b/src/infrastructure/markup/markuprule/PhutilRemarkupHexColorCodeRule.php
@@ -1,57 +1,60 @@
<?php
final class PhutilRemarkupHexColorCodeRule
extends PhabricatorRemarkupCustomInlineRule {
public function getPriority() {
return 1000.0;
}
public function apply($text) {
// Match {#FFFFFF}
- return preg_replace_callback(
- '@\B\{(#([0-9a-fA-F]{3}){1,2})\}@',
- array($this, 'markupHexColorCodedText'),
- $text);
+ if (is_string($text)) {
+ return preg_replace_callback(
+ '@\B\{(#([0-9a-fA-F]{3}){1,2})\}@',
+ array($this, 'markupHexColorCodedText'),
+ $text);
+ }
+ return $text;
}
protected function contrastingColor($color_code) {
$match = ltrim($color_code, '#');
$colors_hex = str_split($match, strlen($match) / 3);
list($r, $g, $b) = array_map('hexdec', $colors_hex);
// Calculation adapted from Myndex, CC BY-SA 4.0
// https://stackoverflow.com/a/69869976
$y = pow((double)$r / 255.0, 2.2) * 0.2126 +
pow((double)$g / 255.0, 2.2) * 0.7152 +
pow((double)$b / 255.0, 2.2) * 0.0722;
return ($y < 0.34) ? 'white' : 'black';
}
protected function markupHexColorCodedText(array $matches) {
if ($this->getEngine()->isTextMode()) {
$result = $matches[1];
} else {
if (count($matches) < 2) {
return $matches[0];
} else {
$len = strlen($matches[1]);
if (7 !== $len && 4 !== $len) {
return $matches[0];
}
}
$match = $matches[1];
$fg = $this->contrastingColor($match);
$result = phutil_tag(
'tt',
array(
'class' => 'remarkup-monospaced',
'style' => "color: {$fg}; background-color: {$match};",
),
$match);
}
return $this->getEngine()->storeText($result);
}
}
diff --git a/src/infrastructure/markup/markuprule/PhutilRemarkupRule.php b/src/infrastructure/markup/markuprule/PhutilRemarkupRule.php
index a0ef7dc3ec..4a3c1460e9 100644
--- a/src/infrastructure/markup/markuprule/PhutilRemarkupRule.php
+++ b/src/infrastructure/markup/markuprule/PhutilRemarkupRule.php
@@ -1,109 +1,115 @@
<?php
abstract class PhutilRemarkupRule extends Phobject {
private $engine;
private $replaceCallback;
public function setEngine(PhutilRemarkupEngine $engine) {
$this->engine = $engine;
return $this;
}
public function getEngine() {
return $this->engine;
}
public function getPriority() {
return 500.0;
}
+ /**
+ * Check input whether to apply RemarkupRule. If true, apply formatting.
+ * @param string|PhutilSafeHTML String to check and potentially format.
+ * @return string|PhutilSafeHTML Unchanged input if no match, or input after
+ * matching the formatting rule and applying the formatting.
+ */
abstract public function apply($text);
public function getPostprocessKey() {
return spl_object_hash($this);
}
public function didMarkupText() {
return;
}
protected function replaceHTML($pattern, $callback, $text) {
$this->replaceCallback = $callback;
return phutil_safe_html(preg_replace_callback(
$pattern,
array($this, 'replaceHTMLCallback'),
phutil_escape_html($text)));
}
private function replaceHTMLCallback(array $match) {
return phutil_escape_html(call_user_func(
$this->replaceCallback,
array_map('phutil_safe_html', $match)));
}
/**
* Safely generate a tag.
*
* In Remarkup contexts, it's not safe to use arbitrary text in tag
* attributes: even though it will be escaped, it may contain replacement
* tokens which are then replaced with markup.
*
* This method acts as @{function:phutil_tag}, but checks attributes before
* using them.
*
* @param string Tag name.
* @param dict<string, wild> Tag attributes.
* @param wild Tag content.
* @return PhutilSafeHTML Tag object.
*/
protected function newTag($name, array $attrs, $content = null) {
foreach ($attrs as $key => $attr) {
if ($attr !== null) {
$attrs[$key] = $this->assertFlatText($attr);
}
}
return phutil_tag($name, $attrs, $content);
}
/**
* Assert that a text token is flat (it contains no replacement tokens).
*
* Because tokens can be replaced with markup, it is dangerous to use
* arbitrary input text in tag attributes. Normally, rule precedence should
* prevent this. Asserting that text is flat before using it as an attribute
* provides an extra layer of security.
*
* Normally, you can call @{method:newTag} rather than calling this method
* directly. @{method:newTag} will check attributes for you.
*
* @param wild Ostensibly flat text.
* @return string Flat text.
*/
protected function assertFlatText($text) {
$text = (string)hsprintf('%s', phutil_safe_html($text));
$rich = (strpos($text, PhutilRemarkupBlockStorage::MAGIC_BYTE) !== false);
if ($rich) {
throw new Exception(
pht(
'Remarkup rule precedence is dangerous: rendering text with tokens '.
'as flat text!'));
}
return $text;
}
/**
* Check whether text is flat (contains no replacement tokens) or not.
*
* @param wild Ostensibly flat text.
* @return bool True if the text is flat.
*/
protected function isFlatText($text) {
$text = (string)hsprintf('%s', phutil_safe_html($text));
return (strpos($text, PhutilRemarkupBlockStorage::MAGIC_BYTE) === false);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Jan 19, 17:19 (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1126890
Default Alt Text
(5 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment