Move image URL cleaning function to HTMLFilter #1787

This commit is contained in:
Kijin Sung 2021-09-11 19:47:04 +09:00
parent a02d5cb554
commit 1c28254902
3 changed files with 46 additions and 12 deletions

View file

@ -5,6 +5,7 @@ namespace Rhymix\Framework\Filters;
use Rhymix\Framework\Config;
use Rhymix\Framework\Security;
use Rhymix\Framework\Storage;
use Rhymix\Framework\URL;
/**
* The HTML filter class.
@ -115,6 +116,37 @@ class HTMLFilter
return $output;
}
/**
* Convert relative URLs to absolute URLs in HTML content.
*
* This is useful when sending content outside of the website,
* such as e-mail and RSS, where relative URLs might not mean the same.
*
* This method also removes attributes that don't mean anything
* when sent outside of the website, such as editor component names.
*
* This method DOES NOT check HTML content for XSS or other attacks.
*
* @param string $content
* @return string
*/
public static function fixRelativeUrls(string $content): string
{
$patterns = [
'!\b(?i:src)=(["\']?)(?:\./|' . preg_quote(\RX_BASEURL, '!') . '|)files/!',
'!\b(?:data-file-srl|editor_component|widget|id)="[^"]*"\s?!',
'!\b(?:class="zbxe_widget_output")\s?!',
];
$replacements = [
'src=$1' . URL::getCurrentDomainURL(\RX_BASEURL) . 'files/',
'',
'',
];
return preg_replace_callback('/<(img|video|audio|source)\b([^>]+)>/i', function($match) use($patterns, $replacements) {
return preg_replace($patterns, $replacements, $match[0]);
}, $content);
}
/**
* Get an instance of HTMLPurifier.
*

View file

@ -406,7 +406,7 @@ class Mail
if (strpos($this->content_type, 'html') !== false)
{
$content = preg_replace_callback('/<img([^>]+)>/i', array($this, 'convertImageURLs'), $content);
$content = Filters\HTMLFilter::fixRelativeUrls($content);
}
$this->message->setBody($content, $this->content_type);
@ -635,17 +635,7 @@ class Mail
*/
protected function convertImageURLs(array $matches)
{
$patterns = [
'!\b(?i:src)=(["\']?)(?:\./|' . preg_quote(\RX_BASEURL, '!') . '|)files/!',
'!\b(?:data-file-srl|editor_component|widget|id)="[^"]*"\s?!',
'!\b(?:class="zbxe_widget_output")\s?!',
];
$replacements = [
'src=$1' . URL::getCurrentDomainURL(\RX_BASEURL) . 'files/',
'',
'',
];
return preg_replace($patterns, $replacements, $matches[0]);
return Filters\HTMLFilter::fixRelativeUrls($matches[0]);
}
/**

View file

@ -241,4 +241,16 @@ class HTMLFilterTest extends \Codeception\TestCase\Test
$target = '<p><img src="foo.jpg" alt="foobar" /></p>';
$this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source));
}
public function testHTMLFilterFixMediaUrls()
{
$content = Rhymix\Framework\Filters\HTMLFilter::fixRelativeUrls('<img src="files/attach/foobar.jpg" alt="TEST" />');
$this->assertEquals('<img src="https://www.rhymix.org/rhymix/files/attach/foobar.jpg" alt="TEST" />', $content);
$content = Rhymix\Framework\Filters\HTMLFilter::fixRelativeUrls('<img src="./files/attach/foobar.jpg" editor_component="foobar" />');
$this->assertEquals('<img src="https://www.rhymix.org/rhymix/files/attach/foobar.jpg" />', $content);
$content = Rhymix\Framework\Filters\HTMLFilter::fixRelativeUrls('<img src="/rhymix/files/attach/foobar.jpg" id="foobar" data-file-srl="2345" />');
$this->assertEquals('<img src="https://www.rhymix.org/rhymix/files/attach/foobar.jpg" />', $content);
$content = Rhymix\Framework\Filters\HTMLFilter::fixRelativeUrls('<img src="//external.site/files/attach/foobar.jpg" alt="TEST" class="zbxe_widget_output" widget="baz" />');
$this->assertEquals('<img src="//external.site/files/attach/foobar.jpg" alt="TEST" />', $content);
}
}