mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-11-09 15:28:40 +00:00
Proper support for name attribute in <a> and <img>
Prior to this commit, the name attribute was unilaterally removed, except for Strict doctypes or a heavy TidyLevel, when it was converted to an id attribute. As name is actually permitted in both HTML 4.01 Strict and XHTML 1.0 Strict, although deprecated, the more sensible default behavior is to allow it unless TidyLevel is heavy. Our implementation is slightly stricter than the specs, as name attributes are treated as first class IDs, disallowing <a name="foo" id="foo"> or duplicate names. The former should be treated as a special case, but that will be a separate commit. Signed-off-by: Edward Z. Yang <edwardzyang@thewritingpot.com>
This commit is contained in:
parent
f8b47c64dd
commit
fd384129bf
3
NEWS
3
NEWS
@ -15,6 +15,9 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
! %Output.AttrSort for when you need your attributes in alphabetical order to
|
! %Output.AttrSort for when you need your attributes in alphabetical order to
|
||||||
deal with a bug in FCKEditor. Requested by frank farmer.
|
deal with a bug in FCKEditor. Requested by frank farmer.
|
||||||
! Enable HTML comments when %HTML.Trusted is on. Requested by Waldo Jaquith.
|
! Enable HTML comments when %HTML.Trusted is on. Requested by Waldo Jaquith.
|
||||||
|
! Proper support for name attribute. It is now allowed and equivalent to the id
|
||||||
|
attribute in a and img tags, and is only converted to id when %HTML.TidyLevel
|
||||||
|
is heavy (for all doctypes).
|
||||||
. Strategy_MakeWellFormed now operates in-place, saving memory and allowing
|
. Strategy_MakeWellFormed now operates in-place, saving memory and allowing
|
||||||
for more interesting filter-backtracking
|
for more interesting filter-backtracking
|
||||||
|
|
||||||
|
2
TODO
2
TODO
@ -14,7 +14,7 @@ afraid to cast your vote for the next feature to be implemented!
|
|||||||
- Investigate how early internal structures can be accessed; this would
|
- Investigate how early internal structures can be accessed; this would
|
||||||
prevent structures from being parsed and serialized multiple times.
|
prevent structures from being parsed and serialized multiple times.
|
||||||
- Built-in support for target="_blank" on all external links
|
- Built-in support for target="_blank" on all external links
|
||||||
- Gitify the repository
|
- Allow <a id="asdf" name="asdf'>
|
||||||
|
|
||||||
FUTURE VERSIONS
|
FUTURE VERSIONS
|
||||||
---------------
|
---------------
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<line>327</line>
|
<line>327</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<line>44</line>
|
<line>47</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="CSS.MaxImgLength">
|
<directive id="CSS.MaxImgLength">
|
||||||
@ -151,7 +151,7 @@
|
|||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.Trusted">
|
<directive id="HTML.Trusted">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>198</line>
|
<line>199</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
<file name="HTMLPurifier/Lexer.php">
|
||||||
<line>238</line>
|
<line>238</line>
|
||||||
@ -162,30 +162,33 @@
|
|||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||||
<line>34</line>
|
<line>34</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<directive id="HTML.AllowedModules">
|
<line>23</line>
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
|
||||||
<line>205</line>
|
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.CoreModules">
|
<directive id="HTML.AllowedModules">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>206</line>
|
<line>206</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
|
<directive id="HTML.CoreModules">
|
||||||
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
|
<line>207</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
<directive id="HTML.Proprietary">
|
<directive id="HTML.Proprietary">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>220</line>
|
<line>221</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.SafeObject">
|
<directive id="HTML.SafeObject">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>225</line>
|
<line>226</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.SafeEmbed">
|
<directive id="HTML.SafeEmbed">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>228</line>
|
<line>229</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Attr.IDBlacklist">
|
<directive id="Attr.IDBlacklist">
|
||||||
@ -366,7 +369,7 @@
|
|||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.EscapeInvalidTags">
|
<directive id="Core.EscapeInvalidTags">
|
||||||
<file name="HTMLPurifier/Strategy/MakeWellFormed.php">
|
<file name="HTMLPurifier/Strategy/MakeWellFormed.php">
|
||||||
<line>22</line>
|
<line>21</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<line>19</line>
|
<line>19</line>
|
||||||
@ -374,12 +377,12 @@
|
|||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.RemoveScriptContents">
|
<directive id="Core.RemoveScriptContents">
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<line>22</line>
|
<line>25</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.HiddenElements">
|
<directive id="Core.HiddenElements">
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<line>23</line>
|
<line>26</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.HostBlacklist">
|
<directive id="URI.HostBlacklist">
|
||||||
|
@ -141,6 +141,7 @@ require 'HTMLPurifier/HTMLModule/Hypertext.php';
|
|||||||
require 'HTMLPurifier/HTMLModule/Image.php';
|
require 'HTMLPurifier/HTMLModule/Image.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Legacy.php';
|
require 'HTMLPurifier/HTMLModule/Legacy.php';
|
||||||
require 'HTMLPurifier/HTMLModule/List.php';
|
require 'HTMLPurifier/HTMLModule/List.php';
|
||||||
|
require 'HTMLPurifier/HTMLModule/Name.php';
|
||||||
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Object.php';
|
require 'HTMLPurifier/HTMLModule/Object.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Presentation.php';
|
require 'HTMLPurifier/HTMLModule/Presentation.php';
|
||||||
@ -155,6 +156,7 @@ require 'HTMLPurifier/HTMLModule/Target.php';
|
|||||||
require 'HTMLPurifier/HTMLModule/Text.php';
|
require 'HTMLPurifier/HTMLModule/Text.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy.php';
|
require 'HTMLPurifier/HTMLModule/Tidy.php';
|
||||||
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||||
|
require 'HTMLPurifier/HTMLModule/Tidy/Name.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||||
|
@ -135,6 +135,7 @@ require_once $__dir . '/HTMLPurifier/HTMLModule/Hypertext.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
|
||||||
@ -149,6 +150,7 @@ require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Name.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||||
|
16
library/HTMLPurifier/HTMLModule/Name.php
Normal file
16
library/HTMLPurifier/HTMLModule/Name.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class HTMLPurifier_HTMLModule_Name extends HTMLPurifier_HTMLModule
|
||||||
|
{
|
||||||
|
|
||||||
|
public $name = 'Name';
|
||||||
|
|
||||||
|
public function setup($config) {
|
||||||
|
$elements = array('a', 'applet', 'form', 'frame', 'iframe', 'img', 'map');
|
||||||
|
foreach ($elements as $name) {
|
||||||
|
$element = $this->addBlankElement($name);
|
||||||
|
$element->attr['name'] = 'ID';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
23
library/HTMLPurifier/HTMLModule/Tidy/Name.php
Normal file
23
library/HTMLPurifier/HTMLModule/Tidy/Name.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name is deprecated, but allowed in strict doctypes, so onl
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_HTMLModule_Tidy_Name extends HTMLPurifier_HTMLModule_Tidy
|
||||||
|
{
|
||||||
|
public $name = 'Tidy_Name';
|
||||||
|
public $defaultLevel = 'heavy';
|
||||||
|
public function makeFixes() {
|
||||||
|
|
||||||
|
$r = array();
|
||||||
|
|
||||||
|
// @name for img, a -----------------------------------------------
|
||||||
|
// Technically, it's allowed even on strict, so we allow authors to use
|
||||||
|
// it. However, it's deprecated in future versions of XHTML.
|
||||||
|
$r['img@name'] =
|
||||||
|
$r['a@name'] = new HTMLPurifier_AttrTransform_Name();
|
||||||
|
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -103,10 +103,6 @@ class HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4 extends HTMLPurifier_HTMLModule
|
|||||||
// @hspace for img ------------------------------------------------
|
// @hspace for img ------------------------------------------------
|
||||||
$r['img@hspace'] = new HTMLPurifier_AttrTransform_ImgSpace('hspace');
|
$r['img@hspace'] = new HTMLPurifier_AttrTransform_ImgSpace('hspace');
|
||||||
|
|
||||||
// @name for img, a -----------------------------------------------
|
|
||||||
$r['img@name'] =
|
|
||||||
$r['a@name'] = new HTMLPurifier_AttrTransform_Name();
|
|
||||||
|
|
||||||
// @noshade for hr ------------------------------------------------
|
// @noshade for hr ------------------------------------------------
|
||||||
// this transformation is not precise but often good enough.
|
// this transformation is not precise but often good enough.
|
||||||
// different browsers use different styles to designate noshade
|
// different browsers use different styles to designate noshade
|
||||||
|
@ -63,7 +63,8 @@ class HTMLPurifier_HTMLModuleManager
|
|||||||
$common = array(
|
$common = array(
|
||||||
'CommonAttributes', 'Text', 'Hypertext', 'List',
|
'CommonAttributes', 'Text', 'Hypertext', 'List',
|
||||||
'Presentation', 'Edit', 'Bdo', 'Tables', 'Image',
|
'Presentation', 'Edit', 'Bdo', 'Tables', 'Image',
|
||||||
'StyleAttribute', 'Scripting', 'Object'
|
'StyleAttribute', 'Scripting', 'Object',
|
||||||
|
'Name' // technically legacy, but present in all the specs
|
||||||
);
|
);
|
||||||
$transitional = array('Legacy', 'Target');
|
$transitional = array('Legacy', 'Target');
|
||||||
$xml = array('XMLCommonAttributes');
|
$xml = array('XMLCommonAttributes');
|
||||||
@ -82,7 +83,7 @@ class HTMLPurifier_HTMLModuleManager
|
|||||||
$this->doctypes->register(
|
$this->doctypes->register(
|
||||||
'HTML 4.01 Strict', false,
|
'HTML 4.01 Strict', false,
|
||||||
array_merge($common, $non_xml),
|
array_merge($common, $non_xml),
|
||||||
array('Tidy_Strict', 'Tidy_Proprietary'),
|
array('Tidy_Strict', 'Tidy_Proprietary', 'Tidy_Name'),
|
||||||
array(),
|
array(),
|
||||||
'-//W3C//DTD HTML 4.01//EN',
|
'-//W3C//DTD HTML 4.01//EN',
|
||||||
'http://www.w3.org/TR/html4/strict.dtd'
|
'http://www.w3.org/TR/html4/strict.dtd'
|
||||||
@ -91,7 +92,7 @@ class HTMLPurifier_HTMLModuleManager
|
|||||||
$this->doctypes->register(
|
$this->doctypes->register(
|
||||||
'XHTML 1.0 Transitional', true,
|
'XHTML 1.0 Transitional', true,
|
||||||
array_merge($common, $transitional, $xml, $non_xml),
|
array_merge($common, $transitional, $xml, $non_xml),
|
||||||
array('Tidy_Transitional', 'Tidy_XHTML', 'Tidy_Proprietary'),
|
array('Tidy_Transitional', 'Tidy_XHTML', 'Tidy_Proprietary', 'Tidy_Name'),
|
||||||
array(),
|
array(),
|
||||||
'-//W3C//DTD XHTML 1.0 Transitional//EN',
|
'-//W3C//DTD XHTML 1.0 Transitional//EN',
|
||||||
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'
|
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'
|
||||||
@ -100,7 +101,7 @@ class HTMLPurifier_HTMLModuleManager
|
|||||||
$this->doctypes->register(
|
$this->doctypes->register(
|
||||||
'XHTML 1.0 Strict', true,
|
'XHTML 1.0 Strict', true,
|
||||||
array_merge($common, $xml, $non_xml),
|
array_merge($common, $xml, $non_xml),
|
||||||
array('Tidy_Strict', 'Tidy_XHTML', 'Tidy_Strict', 'Tidy_Proprietary'),
|
array('Tidy_Strict', 'Tidy_XHTML', 'Tidy_Strict', 'Tidy_Proprietary', 'Tidy_Name'),
|
||||||
array(),
|
array(),
|
||||||
'-//W3C//DTD XHTML 1.0 Strict//EN',
|
'-//W3C//DTD XHTML 1.0 Strict//EN',
|
||||||
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
|
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
|
||||||
@ -109,7 +110,7 @@ class HTMLPurifier_HTMLModuleManager
|
|||||||
$this->doctypes->register(
|
$this->doctypes->register(
|
||||||
'XHTML 1.1', true,
|
'XHTML 1.1', true,
|
||||||
array_merge($common, $xml, array('Ruby')),
|
array_merge($common, $xml, array('Ruby')),
|
||||||
array('Tidy_Strict', 'Tidy_XHTML', 'Tidy_Proprietary', 'Tidy_Strict'), // Tidy_XHTML1_1
|
array('Tidy_Strict', 'Tidy_XHTML', 'Tidy_Proprietary', 'Tidy_Strict', 'Tidy_Name'), // Tidy_XHTML1_1
|
||||||
array(),
|
array(),
|
||||||
'-//W3C//DTD XHTML 1.1//EN',
|
'-//W3C//DTD XHTML 1.1//EN',
|
||||||
'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'
|
'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'
|
||||||
@ -378,7 +379,11 @@ class HTMLPurifier_HTMLModuleManager
|
|||||||
|
|
||||||
$this->contentSets->generateChildDef($def, $module);
|
$this->contentSets->generateChildDef($def, $module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This can occur if there is a blank definition, but no base to
|
||||||
|
// mix it in with
|
||||||
|
if (!$def) return false;
|
||||||
|
|
||||||
// add information on required attributes
|
// add information on required attributes
|
||||||
foreach ($def->attr as $attr_name => $attr_def) {
|
foreach ($def->attr as $attr_name => $attr_def) {
|
||||||
if ($attr_def->required) {
|
if ($attr_def->required) {
|
||||||
|
@ -226,5 +226,11 @@ alert("<This is compatible with XHTML>");
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_name() {
|
||||||
|
$this->config->set('Attr', 'EnableID', true);
|
||||||
|
$this->config->set('HTML', 'Doctype', 'XHTML 1.0 Strict');
|
||||||
|
$this->assertPurification('<a name="asdf"></a>');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user