0
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2025-03-23 14:27:02 +00:00

Reword documentation to be clearer, and give warning on common user error.

Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
This commit is contained in:
Edward Z. Yang 2010-09-04 01:30:32 -04:00
parent e2c15f1c98
commit 479d793562
6 changed files with 43 additions and 11 deletions

2
NEWS
View File

@ -18,6 +18,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
by parser. Thanks zmonteca for reporting. by parser. Thanks zmonteca for reporting.
- Fix missing attributes bug when running on Mac Snow Leopard and APC. - Fix missing attributes bug when running on Mac Snow Leopard and APC.
Thanks sidepodcast for the fix. Thanks sidepodcast for the fix.
- Warn if an element is allowed, but an attribute it requires is
not allowed.
4.1.1, released 2010-05-31 4.1.1, released 2010-05-31
- Fix undefined index warnings in maintenance scripts. - Fix undefined index warnings in maintenance scripts.

View File

@ -5,11 +5,14 @@ DEFAULT: NULL
--DESCRIPTION-- --DESCRIPTION--
<p> <p>
This is a convenience directive that rolls the functionality of This is a preferred convenience directive that combines
%HTML.AllowedElements and %HTML.AllowedAttributes into one directive. %HTML.AllowedElements and %HTML.AllowedAttributes.
Specify elements and attributes that are allowed using: Specify elements and attributes that are allowed using:
<code>element1[attr1|attr2],element2...</code>. You can also use <code>element1[attr1|attr2],element2...</code>. For example,
newlines instead of commas to separate elements. if you would like to only allow paragraphs and links, specify
<code>a[href],p</code>. You can specify attributes that apply
to all elements using an asterisk, e.g. <code>*[lang]</code>.
You can also use newlines instead of commas to separate elements.
</p> </p>
<p> <p>
<strong>Warning</strong>: <strong>Warning</strong>:

View File

@ -4,12 +4,17 @@ VERSION: 1.3.0
DEFAULT: NULL DEFAULT: NULL
--DESCRIPTION-- --DESCRIPTION--
<p> <p>
If HTML Purifier's tag set is unsatisfactory for your needs, you If HTML Purifier's tag set is unsatisfactory for your needs, you can
can overload it with your own list of tags to allow. Note that this overload it with your own list of tags to allow. If you change
method is subtractive: it does its job by taking away from HTML Purifier this, you probably also want to change %HTML.AllowedAttributes; see
usual feature set, so you cannot add a tag that HTML Purifier never also %HTML.Allowed which lets you set allowed elements and
supported in the first place (like embed, form or head). If you attributes at the same time.
change this, you probably also want to change %HTML.AllowedAttributes. </p>
<p>
If you attempt to allow an element that HTML Purifier does not know
about, HTML Purifier will raise an error. You will need to manually
tell HTML Purifier about this element by using the
<a href="http://htmlpurifier.org/docs/enduser-customize.html">advanced customization features.</a>
</p> </p>
<p> <p>
<strong>Warning:</strong> If another directive conflicts with the <strong>Warning:</strong> If another directive conflicts with the

View File

@ -300,7 +300,12 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
unset($allowed_attributes_mutable[$key]); unset($allowed_attributes_mutable[$key]);
} }
} }
if ($delete) unset($this->info[$tag]->attr[$attr]); if ($delete) {
if ($this->info[$tag]->attr[$attr]->required) {
trigger_error("Required attribute '$attr' in element '$tag' was not allowed, which means '$tag' will not be allowed either", E_USER_WARNING);
}
unset($this->info[$tag]->attr[$attr]);
}
} }
} }
// emit errors // emit errors

View File

