mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-11-09 15:28:40 +00:00
[3.0.0]
+ PHP4 reference/foreach cruft in Injector removed . Unit tests for Injector improved . Some todo stuff updated git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1462 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
parent
7ddd9d0afe
commit
b5546ff6f0
2
NEWS
2
NEWS
@ -15,7 +15,9 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
to it.
|
to it.
|
||||||
+ Visibility declarations added
|
+ Visibility declarations added
|
||||||
+ Constructor methods renamed to __construct()
|
+ Constructor methods renamed to __construct()
|
||||||
|
+ PHP4 reference/foreach cruft removed (in progress)
|
||||||
! CSS properties are no case-insensitive
|
! CSS properties are no case-insensitive
|
||||||
|
. Unit tests for Injector improved
|
||||||
|
|
||||||
2.1.3, released 2007-11-05
|
2.1.3, released 2007-11-05
|
||||||
! tests/multitest.php allows you to test multiple versions by running
|
! tests/multitest.php allows you to test multiple versions by running
|
||||||
|
3
TODO
3
TODO
@ -11,6 +11,9 @@ If no interest is expressed for a feature that may required a considerable
|
|||||||
amount of effort to implement, it may get endlessly delayed. Do not be
|
amount of effort to implement, it may get endlessly delayed. Do not be
|
||||||
afraid to cast your vote for the next feature to be implemented!
|
afraid to cast your vote for the next feature to be implemented!
|
||||||
|
|
||||||
|
3.0 release [Go PHP5!]
|
||||||
|
- Convert all &$context calls to $context, as PHP5 passes objects by value
|
||||||
|
|
||||||
3.1 release [Error'ed]
|
3.1 release [Error'ed]
|
||||||
# Error logging for filtering/cleanup procedures
|
# Error logging for filtering/cleanup procedures
|
||||||
- XSS-attempt detection
|
- XSS-attempt detection
|
||||||
|
@ -134,6 +134,7 @@ class HTMLPurifier
|
|||||||
*/
|
*/
|
||||||
public function purify($html, $config = null) {
|
public function purify($html, $config = null) {
|
||||||
|
|
||||||
|
// todo: make the config merge in, instead of replace
|
||||||
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
|
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
|
||||||
|
|
||||||
// implementation is partially environment dependant, partially
|
// implementation is partially environment dependant, partially
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* @todo Allow injectors to request a re-run on their output. This
|
* @todo Allow injectors to request a re-run on their output. This
|
||||||
* would help if an operation is recursive.
|
* would help if an operation is recursive.
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_Injector
|
abstract class HTMLPurifier_Injector
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +39,7 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
$result = array();
|
$result = array();
|
||||||
$generator = new HTMLPurifier_Generator();
|
$generator = new HTMLPurifier_Generator();
|
||||||
$escape_invalid_tags = $config->get('Core', 'EscapeInvalidTags');
|
$escape_invalid_tags = $config->get('Core', 'EscapeInvalidTags');
|
||||||
$e =& $context->get('ErrorCollector', true);
|
$e = $context->get('ErrorCollector', true);
|
||||||
|
|
||||||
// member variables
|
// member variables
|
||||||
$this->currentNesting = array();
|
$this->currentNesting = array();
|
||||||
@ -49,8 +49,8 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
|
|
||||||
// context variables
|
// context variables
|
||||||
$context->register('CurrentNesting', $this->currentNesting);
|
$context->register('CurrentNesting', $this->currentNesting);
|
||||||
$context->register('InputIndex', $this->inputIndex);
|
$context->register('InputIndex', $this->inputIndex);
|
||||||
$context->register('InputTokens', $tokens);
|
$context->register('InputTokens', $tokens);
|
||||||
|
|
||||||
// -- begin INJECTOR --
|
// -- begin INJECTOR --
|
||||||
|
|
||||||
@ -81,23 +81,22 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
|
|
||||||
// give the injectors references to the definition and context
|
// give the injectors references to the definition and context
|
||||||
// variables for performance reasons
|
// variables for performance reasons
|
||||||
foreach ($this->injectors as $i => $x) {
|
foreach ($this->injectors as $i => $injector) {
|
||||||
$error = $this->injectors[$i]->prepare($config, $context);
|
$error = $injector->prepare($config, $context);
|
||||||
if (!$error) continue;
|
if (!$error) continue;
|
||||||
list($injector) = array_splice($this->injectors, $i, 1);
|
array_splice($this->injectors, $i, 1); // rm the injector
|
||||||
$name = $injector->name;
|
trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING);
|
||||||
trigger_error("Cannot enable $name injector because $error is not allowed", E_USER_WARNING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// warning: most foreach loops follow the convention $i => $x.
|
// warning: most foreach loops follow the convention $i => $injector.
|
||||||
// be sure, for PHP4 compatibility, to only perform write operations
|
// Don't define these as loop-wide variables, please!
|
||||||
// directly referencing the object using $i: $x is only safe for reads
|
|
||||||
|
|
||||||
// -- end INJECTOR --
|
// -- end INJECTOR --
|
||||||
|
|
||||||
$token = false;
|
$token = false;
|
||||||
$context->register('CurrentToken', $token);
|
$context->register('CurrentToken', $token);
|
||||||
|
|
||||||
|
// isset is in loop because $tokens size changes during loop exec
|
||||||
for ($this->inputIndex = 0; isset($tokens[$this->inputIndex]); $this->inputIndex++) {
|
for ($this->inputIndex = 0; isset($tokens[$this->inputIndex]); $this->inputIndex++) {
|
||||||
|
|
||||||
// if all goes well, this token will be passed through unharmed
|
// if all goes well, this token will be passed through unharmed
|
||||||
@ -105,16 +104,16 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
|
|
||||||
//printTokens($tokens, $this->inputIndex);
|
//printTokens($tokens, $this->inputIndex);
|
||||||
|
|
||||||
foreach ($this->injectors as $i => $x) {
|
foreach ($this->injectors as $injector) {
|
||||||
if ($x->skip > 0) $this->injectors[$i]->skip--;
|
if ($injector->skip > 0) $injector->skip--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// quick-check: if it's not a tag, no need to process
|
// quick-check: if it's not a tag, no need to process
|
||||||
if (empty( $token->is_tag )) {
|
if (empty( $token->is_tag )) {
|
||||||
if ($token->type === 'text') {
|
if ($token->type === 'text') {
|
||||||
// injector handler code; duplicated for performance reasons
|
// injector handler code; duplicated for performance reasons
|
||||||
foreach ($this->injectors as $i => $x) {
|
foreach ($this->injectors as $i => $injector) {
|
||||||
if (!$x->skip) $this->injectors[$i]->handleText($token);
|
if (!$injector->skip) $injector->handleText($token);
|
||||||
if (is_array($token)) {
|
if (is_array($token)) {
|
||||||
$this->currentInjector = $i;
|
$this->currentInjector = $i;
|
||||||
break;
|
break;
|
||||||
@ -171,8 +170,8 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
|
|
||||||
// injector handler code; duplicated for performance reasons
|
// injector handler code; duplicated for performance reasons
|
||||||
if ($ok) {
|
if ($ok) {
|
||||||
foreach ($this->injectors as $i => $x) {
|
foreach ($this->injectors as $i => $injector) {
|
||||||
if (!$x->skip) $this->injectors[$i]->handleElement($token);
|
if (!$injector->skip) $injector->handleElement($token);
|
||||||
if (is_array($token)) {
|
if (is_array($token)) {
|
||||||
$this->currentInjector = $i;
|
$this->currentInjector = $i;
|
||||||
break;
|
break;
|
||||||
@ -202,8 +201,8 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
$current_parent = array_pop($this->currentNesting);
|
$current_parent = array_pop($this->currentNesting);
|
||||||
if ($current_parent->name == $token->name) {
|
if ($current_parent->name == $token->name) {
|
||||||
$result[] = $token;
|
$result[] = $token;
|
||||||
foreach ($this->injectors as $i => $x) {
|
foreach ($this->injectors as $i => $injector) {
|
||||||
$this->injectors[$i]->notifyEnd($token);
|
$injector->notifyEnd($token);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -242,12 +241,13 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
// okay, we found it, close all the skipped tags
|
// okay, we found it, close all the skipped tags
|
||||||
// note that skipped tags contains the element we need closed
|
// note that skipped tags contains the element we need closed
|
||||||
for ($i = count($skipped_tags) - 1; $i >= 0; $i--) {
|
for ($i = count($skipped_tags) - 1; $i >= 0; $i--) {
|
||||||
|
// please don't redefine $i!
|
||||||
if ($i && $e && !isset($skipped_tags[$i]->armor['MakeWellFormed_TagClosedError'])) {
|
if ($i && $e && !isset($skipped_tags[$i]->armor['MakeWellFormed_TagClosedError'])) {
|
||||||
$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$i]);
|
$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$i]);
|
||||||
}
|
}
|
||||||
$result[] = $new_token = new HTMLPurifier_Token_End($skipped_tags[$i]->name);
|
$result[] = $new_token = new HTMLPurifier_Token_End($skipped_tags[$i]->name);
|
||||||
foreach ($this->injectors as $j => $x) { // $j, not $i!!!
|
foreach ($this->injectors as $injector) {
|
||||||
$this->injectors[$j]->notifyEnd($new_token);
|
$injector->notifyEnd($new_token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,12 +263,13 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
// not using $skipped_tags since it would invariably be all of them
|
// not using $skipped_tags since it would invariably be all of them
|
||||||
if (!empty($this->currentNesting)) {
|
if (!empty($this->currentNesting)) {
|
||||||
for ($i = count($this->currentNesting) - 1; $i >= 0; $i--) {
|
for ($i = count($this->currentNesting) - 1; $i >= 0; $i--) {
|
||||||
|
// please don't redefine $i!
|
||||||
if ($e && !isset($this->currentNesting[$i]->armor['MakeWellFormed_TagClosedError'])) {
|
if ($e && !isset($this->currentNesting[$i]->armor['MakeWellFormed_TagClosedError'])) {
|
||||||
$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $this->currentNesting[$i]);
|
$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $this->currentNesting[$i]);
|
||||||
}
|
}
|
||||||
$result[] = $new_token = new HTMLPurifier_Token_End($this->currentNesting[$i]->name);
|
$result[] = $new_token = new HTMLPurifier_Token_End($this->currentNesting[$i]->name);
|
||||||
foreach ($this->injectors as $j => $x) { // $j, not $i!!!
|
foreach ($this->injectors as $injector) {
|
||||||
$this->injectors[$j]->notifyEnd($new_token);
|
$injector->notifyEnd($new_token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,19 @@ class HTMLPurifier_Strategy_MakeWellFormed_InjectorTest extends HTMLPurifier_Str
|
|||||||
$this->assertResult('<i><b>asdf</b>', '<i><b>asdf</b></i>');
|
$this->assertResult('<i><b>asdf</b>', '<i><b>asdf</b></i>');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testErrorRequiredElementNotAllowed() {
|
||||||
|
$this->config->set('HTML', 'Allowed', '');
|
||||||
|
$this->expectError('Cannot enable AutoParagraph injector because p is not allowed');
|
||||||
|
$this->expectError('Cannot enable Linkify injector because a is not allowed');
|
||||||
|
$this->assertResult('Foobar');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testErrorRequiredAttributeNotAllowed() {
|
||||||
|
$this->config->set('HTML', 'Allowed', 'a,p');
|
||||||
|
$this->expectError('Cannot enable Linkify injector because a.href is not allowed');
|
||||||
|
$this->assertResult('<p>http://example.com</p>');
|
||||||
|
}
|
||||||
|
|
||||||
function testOnlyAutoParagraph() {
|
function testOnlyAutoParagraph() {
|
||||||
$this->assertResult(
|
$this->assertResult(
|
||||||
'Foobar',
|
'Foobar',
|
||||||
|
Loading…
Reference in New Issue
Block a user