0
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2024-09-19 10:45:18 +00:00

Add AutoFormat.RemoveEmpty.Predicate, fixes #35.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
This commit is contained in:
Edward Z. Yang 2014-08-31 11:16:30 +01:00
parent b8704535a3
commit 39d3df1fd7
6 changed files with 53 additions and 5 deletions

5
NEWS
View File

@ -12,6 +12,11 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
4.7.0, unknown release date
# opacity is now considered a "tricky" CSS property rather than a
proprietary one.
! %AutoFormat.RemoveEmpty.Predicate for specifying exactly when
an element should be considered "empty" (maybe preserve if it
has attributes), and modify iframe support so that the iframe
is removed if it is missing a src attribute. Thanks meeva for
reporting.
- Don't truncate upon encountering </div> when using DOMLex. Thanks
Myrto Christina for finally convincing me to fix this.
- Update YouTube filter for new code.

View File

@ -481,6 +481,11 @@
<line>47</line>
</file>
</directive>
<directive id="AutoFormat.RemoveEmpty.Predicate">
<file name="HTMLPurifier/Injector/RemoveEmpty.php">
<line>48</line>
</file>
</directive>
<directive id="Core.AggressivelyFixLt">
<file name="HTMLPurifier/Lexer/DOMLex.php">
<line>54</line>

View File

@ -0,0 +1,14 @@
AutoFormat.RemoveEmpty.Predicate
TYPE: hash
VERSION: 4.7.0
DEFAULT: array('colgroup' => array(), 'th' => array(), 'td' => array(), 'iframe' => array('src'))
--DESCRIPTION--
<p>
Given that an element has no contents, it will be removed by default, unless
this predicate dictates otherwise. The predicate can either be an associative
map from tag name to list of attributes that must be present for the element
to be considered preserved: thus, the default always preserves <code>colgroup</code>,
<code>th</code> and <code>td</code>, and also <code>iframe</code> if it
has a <code>src</code>.
</p>
--# vim: et sw=4 sts=4

View File

@ -28,10 +28,10 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
private $removeNbspExceptions;
/**
* Cached contents of %AutoFormat.RemoveEmpty.Predicate
* @type array
* TODO: make me configurable
*/
private $_exclude = array('colgroup' => 1, 'th' => 1, 'td' => 1, 'iframe' => 1);
private $exclude;
/**
* @param HTMLPurifier_Config $config
@ -45,6 +45,7 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
$this->context = $context;
$this->removeNbsp = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp');
$this->removeNbspExceptions = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions');
$this->exclude = $config->get('AutoFormat.RemoveEmpty.Predicate');
$this->attrValidator = new HTMLPurifier_AttrValidator();
}
@ -75,11 +76,15 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
break;
}
if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
if (isset($this->_exclude[$token->name])) {
return;
}
$this->attrValidator->validateToken($token, $this->config, $this->context);
$token->armor['ValidateAttributes'] = true;
if (isset($this->exclude[$token->name])) {
$r = true;
foreach ($this->exclude[$token->name] as $elem) {
if (!isset($token->attr[$elem])) $r = false;
}
if ($r) return;
}
if (isset($token->attr['id']) || isset($token->attr['name'])) {
return;
}

View File

@ -91,6 +91,25 @@ class HTMLPurifier_Injector_RemoveEmptyTest extends HTMLPurifier_InjectorHarness
$this->assertResult('<b>&nbsp;</b>', "<b>\xC2\xA0</b>");
}
public function testRemoveIframe()
{
$this->config->set('HTML.SafeIframe', true);
$this->assertResult('<iframe></iframe>', '');
}
public function testNoRemoveIframe()
{
$this->config->set('HTML.SafeIframe', true);
$this->assertResult('<iframe src="http://google.com"></iframe>', '');
}
public function testRemoveDisallowedIframe()
{
$this->config->set('HTML.SafeIframe', true);
$this->config->set('URI.SafeIframeRegexp', '%^http://www.youtube.com/embed/%');
$this->assertResult('<iframe src="http://google.com"></iframe>', '');
}
}
// vim: et sw=4 sts=4