mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°1921 Process InlineImage from another iTop as external images
* Notifications : do not embed InlineImage with wrong secret * HtmlSanitizer : remove data-img-* attributes if not the same iTop (using approot from Config) * move \HTMLDOMSanitizer::ProcessImage to \InlineImage::ProcessImageTag * data-img-* attributes name are now InlineImage class constants
This commit is contained in:
@@ -234,19 +234,28 @@ class EMail
|
||||
$oDOMDoc = new DOMDocument();
|
||||
$oDOMDoc->preserveWhitespace = true;
|
||||
@$oDOMDoc->loadHTML('<?xml encoding="UTF-8"?>'.$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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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('/<img ([^>]*)data-img-id="([0-9]+)"([^>]*)>/i', $sHtml, $aMatches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
|
||||
if (preg_match_all('/<img ([^>]*)'.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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user