1: <?php
2: /**
3: * Copyright 2014 Horde LLC (http://www.horde.org/)
4: *
5: * See the enclosed file COPYING for license information (GPL). If you
6: * did not receive this file, see http://www.horde.org/licenses/gpl.
7: *
8: * @category Horde
9: * @copyright 2014 Horde LLC
10: * @license http://www.horde.org/licenses/gpl GPL
11: * @package IMP
12: */
13:
14: /**
15: * Parse HTML signature data.
16: *
17: * @author Michael Slusarz <slusarz@horde.org>
18: * @category Horde
19: * @copyright 2014 Horde LLC
20: * @license http://www.horde.org/licenses/gpl GPL
21: * @package IMP
22: */
23: class IMP_Compose_HtmlSignature
24: {
25: /** Signature data attribute name. */
26: const HTMLSIG_ATTR = 'imp_htmlsig';
27:
28: /**
29: * DOM object containing HTML signature data.
30: *
31: * @var Horde_Domhtml
32: */
33: public $dom;
34:
35: /**
36: * Constructor.
37: *
38: * @param string $sig HTML signature data.
39: *
40: * @throws IMP_Exception
41: */
42: public function __construct($sig)
43: {
44: global $conf, $injector;
45:
46: /* Scrub HTML. */
47: $this->dom = $injector->getInstance('Horde_Core_Factory_TextFilter')->filter(
48: $sig,
49: 'Xss',
50: array(
51: 'charset' => 'UTF-8',
52: 'return_dom' => true,
53: 'strip_style_attributes' => false
54: )
55: );
56:
57: $img_limit = intval($conf['compose']['htmlsig_img_size']);
58:
59: $xpath = new DOMXPath($this->dom->dom);
60: foreach ($xpath->query('//*[@src]') as $node) {
61: $src = $node->getAttribute('src');
62:
63: if (Horde_Url_Data::isData($src)) {
64: if (strcasecmp($node->tagName, 'IMG') === 0) {
65: $data_url = new Horde_Url_Data($src);
66: if ($img_limit &&
67: ($img_limit -= strlen($data_url->data)) < 0) {
68: throw new IMP_Exception(_("The total size of your HTML signature image data has exceeded the maximum allowed."));
69: }
70:
71: $node->setAttribute(self::HTMLSIG_ATTR, 1);
72: } else {
73: /* Don't allow any other non-image data URLs. */
74: $node->removeAttribute('src');
75: }
76: }
77: }
78: }
79:
80: /**
81: * Determine if node contains HTML signature image data.
82: *
83: * @param DOMNode $node The node to check.
84: * @param boolean $strip Strip attribute from the node?
85: *
86: * @return boolean True if node contains image data.
87: */
88: public static function isSigImage(DOMNode $node, $strip = false)
89: {
90: if ((strcasecmp($node->tagName, 'IMG') === 0) &&
91: $node->hasAttribute(self::HTMLSIG_ATTR)) {
92: if ($strip) {
93: $node->removeAttribute(self::HTMLSIG_ATTR);
94: }
95: return true;
96: }
97:
98: return false;
99: }
100:
101: }
102: