From f709e3d908e64775e6475a532cca16411ee2ed6c Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Mon, 14 Apr 2014 02:29:40 -0600 Subject: [PATCH] Abstract HTML signature image processing code Needed because drag/drop images is allowed in compose preview window --- imp/lib/Compose.php | 26 +++--- imp/lib/Compose/HtmlSignature.php | 101 ++++++++++++++++++++++++ imp/lib/Prefs/Special/HtmlSignature.php | 42 ++-------- imp/package.xml | 4 +- 4 files changed, 122 insertions(+), 51 deletions(-) create mode 100644 imp/lib/Compose/HtmlSignature.php diff --git a/imp/lib/Compose.php b/imp/lib/Compose.php index 512584326ed..bb133742ac8 100644 --- a/imp/lib/Compose.php +++ b/imp/lib/Compose.php @@ -44,9 +44,6 @@ class IMP_Compose implements ArrayAccess, Countable, IteratorAggregate /* Related part attribute name. */ const RELATED_ATTR = 'imp_related_attr'; - /* Signature data attribute name. */ - const HTMLSIG_ATTR = 'imp_htmlsig'; - /* The blockquote tag to use to indicate quoted text in HTML data. */ const HTML_BLOCKQUOTE = '
'; @@ -1496,11 +1493,16 @@ protected function _createMimeMessage( } if (!empty($options['html'])) { - $sig_dom = new Horde_Domhtml($html_sig, 'UTF-8'); - foreach ($sig_dom->getBody()->childNodes as $child) { - $node = $body_html->dom->importNode($child, true); - $node->setAttribute(self::HTMLSIG_ATTR, '1'); - $body_html_body->appendChild($node); + try { + $sig_ob = new IMP_Compose_HtmlSignature($html_sig); + } catch (IMP_Exception $e) { + throw new IMP_Compose_Exception($e); + } + + foreach ($sig_ob->dom->getBody()->childNodes as $child) { + $body_html_body->appendChild( + $body_html->dom->importNode($child, true) + ); } } } @@ -2630,8 +2632,7 @@ protected function _cleanHtmlOutput(Horde_Domhtml $html) /* Check for attempts to sneak data URL information into the * output. */ if (Horde_Url_Data::isData($src)) { - if ((strcasecmp($node->tagName, 'IMG') === 0) && - ($xpath->query('ancestor-or-self::node()[@' . self::HTMLSIG_ATTR . ']', $node)->length)) { + if (IMP_Compose_HtmlSignature::isSigImage($node, true)) { /* This is HTML signature image data. Convert to an * attachment. */ $sig_img = new Horde_Url_Data($src); @@ -2685,11 +2686,6 @@ protected function _cleanHtmlOutput(Horde_Domhtml $html) } } } - - /* Remove HTML sig identifiers. */ - foreach ($xpath->query('//*[@' . self::HTMLSIG_ATTR . ']') as $node) { - $node->removeAttribute(self::HTMLSIG_ATTR); - } } /** diff --git a/imp/lib/Compose/HtmlSignature.php b/imp/lib/Compose/HtmlSignature.php new file mode 100644 index 00000000000..a74155080aa --- /dev/null +++ b/imp/lib/Compose/HtmlSignature.php @@ -0,0 +1,101 @@ + + * @category Horde + * @copyright 2014 Horde LLC + * @license http://www.horde.org/licenses/gpl GPL + * @package IMP + */ +class IMP_Compose_HtmlSignature +{ + /** Signature data attribute name. */ + const HTMLSIG_ATTR = 'imp_htmlsig'; + + /** + * DOM object containing HTML signature data. + * + * @var Horde_Domhtml + */ + public $dom; + + /** + * Constructor. + * + * @param string $sig HTML signature data. + * + * @throws IMP_Exception + */ + public function __construct($sig) + { + global $conf, $injector; + + /* Scrub HTML. */ + $this->dom = $injector->getInstance('Horde_Core_Factory_TextFilter')->filter( + $sig, + 'Xss', + array( + 'charset' => 'UTF-8', + 'return_dom' => true, + 'strip_style_attributes' => false + ) + ); + + $img_limit = intval($conf['compose']['htmlsig_img_size']); + + $xpath = new DOMXPath($this->dom->dom); + foreach ($xpath->query('//*[@src]') as $node) { + $src = $node->getAttribute('src'); + + if (Horde_Url_Data::isData($src)) { + if (strcasecmp($node->tagName, 'IMG') === 0) { + $data_url = new Horde_Url_Data($src); + if ($img_limit && + ($img_limit -= strlen($data_url->data)) < 0) { + throw new IMP_Exception(_("The total size of your HTML signature image data has exceeded the maximum allowed.")); + } + + $node->setAttribute(self::HTMLSIG_ATTR, 1); + } else { + /* Don't allow any other non-image data URLs. */ + $node->removeAttribute('src'); + } + } + } + } + + /** + * Determine if node contains HTML signature image data. + * + * @param DOMNode $node The node to check. + * @param boolean $strip Strip attribute from the node? + * + * @return boolean True if node contains image data. + */ + static public function isSigImage(DOMNode $node, $strip = false) + { + if ((strcasecmp($node->tagName, 'IMG') === 0) && + $node->hasAttribute(self::HTMLSIG_ATTR)) { + if ($strip) { + $node->removeAttribute(self::HTMLSIG_ATTR); + } + return true; + } + + return false; + } + +} diff --git a/imp/lib/Prefs/Special/HtmlSignature.php b/imp/lib/Prefs/Special/HtmlSignature.php index 2429a2c8d8d..c1ed904d709 100644 --- a/imp/lib/Prefs/Special/HtmlSignature.php +++ b/imp/lib/Prefs/Special/HtmlSignature.php @@ -63,46 +63,18 @@ public function display(Horde_Core_Prefs_Ui $ui) */ public function update(Horde_Core_Prefs_Ui $ui) { - global $conf, $injector, $notification; + global $notification; - $filter = $injector->getInstance('Horde_Core_Factory_TextFilter'); - - /* Scrub HTML. */ - $html = $filter->filter( - $ui->vars->signature_html, - 'Xss', - array( - 'charset' => 'UTF-8', - 'return_dom' => true, - 'strip_style_attributes' => false - ) - ); - - if ($img_limit = intval($conf['compose']['htmlsig_img_size'])) { - $xpath = new DOMXPath($html->dom); - foreach ($xpath->query('//*[@src]') as $node) { - $src = $node->getAttribute('src'); - if (Horde_Url_Data::isData($src)) { - if (strcasecmp($node->tagName, 'IMG') === 0) { - $data_url = new Horde_Url_Data($src); - if (($img_limit -= strlen($data_url->data)) < 0) { - $notification->push( - _("The total size of your HTML signature image data has exceeded the maximum allowed."), - 'horde.error' - ); - return false; - } - } else { - /* Don't allow any other non-image data URLs. */ - $node->removeAttribute('src'); - } - } - } + try { + new IMP_Compose_HtmlSignature($ui->vars->signature_html); + } catch (IMP_Exception $e) { + $notification->push($e, 'horde.error'); + return false; } return $injector->getInstance('IMP_Identity')->setValue( 'signature_html', - $html->returnHtml(array('charset' => 'UTF-8')) + $ui->vars->signature_html ); } diff --git a/imp/package.xml b/imp/package.xml index bee8624dfe9..63f94124ac5 100644 --- a/imp/package.xml +++ b/imp/package.xml @@ -22,7 +22,7 @@ chuck@horde.org yes - 2014-03-23 + 2014-04-14 6.2.0 6.2.0 @@ -227,6 +227,7 @@ + @@ -1664,6 +1665,7 @@ +