@ -122,17 +122,20 @@ a[href|title]
} }
function test_AllowedAttributes_global_preferredSyntax() { function test_AllowedAttributes_global_preferredSyntax() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', 'style'); $this->config->set('HTML.AllowedAttributes', 'style');
$this->assertPurification_AllowedAttributes_global_style(); $this->assertPurification_AllowedAttributes_global_style();
} }
function test_AllowedAttributes_global_verboseSyntax() { function test_AllowedAttributes_global_verboseSyntax() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', '*@style'); $this->config->set('HTML.AllowedAttributes', '*@style');
$this->assertPurification_AllowedAttributes_global_style(); $this->assertPurification_AllowedAttributes_global_style();
} }
function test_AllowedAttributes_global_discouragedSyntax() { function test_AllowedAttributes_global_discouragedSyntax() {
// Emit errors eventually // Emit errors eventually
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', '*.style'); $this->config->set('HTML.AllowedAttributes', '*.style');
$this->assertPurification_AllowedAttributes_global_style(); $this->assertPurification_AllowedAttributes_global_style();
} }
@ -144,16 +147,19 @@ a[href|title]
} }
function test_AllowedAttributes_local_preferredSyntax() { function test_AllowedAttributes_local_preferredSyntax() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', 'p@style'); $this->config->set('HTML.AllowedAttributes', 'p@style');
$this->assertPurification_AllowedAttributes_local_p_style(); $this->assertPurification_AllowedAttributes_local_p_style();
} }
function test_AllowedAttributes_local_discouragedSyntax() { function test_AllowedAttributes_local_discouragedSyntax() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', 'p.style'); $this->config->set('HTML.AllowedAttributes', 'p.style');
$this->assertPurification_AllowedAttributes_local_p_style(); $this->assertPurification_AllowedAttributes_local_p_style();
} }
function test_AllowedAttributes_multiple() { function test_AllowedAttributes_multiple() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', 'p@style,br@class,title'); $this->config->set('HTML.AllowedAttributes', 'p@style,br@class,title');
$this->assertPurification( $this->assertPurification(
'<p style="font-weight:bold;" class="foo" title="foo">Jelly</p><br style="clear:both;" class="foo" title="foo" />', '<p style="font-weight:bold;" class="foo" title="foo">Jelly</p><br style="clear:both;" class="foo" title="foo" />',
@ -162,29 +168,34 @@ a[href|title]
} }
function test_AllowedAttributes_local_invalidAttribute() { function test_AllowedAttributes_local_invalidAttribute() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', array('p@style', 'p@<foo>')); $this->config->set('HTML.AllowedAttributes', array('p@style', 'p@<foo>'));
$this->expectError(new PatternExpectation("/Attribute '&lt;foo&gt;' in element 'p' not supported/")); $this->expectError(new PatternExpectation("/Attribute '&lt;foo&gt;' in element 'p' not supported/"));
$this->assertPurification_AllowedAttributes_local_p_style(); $this->assertPurification_AllowedAttributes_local_p_style();
} }
function test_AllowedAttributes_global_invalidAttribute() { function test_AllowedAttributes_global_invalidAttribute() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', array('style', '<foo>')); $this->config->set('HTML.AllowedAttributes', array('style', '<foo>'));
$this->expectError(new PatternExpectation("/Global attribute '&lt;foo&gt;' is not supported in any elements/")); $this->expectError(new PatternExpectation("/Global attribute '&lt;foo&gt;' is not supported in any elements/"));
$this->assertPurification_AllowedAttributes_global_style(); $this->assertPurification_AllowedAttributes_global_style();
} }
function test_AllowedAttributes_local_invalidAttributeDueToMissingElement() { function test_AllowedAttributes_local_invalidAttributeDueToMissingElement() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', 'p.style,foo.style'); $this->config->set('HTML.AllowedAttributes', 'p.style,foo.style');
$this->expectError(new PatternExpectation("/Cannot allow attribute 'style' if element 'foo' is not allowed\/supported/")); $this->expectError(new PatternExpectation("/Cannot allow attribute 'style' if element 'foo' is not allowed\/supported/"));
$this->assertPurification_AllowedAttributes_local_p_style(); $this->assertPurification_AllowedAttributes_local_p_style();
} }
function test_AllowedAttributes_duplicate() { function test_AllowedAttributes_duplicate() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', 'p.style,p@style'); $this->config->set('HTML.AllowedAttributes', 'p.style,p@style');
$this->assertPurification_AllowedAttributes_local_p_style(); $this->assertPurification_AllowedAttributes_local_p_style();
} }
function test_AllowedAttributes_multipleErrors() { function test_AllowedAttributes_multipleErrors() {
$this->config->set('HTML.AllowedElements', array('p', 'br'));
$this->config->set('HTML.AllowedAttributes', 'p.style,foo.style,<foo>'); $this->config->set('HTML.AllowedAttributes', 'p.style,foo.style,<foo>');
$this->expectError(new PatternExpectation("/Cannot allow attribute 'style' if element 'foo' is not allowed\/supported/")); $this->expectError(new PatternExpectation("/Cannot allow attribute 'style' if element 'foo' is not allowed\/supported/"));
$this->expectError(new PatternExpectation("/Global attribute '&lt;foo&gt;' is not supported in any elements/")); $this->expectError(new PatternExpectation("/Global attribute '&lt;foo&gt;' is not supported in any elements/"));
@ -347,6 +358,12 @@ a[href|title]
); );
} }
function test_notAllowedRequiredAttributeError() {
$this->expectError("Required attribute 'src' in element 'img' was not allowed, which means 'img' will not be allowed either");
$this->config->set('HTML.Allowed', 'img[alt]');
$this->config->getHTMLDefinition();
}
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4