Compare commits

...

1 Commits

Author SHA1 Message Date
Pierre Goiffon
bc841dd239 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

(cherry picked from commit 0aab80917a)
2019-03-04 14:59:38 +01:00
3 changed files with 58 additions and 24 deletions

View File

@@ -234,19 +234,28 @@ class EMail
$oDOMDoc = new DOMDocument(); $oDOMDoc = new DOMDocument();
$oDOMDoc->preserveWhitespace = true; $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 @$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); $oXPath = new DOMXPath($oDOMDoc);
$sXPath = "//img[@data-img-id]"; $sXPath = '//img[@'.InlineImage::DOM_ATTR_ID.']';
$oImagesList = $oXPath->query($sXPath); $oImagesList = $oXPath->query($sXPath);
if ($oImagesList->length != 0) if ($oImagesList->length != 0)
{ {
foreach($oImagesList as $oImg) 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 */); $oAttachment = MetaModel::GetObject('InlineImage', $iAttId, false, true /* Allow All Data */);
if ($oAttachment) 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'); $oDoc = $oAttachment->Get('contents');
$oSwiftImage = new Swift_Image($oDoc->GetData(), $oDoc->GetFileName(), $oDoc->GetMimeType()); $oSwiftImage = new Swift_Image($oDoc->GetData(), $oDoc->GetFileName(), $oDoc->GetMimeType());
$sCid = $this->m_oMessage->embed($oSwiftImage); $sCid = $this->m_oMessage->embed($oSwiftImage);

View File

@@ -348,7 +348,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
$this->CleanNode($oNode); $this->CleanNode($oNode);
if (($oNode instanceof DOMElement) && (strtolower($oNode->tagName) == 'img')) if (($oNode instanceof DOMElement) && (strtolower($oNode->tagName) == 'img'))
{ {
$this->ProcessImage($oNode); InlineImage::ProcessImageTag($oNode);
} }
} }
} }
@@ -359,24 +359,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) protected function CleanStyle($sStyle)
{ {
$aAllowedStyles = array(); $aAllowedStyles = array();

View File

@@ -27,6 +27,11 @@ define('INLINEIMAGE_DOWNLOAD_URL', 'pages/ajax.document.php?operation=download_i
class InlineImage extends DBObject 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() public static function Init()
{ {
$aParams = array $aParams = array
@@ -221,7 +226,8 @@ class InlineImage extends DBObject
$aNeedles = array(); $aNeedles = array();
$aReplacements = array(); $aReplacements = array();
// Find img tags with an attribute data-img-id // 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; $sUrl = utils::GetAbsoluteUrlAppRoot().INLINEIMAGE_DOWNLOAD_URL;
foreach($aMatches as $aImgInfo) foreach($aMatches as $aImgInfo)
@@ -243,6 +249,42 @@ class InlineImage extends DBObject
return $sHtml; 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 * Get the javascript fragment - to be added to "on document ready" - to adjust (on the fly) the width on Inline Images
*/ */