From d41a59e422de2da019f77e520421a1a84fc5ba73 Mon Sep 17 00:00:00 2001 From: "f.godfrin" Date: Thu, 9 Feb 2017 22:18:15 +0100 Subject: [PATCH] Add rgba support for css color attribute definition --- library/HTMLPurifier/AttrDef/CSS/Color.php | 37 ++++++++++++++++---- tests/HTMLPurifier/AttrDef/CSS/ColorTest.php | 5 +++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/library/HTMLPurifier/AttrDef/CSS/Color.php b/library/HTMLPurifier/AttrDef/CSS/Color.php index 16d2a6b9..e64bc936 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Color.php +++ b/library/HTMLPurifier/AttrDef/CSS/Color.php @@ -29,24 +29,49 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef return $colors[$lower]; } - if (strpos($color, 'rgb(') !== false) { + if (preg_match('#(rgb|rgba)\(#', $color, $matches) === 1) { + // get used function : rgb or rgba + $function = $matches[1]; + if ($function == 'rgba') { + $parameters_size = 4; + } else { + $parameters_size = 3; + } + // rgb literal handling $length = strlen($color); if (strpos($color, ')') !== $length - 1) { return false; } - $triad = substr($color, 4, $length - 4 - 1); - $parts = explode(',', $triad); - if (count($parts) !== 3) { + + $values = substr($color, strlen($function) + 1, $length - strlen($function) - 2); + + $parts = explode(',', $values); + if (count($parts) !== $parameters_size) { return false; } $type = false; // to ensure that they're all the same type $new_parts = array(); + $i = 0; foreach ($parts as $part) { + $i++; $part = trim($part); if ($part === '') { return false; } + + // different check for alpha channel + if ($function === 'rgba' && $i === count($parts)) { + $result = (new HTMLPurifier_AttrDef_CSS_AlphaValue())->validate($part, $config, $context); + + if ($result === false) { + return false; + } + + $new_parts[] = (string)$result; + continue; + } + $length = strlen($part); if ($part[$length - 1] === '%') { // handle percents @@ -80,8 +105,8 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef $new_parts[] = (string)$num; } } - $new_triad = implode(',', $new_parts); - $color = "rgb($new_triad)"; + $new_values = implode(',', $new_parts); + $color = "$function($new_values)"; } else { // hexadecimal handling if ($color[0] === '#') { diff --git a/tests/HTMLPurifier/AttrDef/CSS/ColorTest.php b/tests/HTMLPurifier/AttrDef/CSS/ColorTest.php index 980bd909..9586f063 100644 --- a/tests/HTMLPurifier/AttrDef/CSS/ColorTest.php +++ b/tests/HTMLPurifier/AttrDef/CSS/ColorTest.php @@ -11,10 +11,15 @@ class HTMLPurifier_AttrDef_CSS_ColorTest extends HTMLPurifier_AttrDefHarness $this->assertDef('#fff'); $this->assertDef('#eeeeee'); $this->assertDef('#808080'); + $this->assertDef('rgb(255, 0, 0)', 'rgb(255,0,0)'); // rm spaces $this->assertDef('rgb(100%,0%,0%)'); $this->assertDef('rgb(50.5%,23.2%,43.9%)'); // decimals okay + $this->assertDef('rgba(255, 0, 0, 0)', 'rgba(255,0,0,0)'); // rm spaces + $this->assertDef('rgba(100%,0%,0%,.4)'); + $this->assertDef('rgba(38.1%,59.7%,1.8%,0.7)', 'rgba(38.1%,59.7%,1.8%,.7)'); // decimals okay + $this->assertDef('#G00', false); $this->assertDef('cmyk(40, 23, 43, 23)', false); $this->assertDef('rgb(0%, 23, 68%)', false);