diff --git a/core/email.class.inc.php b/core/email.class.inc.php
index 3f6616f71..b8fd2a2ec 100644
--- a/core/email.class.inc.php
+++ b/core/email.class.inc.php
@@ -234,19 +234,28 @@ class EMail
$oDOMDoc = new DOMDocument();
$oDOMDoc->preserveWhitespace = true;
@$oDOMDoc->loadHTML(''.$this->m_aData['body']['body']); // For loading HTML chunks where the character set is not specified
-
+
$oXPath = new DOMXPath($oDOMDoc);
- $sXPath = "//img[@data-img-id]";
+ $sXPath = '//img[@'.InlineImage::DOM_ATTR_ID.']';
$oImagesList = $oXPath->query($sXPath);
-
+
if ($oImagesList->length != 0)
{
foreach($oImagesList as $oImg)
{
- $iAttId = $oImg->getAttribute('data-img-id');
+ $iAttId = $oImg->getAttribute(InlineImage::DOM_ATTR_ID);
$oAttachment = MetaModel::GetObject('InlineImage', $iAttId, false, true /* Allow All Data */);
if ($oAttachment)
{
+ $sImageSecret = $oImg->getAttribute('data-img-secret');
+ $sAttachmentSecret = $oAttachment->Get('secret');
+ if ($sImageSecret !== $sAttachmentSecret)
+ {
+ // @see N°1921
+ // If copying from another iTop we could get an IMG pointing to an InlineImage with wrong secret
+ continue;
+ }
+
$oDoc = $oAttachment->Get('contents');
$oSwiftImage = new Swift_Image($oDoc->GetData(), $oDoc->GetFileName(), $oDoc->GetMimeType());
$sCid = $this->m_oMessage->embed($oSwiftImage);
diff --git a/core/htmlsanitizer.class.inc.php b/core/htmlsanitizer.class.inc.php
index cbb5c8804..7746b797a 100644
--- a/core/htmlsanitizer.class.inc.php
+++ b/core/htmlsanitizer.class.inc.php
@@ -346,7 +346,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
$this->CleanNode($oNode);
if (($oNode instanceof DOMElement) && (strtolower($oNode->tagName) == 'img'))
{
- $this->ProcessImage($oNode);
+ InlineImage::ProcessImageTag($oNode);
}
}
}
@@ -357,24 +357,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
}
}
}
-
- /**
- * Add an extra attribute data-img-id for images which are based on an actual InlineImage
- * so that we can later reconstruct the full "src" URL when needed
- * @param DOMNode $oElement
- */
- protected function ProcessImage(DOMNode $oElement)
- {
- $sSrc = $oElement->getAttribute('src');
- $sDownloadUrl = str_replace(array('.', '?'), array('\.', '\?'), INLINEIMAGE_DOWNLOAD_URL); // Escape . and ?
- $sUrlPattern = '|'.$sDownloadUrl.'([0-9]+)&s=([0-9a-f]+)|';
- if (preg_match($sUrlPattern, $sSrc, $aMatches))
- {
- $oElement->setAttribute('data-img-id', $aMatches[1]);
- $oElement->setAttribute('data-img-secret', $aMatches[2]);
- }
- }
-
+
protected function CleanStyle($sStyle)
{
$aAllowedStyles = array();
diff --git a/core/inlineimage.class.inc.php b/core/inlineimage.class.inc.php
index 690616ca6..5fd242de4 100644
--- a/core/inlineimage.class.inc.php
+++ b/core/inlineimage.class.inc.php
@@ -27,6 +27,11 @@ define('INLINEIMAGE_DOWNLOAD_URL', 'pages/ajax.document.php?operation=download_i
class InlineImage extends DBObject
{
+ /** @var string attribute to be added to IMG tags to contain ID */
+ const DOM_ATTR_ID = 'data-img-id';
+ /** @var string attribute to be added to IMG tags to contain secret */
+ const DOM_ATTR_SECRET = 'data-img-secret';
+
public static function Init()
{
$aParams = array
@@ -208,7 +213,8 @@ class InlineImage extends DBObject
$aNeedles = array();
$aReplacements = array();
// Find img tags with an attribute data-img-id
- if (preg_match_all('/
]*)data-img-id="([0-9]+)"([^>]*)>/i', $sHtml, $aMatches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
+ if (preg_match_all('/
]*)'.self::DOM_ATTR_ID.'="([0-9]+)"([^>]*)>/i',
+ $sHtml, $aMatches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
{
$sUrl = utils::GetAbsoluteUrlAppRoot().INLINEIMAGE_DOWNLOAD_URL;
foreach($aMatches as $aImgInfo)
@@ -230,6 +236,42 @@ class InlineImage extends DBObject
return $sHtml;
}
+ /**
+ * Add an extra attribute data-img-id for images which are based on an actual InlineImage
+ * so that we can later reconstruct the full "src" URL when needed
+ *
+ * @param \DOMElement $oElement
+ */
+ public static function ProcessImageTag(DOMElement $oElement)
+ {
+ $sSrc = $oElement->getAttribute('src');
+ $sDownloadUrl = str_replace(array('.', '?'), array('\.', '\?'), INLINEIMAGE_DOWNLOAD_URL); // Escape . and ?
+ $sUrlPattern = '|'.$sDownloadUrl.'([0-9]+)&s=([0-9a-f]+)|';
+ $bIsInlineImage = preg_match($sUrlPattern, $sSrc, $aMatches);
+ if (!$bIsInlineImage)
+ {
+ return;
+ }
+ $iInlineImageId = $aMatches[1];
+ $sInlineIMageSecret = $aMatches[2];
+
+ $sAppRoot = utils::GetAbsoluteUrlAppRoot();
+ $sAppRootPattern = '/^'.preg_quote($sAppRoot, '/').'/';
+ $bIsSameItop = preg_match($sAppRootPattern, $sSrc);
+ if (!$bIsSameItop)
+ {
+ // @see N°1921
+ // image from another iTop should be treated as external images
+ $oElement->removeAttribute(self::DOM_ATTR_ID);
+ $oElement->removeAttribute(self::DOM_ATTR_SECRET);
+
+ return;
+ }
+
+ $oElement->setAttribute(self::DOM_ATTR_ID, $iInlineImageId);
+ $oElement->setAttribute(self::DOM_ATTR_SECRET, $sInlineIMageSecret);
+ }
+
/**
* Get the javascript fragment - to be added to "on document ready" - to adjust (on the fly) the width on Inline Images
*/