From 1ea697a3cf8117d6a4c867e7a46cfac30ef57a97 Mon Sep 17 00:00:00 2001 From: Thomas Guyard Date: Tue, 9 Sep 2014 12:37:20 +0200 Subject: [PATCH] Fix properties split on base64 encoded url content Css property with base64 encoded content contain a ';' and they were not managed by the property spliting function. Example of breaked input that works now: 'background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIUAAAAgCAYAA...);' --- src/CssToInlineStyles.php | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/CssToInlineStyles.php b/src/CssToInlineStyles.php index fe46355..b33cc79 100644 --- a/src/CssToInlineStyles.php +++ b/src/CssToInlineStyles.php @@ -207,8 +207,7 @@ public function convert($outputXHTML = false) $definedStyles = (string) $stylesAttribute->value; // split into properties - $definedProperties = (array) explode(';', $definedStyles); - + $definedProperties = $this->splitIntoProperties($definedStyles); // loop properties foreach ($definedProperties as $property) { // validate property @@ -275,7 +274,7 @@ public function convert($outputXHTML = false) if ($originalStyle != '') { $originalProperties = array(); - $originalStyles = (array) explode(';', $originalStyle); + $originalStyles = $this->splitIntoProperties($originalStyle); foreach ($originalStyles as $property) { // validate property @@ -305,7 +304,7 @@ public function convert($outputXHTML = false) $definedStyles = (string) $stylesAttribute->value; // split into properties - $definedProperties = (array) explode(';', $definedStyles); + $definedProperties = $this->splitIntoProperties($definedStyles); // loop properties foreach ($definedProperties as $property) { @@ -365,7 +364,7 @@ public function convert($outputXHTML = false) if ($this->stripOriginalStyleTags) { $this->stripOriginalStyleTags($xPath); } - + // should we output XHTML? if ($outputXHTML) { // set formating @@ -400,6 +399,28 @@ public function convert($outputXHTML = false) return $html; } + /** + * Split a style string into an array of properties. + * The returned array can contain empty strings. + * + * @param string $styles ex: 'color:blue;font-size:12px;' + * @return array an array of strings containing css property ex: array('color:blue','font-size:12px') + */ + private function splitIntoProperties($styles) { + $properties = (array) explode(';', $styles); + + for ($i = 0; $i < count($properties); $i++) { + // If next property begins with base64, + // Then the ';' was part of this property (and we should not have split on it). + if (isset($properties[$i + 1]) && strpos($properties[$i + 1], 'base64,') === 0) { + $properties[$i] .= ';' . $properties[$i + 1]; + $properties[$i + 1] = ''; + $i += 1; + } + } + return $properties; + } + /** * Get the encoding to use * @@ -506,7 +527,7 @@ private function processCSS() private function processCSSProperties($propertyString) { // split into chunks - $properties = (array) explode(';', $propertyString); + $properties = $this->splitIntoProperties($propertyString); // init var $pairs = array(); @@ -567,7 +588,7 @@ public function setCSS($css) * * @return void * @param string $encoding The encoding to use. - * + * * @deprecated Doesn't have any effect */ public function setEncoding($encoding)