0
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2024-12-23 00:41:52 +00:00

[3.1.0] Deprecate addFilter; set up Filter namespace

- Added EXTERNAL dependency config-schema value
- Fix safe bug in Printer_HTMLDefinition
- Fixed broken smoketests

git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1669 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
Edward Z. Yang 2008-04-22 06:40:04 +00:00
parent e616f07739
commit e1876c18ad
26 changed files with 193 additions and 71 deletions

3
NEWS
View File

@ -26,6 +26,9 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
# HTMLPurifier_Config will now throw E_USER_NOTICE when you use a directive # HTMLPurifier_Config will now throw E_USER_NOTICE when you use a directive
alias; to get rid of these errors just modify your configuration to use alias; to get rid of these errors just modify your configuration to use
the new directive name. the new directive name.
# HTMLPurifier->addFilter is deprecated; built-in filters can now be
enabled using %Filter.$filter_name or by setting your own filters using
%Filter.Custom
# Directive-level safety properties superceded in favor of module-level # Directive-level safety properties superceded in favor of module-level
safety. Internal method HTMLModule->addElement() has changed, although safety. Internal method HTMLModule->addElement() has changed, although
the externally visible HTMLDefinition->addElement has *not* changed. the externally visible HTMLDefinition->addElement has *not* changed.

1
TODO
View File

@ -22,7 +22,6 @@ DOCUMENTATION
- Update French translation of README - Update French translation of README
IMPORTANT FEATURES IMPORTANT FEATURES
- Get everything into configuration objects (filters, I'm looking at you)
- Factor out command line parser into its own class, and unit test it - Factor out command line parser into its own class, and unit test it
- Figure out autoload and PEAR - Figure out autoload and PEAR

View File

@ -216,5 +216,18 @@
<td><pre><xsl:value-of select="." xml:space="preserve" /></pre></td> <td><pre><xsl:value-of select="." xml:space="preserve" /></pre></td>
</tr> </tr>
</xsl:template> </xsl:template>
<xsl:template match="constraints/external">
<tr>
<th>External deps</th>
<td>
<ul>
<xsl:apply-templates />
</ul>
</td>
</tr>
</xsl:template>
<xsl:template match="constraints/external/project">
<xsl:value-of select="." />
</xsl:template>
</xsl:stylesheet> </xsl:stylesheet>

View File

@ -2,7 +2,7 @@
<usage> <usage>
<directive id="Core.CollectErrors"> <directive id="Core.CollectErrors">
<file name="HTMLPurifier.php"> <file name="HTMLPurifier.php">
<line>130</line> <line>131</line>
</file> </file>
<file name="HTMLPurifier/Lexer.php"> <file name="HTMLPurifier/Lexer.php">
<line>93</line> <line>93</line>
@ -280,14 +280,19 @@
<line>91</line> <line>91</line>
</file> </file>
</directive> </directive>
<directive id="Filter.ExtractStyleBlocksScope"> <directive id="FilterParam.ExtractStyleBlocksTidyImpl">
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php"> <file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
<line>69</line> <line>41</line>
</file> </file>
</directive> </directive>
<directive id="Filter.ExtractStyleBlocksEscaping"> <directive id="FilterParam.ExtractStyleBlocksScope">
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php"> <file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
<line>127</line> <line>65</line>
</file>
</directive>
<directive id="FilterParam.ExtractStyleBlocksEscaping">
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
<line>123</line>
</file> </file>
</directive> </directive>
<directive id="HTML.TidyLevel"> <directive id="HTML.TidyLevel">

View File

@ -133,6 +133,14 @@ Test.Example</pre>
different, although they should offer the same functionality. different, although they should offer the same functionality.
If they are identical, use an alias instead.</td> If they are identical, use an alias instead.</td>
</tr> </tr>
<tr>
<td>EXTERNAL</td>
<td>CSSTidy</td>
<td><em>Not shown</em>. Indicates if there is an external library
the user will need to download and install to use this configuration
directive. As of right now, this is merely a Google-able name; future
versions may also provide links and instructions.</td>
</tr>
</tbody> </tbody>
</table> </table>

View File

@ -62,8 +62,8 @@ class HTMLPurifier
/** Global configuration object */ /** Global configuration object */
public $config; public $config;
/** Array of HTMLPurifier_Filter objects to run on HTML */ /** Array of extra HTMLPurifier_Filter objects to run on HTML, for backwards compatibility */
public $filters = array(); private $filters = array();
/** Single instance of HTML Purifier */ /** Single instance of HTML Purifier */
private static $instance; private static $instance;
@ -98,6 +98,7 @@ class HTMLPurifier
* @param $filter HTMLPurifier_Filter object * @param $filter HTMLPurifier_Filter object
*/ */
public function addFilter($filter) { public function addFilter($filter) {
trigger_error('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom', E_USER_WARNING);
$this->filters[] = $filter; $this->filters[] = $filter;
} }
@ -144,8 +145,25 @@ class HTMLPurifier
$html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context); $html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context);
for ($i = 0, $size = count($this->filters); $i < $size; $i++) { // setup filters
$html = $this->filters[$i]->preFilter($html, $config, $context); $filter_flags = $config->getBatch('Filter');
$custom_filters = $filter_flags['Custom'];
unset($filter_flags['Custom']);
$filters = array();
foreach ($filter_flags as $filter => $flag) {
if (!$flag) continue;
$class = "HTMLPurifier_Filter_$filter";
$filters[] = new $class;
}
foreach ($custom_filters as $filter) {
// maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat
$filters[] = $filter;
}
$filters = array_merge($filters, $this->filters);
// maybe prepare(), but later
for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) {
$html = $filters[$i]->preFilter($html, $config, $context);
} }
// purified HTML // purified HTML
@ -163,8 +181,8 @@ class HTMLPurifier
$config, $context $config, $context
); );
for ($i = $size - 1; $i >= 0; $i--) { for ($i = $filter_size - 1; $i >= 0; $i--) {
$html = $this->filters[$i]->postFilter($html, $config, $context); $html = $filters[$i]->postFilter($html, $config, $context);
} }
$html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context); $html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context);

View File

@ -80,6 +80,11 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
} }
$this->writeElement('default', $this->export($directive->default)); $this->writeElement('default', $this->export($directive->default));
$this->writeAttribute('xml:space', 'preserve'); $this->writeAttribute('xml:space', 'preserve');
if ($directive->external) {
$this->startElement('external');
foreach ($directive->external as $project) $this->writeElement('project', $project);
$this->endElement();
}
$this->endElement(); // constraints $this->endElement(); // constraints
if ($directive->deprecatedVersion) { if ($directive->deprecatedVersion) {

View File

@ -67,5 +67,9 @@ class HTMLPurifier_ConfigSchema_Interchange_Directive
*/ */
public $deprecatedVersion; public $deprecatedVersion;
/**
* List of external projects this directive depends on, e.g. array('CSSTidy').
*/
public $external = array();
} }

View File

@ -120,6 +120,10 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
$directive->deprecatedVersion = $hash->offsetGet('DEPRECATED-VERSION'); $directive->deprecatedVersion = $hash->offsetGet('DEPRECATED-VERSION');
} }
if (isset($hash['EXTERNAL'])) {
$directive->external = preg_split('/\s*,\s*/', trim($hash->offsetGet('EXTERNAL')));
}
$interchange->addDirective($directive); $interchange->addDirective($directive);
} }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
Filter.Custom
TYPE: list
VERSION: 3.1.0
DEFAULT: array()
--DESCRIPTION--
<p>
This directive can be used to add custom filters; it is nearly the
equivalent of the now deprecated <code>HTMLPurifier-&gt;addFilter()</code>
method. Specify an array of concrete implementations.
</p>

View File

@ -0,0 +1,23 @@
Filter.ExtractStyleBlocks
TYPE: bool
VERSION: 3.1.0
DEFAULT: false
EXTERNAL: CSSTidy
--DESCRIPTION--
<p>
This directive turns on the style block extraction filter, which removes
<code>style</code> blocks from input HTML, cleans them up with CSSTidy,
and places them in the <code>StyleBlocks</code> context variable, for further
use by you, usually to be placed in an external stylesheet, or a
<code>style</code> block in the <code>head</code> of your document.
</p>
<p>
Sample usage:
</p>
<pre><![CDATA[$config = HTMLPurifier_Config::createDefault();
$config->set('Filter', 'ExtractStyleBlocks', true);
$purifier = new HTMLPurifier($config);
$styles = $purifier->context->get('StyleBlocks');
foreach ($styles as $style) {
echo '<style type="text/css">' . $style . "</style>\n";
}]]></pre>

View File

@ -0,0 +1,10 @@
Filter.YouTube
TYPE: bool
VERSION: 3.1.0
DEFAULT: false
--DESCRIPTION--
<p>
This directive enables YouTube video embedding in HTML Purifier. Check
<a href="http://htmlpurifier.org/docs/enduser-youtube.html">this document
on embedding videos</a> for more information on what this filter does.
</p>

View File

@ -1,2 +1,2 @@
Filter Filter
DESCRIPTION: Configuration for filters DESCRIPTION: Directives for turning filters on and off, or specifying custom filters.

View File

@ -1,7 +1,8 @@
Filter.ExtractStyleBlocksEscaping FilterParam.ExtractStyleBlocksEscaping
TYPE: bool TYPE: bool
VERSION: 3.0.0 VERSION: 3.0.0
DEFAULT: true DEFAULT: true
ALIASES: Filter.ExtractStyleBlocksEscaping
--DESCRIPTION-- --DESCRIPTION--
<p> <p>

View File

@ -1,7 +1,8 @@
Filter.ExtractStyleBlocksScope FilterParam.ExtractStyleBlocksScope
TYPE: string/null TYPE: string/null
VERSION: 3.0.0 VERSION: 3.0.0
DEFAULT: NULL DEFAULT: NULL
ALIASES: Filter.ExtractStyleBlocksScope
--DESCRIPTION-- --DESCRIPTION--
<p> <p>

View File

@ -0,0 +1,14 @@
FilterParam.ExtractStyleBlocksTidyImpl
TYPE: mixed/null
VERSION: 3.1.0
DEFAULT: NULL
--DESCRIPTION--
<p>
If left NULL, HTML Purifier will attempt to instantiate a <code>csstidy</code>
class to use for internal cleaning. This will usually be good enough.
</p>
<p>
However, for trusted user input, you can set this to <code>false</code> to
disable cleaning. In addition, you can supply your own concrete implementation
of Tidy's interface to use, although I don't know why you'd want to do that.
</p>

View File

@ -0,0 +1,2 @@
FilterParam
DESCRIPTION: Configuration for filters.

View File

@ -21,14 +21,8 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
private $_styleMatches = array(); private $_styleMatches = array();
private $_tidy; private $_tidy;
/** public function __construct() {
* @param $tidy $this->_tidy = new csstidy();
* Instance of csstidy to use, false to turn off cleaning,
* and null to automatically instantiate
*/
public function __construct($tidy = null) {
if ($tidy === null) $tidy = new csstidy();
$this->_tidy = $tidy;
} }
/** /**
@ -44,6 +38,8 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
* @todo Extend to indicate non-text/css style blocks * @todo Extend to indicate non-text/css style blocks
*/ */
public function preFilter($html, $config, $context) { public function preFilter($html, $config, $context) {
$tidy = $config->get('FilterParam', 'ExtractStyleBlocksTidyImpl');
if ($tidy !== null) $this->_tidy = $tidy;
$html = preg_replace_callback('#<style(?:\s.*)?>(.+)</style>#isU', array($this, 'styleCallback'), $html); $html = preg_replace_callback('#<style(?:\s.*)?>(.+)</style>#isU', array($this, 'styleCallback'), $html);
$style_blocks = $this->_styleMatches; $style_blocks = $this->_styleMatches;
$this->_styleMatches = array(); // reset $this->_styleMatches = array(); // reset
@ -66,7 +62,7 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
*/ */
public function cleanCSS($css, $config, $context) { public function cleanCSS($css, $config, $context) {
// prepare scope // prepare scope
$scope = $config->get('Filter', 'ExtractStyleBlocksScope'); $scope = $config->get('FilterParam', 'ExtractStyleBlocksScope');
if ($scope !== null) { if ($scope !== null) {
$scopes = array_map('trim', explode(',', $scope)); $scopes = array_map('trim', explode(',', $scope));
} else { } else {
@ -124,7 +120,7 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
$css = $this->_tidy->print->plain(); $css = $this->_tidy->print->plain();
// we are going to escape any special characters <>& to ensure // we are going to escape any special characters <>& to ensure
// that no funny business occurs (i.e. </style> in a font-family prop). // that no funny business occurs (i.e. </style> in a font-family prop).
if ($config->get('Filter', 'ExtractStyleBlocksEscaping')) { if ($config->get('FilterParam', 'ExtractStyleBlocksEscaping')) {
$css = str_replace( $css = str_replace(
array('<', '>', '&'), array('<', '>', '&'),
array('\3C ', '\3E ', '\26 '), array('\3C ', '\3E ', '\26 '),

View File

@ -118,7 +118,7 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
$ret .= $this->end('tr'); $ret .= $this->end('tr');
foreach ($this->def->info as $name => $def) { foreach ($this->def->info as $name => $def) {
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', "<$name>" . ($def->safe ? '' : ' (unsafe)'), array('class'=>'heavy' . ($def->safe ? '' : ' unsafe'), 'colspan' => 2)); $ret .= $this->element('th', "<$name>", array('class'=>'heavy', 'colspan' => 2));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Inline content'); $ret .= $this->element('th', 'Inline content');

View File

@ -15,11 +15,6 @@ if (isset($_GET['doc'])) {
if (version_compare('5', PHP_VERSION, '>')) exit('Requires PHP 5 or higher.'); if (version_compare('5', PHP_VERSION, '>')) exit('Requires PHP 5 or higher.');
// setup schema for parsing
require_once 'testSchema.php';
$new_schema = $custom_schema; // dereference the reference
HTMLPurifier_ConfigSchema::instance($old); // restore old version
// setup ConfigDoc environment // setup ConfigDoc environment
require_once '../configdoc/library/ConfigDoc.auto.php'; require_once '../configdoc/library/ConfigDoc.auto.php';
@ -60,6 +55,7 @@ require_once 'HTMLPurifier/Printer/ConfigForm.php';
// fictional set, attempts to cover every possible data-type // fictional set, attempts to cover every possible data-type
// see source at ConfigTest.php // see source at ConfigTest.php
require_once 'testSchema.php'; require_once 'testSchema.php';
HTMLPurifier_ConfigSchema::instance($custom_schema);
// cleanup ( this should be rolled into Config ) // cleanup ( this should be rolled into Config )
$config = HTMLPurifier_Config::loadArrayFromForm($_GET, 'config'); $config = HTMLPurifier_Config::loadArrayFromForm($_GET, 'config');

View File

@ -20,8 +20,9 @@ accordingly.
require_once $csstidy_location . 'class.csstidy.php'; require_once $csstidy_location . 'class.csstidy.php';
require_once $csstidy_location . 'class.csstidy_print.php'; require_once $csstidy_location . 'class.csstidy_print.php';
$purifier = new HTMLPurifier(); $purifier = new HTMLPurifier(array(
$purifier->addFilter(new HTMLPurifier_Filter_ExtractStyleBlocks()); 'Filter.ExtractStyleBlocks' => true,
));
$html = isset($_POST['html']) ? $_POST['html'] : ''; $html = isset($_POST['html']) ? $_POST['html'] : '';
$purified_html = $purifier->purify($html); $purified_html = $purifier->purify($html);

View File

@ -19,9 +19,9 @@ $string = '<object width="425" height="350"><param name="movie" value="http://ww
$regular_purifier = new HTMLPurifier(); $regular_purifier = new HTMLPurifier();
$youtube_purifier = new HTMLPurifier(); $youtube_purifier = new HTMLPurifier(array(
require_once 'HTMLPurifier/Filter/YouTube.php'; 'Filter.YouTube' => true,
$youtube_purifier->addFilter(new HTMLPurifier_Filter_YouTube()); ));
?> ?>
<h2>Unpurified</h2> <h2>Unpurified</h2>

View File

@ -2,42 +2,40 @@
// overload default configuration schema temporarily // overload default configuration schema temporarily
$custom_schema = new HTMLPurifier_ConfigSchema(); $custom_schema = new HTMLPurifier_ConfigSchema();
$old = HTMLPurifier_ConfigSchema::instance();
$custom_schema =& HTMLPurifier_ConfigSchema::instance($custom_schema);
HTMLPurifier_ConfigSchema::defineNamespace('Element', 'Chemical substances that cannot be further decomposed'); $custom_schema->addNamespace('Element', 'Chemical substances that cannot be further decomposed');
HTMLPurifier_ConfigSchema::define('Element', 'Abbr', 'H', 'string', 'Abbreviation of element name.'); $custom_schema->add('Element', 'Abbr', 'H', 'string', false, 'Abbreviation of element name.');
HTMLPurifier_ConfigSchema::define('Element', 'Name', 'hydrogen', 'istring', 'Full name of atoms.'); $custom_schema->add('Element', 'Name', 'hydrogen', 'istring', false, 'Full name of atoms.');
HTMLPurifier_ConfigSchema::define('Element', 'Number', 1, 'int', 'Atomic number, is identity.'); $custom_schema->add('Element', 'Number', 1, 'int', false, 'Atomic number, is identity.');
HTMLPurifier_ConfigSchema::define('Element', 'Mass', 1.00794, 'float', 'Atomic mass.'); $custom_schema->add('Element', 'Mass', 1.00794, 'float', false, 'Atomic mass.');
HTMLPurifier_ConfigSchema::define('Element', 'Radioactive', false, 'bool', 'Does it have rapid decay?'); $custom_schema->add('Element', 'Radioactive', false, 'bool', false, 'Does it have rapid decay?');
HTMLPurifier_ConfigSchema::define('Element', 'Isotopes', array('1' => true, '2' => true, '3' => true), 'lookup', $custom_schema->add('Element', 'Isotopes', array('1' => true, '2' => true, '3' => true), 'lookup', false,
'What numbers of neutrons for this element have been observed?'); 'What numbers of neutrons for this element have been observed?');
HTMLPurifier_ConfigSchema::define('Element', 'Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', $custom_schema->add('Element', 'Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', false,
'What are general properties of the element?'); 'What are general properties of the element?');
HTMLPurifier_ConfigSchema::define('Element', 'IsotopeNames', array('1' => 'protium', '2' => 'deuterium', '3' => 'tritium'), 'hash', $custom_schema->add('Element', 'IsotopeNames', array('1' => 'protium', '2' => 'deuterium', '3' => 'tritium'), 'hash', false,
'Lookup hash of neutron counts to formal names.'); 'Lookup hash of neutron counts to formal names.');
HTMLPurifier_ConfigSchema::defineNamespace('Instrument', 'Of the musical type.'); $custom_schema->addNamespace('Instrument', 'Of the musical type.');
HTMLPurifier_ConfigSchema::define('Instrument', 'Manufacturer', 'Yamaha', 'string', 'Who made it?'); $custom_schema->add('Instrument', 'Manufacturer', 'Yamaha', 'string', false, 'Who made it?');
HTMLPurifier_ConfigSchema::defineAllowedValues('Instrument', 'Manufacturer', array( $custom_schema->addAllowedValues('Instrument', 'Manufacturer', array(
'Yamaha', 'Conn-Selmer', 'Vandoren', 'Laubin', 'Buffet', 'other')); 'Yamaha', 'Conn-Selmer', 'Vandoren', 'Laubin', 'Buffet', 'other'));
HTMLPurifier_ConfigSchema::defineValueAliases('Instrument', 'Manufacturer', array( $custom_schema->addValueAliases('Instrument', 'Manufacturer', array(
'Selmer' => 'Conn-Selmer')); 'Selmer' => 'Conn-Selmer'));
HTMLPurifier_ConfigSchema::define('Instrument', 'Family', 'woodwind', 'istring', 'What family is it?'); $custom_schema->add('Instrument', 'Family', 'woodwind', 'istring', false, 'What family is it?');
HTMLPurifier_ConfigSchema::defineAllowedValues('Instrument', 'Family', array( $custom_schema->addAllowedValues('Instrument', 'Family', array(
'brass', 'woodwind', 'percussion', 'string', 'keyboard', 'electronic')); 'brass', 'woodwind', 'percussion', 'string', 'keyboard', 'electronic'));
HTMLPurifier_ConfigSchema::defineValueAliases('Instrument', 'Family', array( $custom_schema->addValueAliases('Instrument', 'Family', array(
'synth' => 'electronic')); 'synth' => 'electronic'));
HTMLPurifier_ConfigSchema::defineNamespace('ReportCard', 'It is for grades.'); $custom_schema->addNamespace('ReportCard', 'It is for grades.');
HTMLPurifier_ConfigSchema::define('ReportCard', 'English', null, 'string/null', 'Grade from English class.'); $custom_schema->add('ReportCard', 'English', null, 'string', true, 'Grade from English class.');
HTMLPurifier_ConfigSchema::define('ReportCard', 'Absences', 0, 'int', 'How many times missing from school?'); $custom_schema->add('ReportCard', 'Absences', 0, 'int', false, 'How many times missing from school?');
HTMLPurifier_ConfigSchema::defineNamespace('Text', 'This stuff is long, boring, and English.'); $custom_schema->addNamespace('Text', 'This stuff is long, boring, and English.');
HTMLPurifier_ConfigSchema::define('Text', 'AboutUs', 'Nothing much, but this should be decently long so that a textarea would be better', 'text', 'Who are we? What are we up to?'); $custom_schema->add('Text', 'AboutUs', 'Nothing much, but this should be decently long so that a textarea would be better', 'text', false, 'Who are we? What are we up to?');
HTMLPurifier_ConfigSchema::define('Text', 'Hash', "not-case-sensitive\nstill-not-case-sensitive\nsuper-not-case-sensitive", 'itext', 'This is of limited utility, but of course it ends up being used.'); $custom_schema->add('Text', 'Hash', "not-case-sensitive\nstill-not-case-sensitive\nsuper-not-case-sensitive", 'itext', false, 'This is of limited utility, but of course it ends up being used.');

View File

@ -8,8 +8,8 @@ class HTMLPurifier_Filter_ExtractStyleBlocksTest extends HTMLPurifier_Harness
// usual use case: // usual use case:
function test_tokenizeHTML_extractStyleBlocks() { function test_tokenizeHTML_extractStyleBlocks() {
$this->config->set('Filter', 'ExtractStyleBlocks', true);
$purifier = new HTMLPurifier($this->config); $purifier = new HTMLPurifier($this->config);
$purifier->addFilter(new HTMLPurifier_Filter_ExtractStyleBlocks());
$result = $purifier->purify('<style type="text/css">.foo {text-align:center;bogus:remove-me;}</style>Test<style>* {font-size:12pt;}</style>'); $result = $purifier->purify('<style type="text/css">.foo {text-align:center;bogus:remove-me;}</style>Test<style>* {font-size:12pt;}</style>');
$this->assertIdentical($result, 'Test'); $this->assertIdentical($result, 'Test');
$this->assertIdentical($purifier->context->get('StyleBlocks'), $this->assertIdentical($purifier->context->get('StyleBlocks'),
@ -21,8 +21,9 @@ class HTMLPurifier_Filter_ExtractStyleBlocksTest extends HTMLPurifier_Harness
} }
function assertExtractStyleBlocks($html, $expect = true, $styles = array()) { function assertExtractStyleBlocks($html, $expect = true, $styles = array()) {
$filter = new HTMLPurifier_Filter_ExtractStyleBlocks(false); // disable cleaning $filter = new HTMLPurifier_Filter_ExtractStyleBlocks(); // disable cleaning
if ($expect === true) $expect = $html; if ($expect === true) $expect = $html;
$this->config->set('FilterParam', 'ExtractStyleBlocksTidyImpl', false);
$result = $filter->preFilter($html, $this->config, $this->context); $result = $filter->preFilter($html, $this->config, $this->context);
$this->assertIdentical($result, $expect); $this->assertIdentical($result, $expect);
$this->assertIdentical($this->context->get('StyleBlocks'), $styles); $this->assertIdentical($this->context->get('StyleBlocks'), $styles);
@ -103,14 +104,14 @@ class HTMLPurifier_Filter_ExtractStyleBlocksTest extends HTMLPurifier_Harness
} }
function test_cleanCSS_noEscapeCodes() { function test_cleanCSS_noEscapeCodes() {
$this->config->set('Filter', 'ExtractStyleBlocksEscaping', false); $this->config->set('FilterParam', 'ExtractStyleBlocksEscaping', false);
$this->assertCleanCSS( $this->assertCleanCSS(
".class {\nfont-family:'</style>';\n}" ".class {\nfont-family:'</style>';\n}"
); );
} }
function test_cleanCSS_scope() { function test_cleanCSS_scope() {
$this->config->set('Filter', 'ExtractStyleBlocksScope', '#foo'); $this->config->set('FilterParam', 'ExtractStyleBlocksScope', '#foo');
$this->assertCleanCSS( $this->assertCleanCSS(
"p {\ntext-indent:1em;\n}", "p {\ntext-indent:1em;\n}",
"#foo p {\ntext-indent:1em;\n}" "#foo p {\ntext-indent:1em;\n}"
@ -118,7 +119,7 @@ class HTMLPurifier_Filter_ExtractStyleBlocksTest extends HTMLPurifier_Harness
} }
function test_cleanCSS_scopeWithSelectorCommas() { function test_cleanCSS_scopeWithSelectorCommas() {
$this->config->set('Filter', 'ExtractStyleBlocksScope', '#foo'); $this->config->set('FilterParam', 'ExtractStyleBlocksScope', '#foo');
$this->assertCleanCSS( $this->assertCleanCSS(
"b, i {\ntext-decoration:underline;\n}", "b, i {\ntext-decoration:underline;\n}",
"#foo b, #foo i {\ntext-decoration:underline;\n}" "#foo b, #foo i {\ntext-decoration:underline;\n}"
@ -126,17 +127,17 @@ class HTMLPurifier_Filter_ExtractStyleBlocksTest extends HTMLPurifier_Harness
} }
function test_cleanCSS_scopeWithNaughtySelector() { function test_cleanCSS_scopeWithNaughtySelector() {
$this->config->set('Filter', 'ExtractStyleBlocksScope', '#foo'); $this->config->set('FilterParam', 'ExtractStyleBlocksScope', '#foo');
$this->assertCleanCSS(" + p {\ntext-indent:1em;\n}", ''); $this->assertCleanCSS(" + p {\ntext-indent:1em;\n}", '');
} }
function test_cleanCSS_scopeWithMultipleNaughtySelectors() { function test_cleanCSS_scopeWithMultipleNaughtySelectors() {
$this->config->set('Filter', 'ExtractStyleBlocksScope', '#foo'); $this->config->set('FilterParam', 'ExtractStyleBlocksScope', '#foo');
$this->assertCleanCSS(" ++ ++ p {\ntext-indent:1em;\n}", ''); $this->assertCleanCSS(" ++ ++ p {\ntext-indent:1em;\n}", '');
} }
function test_cleanCSS_scopeWithCommas() { function test_cleanCSS_scopeWithCommas() {
$this->config->set('Filter', 'ExtractStyleBlocksScope', '#foo, .bar'); $this->config->set('FilterParam', 'ExtractStyleBlocksScope', '#foo, .bar');
$this->assertCleanCSS( $this->assertCleanCSS(
"p {\ntext-indent:1em;\n}", "p {\ntext-indent:1em;\n}",
"#foo p, .bar p {\ntext-indent:1em;\n}" "#foo p, .bar p {\ntext-indent:1em;\n}"
@ -144,7 +145,7 @@ class HTMLPurifier_Filter_ExtractStyleBlocksTest extends HTMLPurifier_Harness
} }
function test_cleanCSS_scopeAllWithCommas() { function test_cleanCSS_scopeAllWithCommas() {
$this->config->set('Filter', 'ExtractStyleBlocksScope', '#foo, .bar'); $this->config->set('FilterParam', 'ExtractStyleBlocksScope', '#foo, .bar');
$this->assertCleanCSS( $this->assertCleanCSS(
"p, div {\ntext-indent:1em;\n}", "p, div {\ntext-indent:1em;\n}",
"#foo p, #foo div, .bar p, .bar div {\ntext-indent:1em;\n}" "#foo p, #foo div, .bar p, .bar div {\ntext-indent:1em;\n}"
@ -152,7 +153,7 @@ class HTMLPurifier_Filter_ExtractStyleBlocksTest extends HTMLPurifier_Harness
} }
function test_cleanCSS_scopeWithConflicts() { function test_cleanCSS_scopeWithConflicts() {
$this->config->set('Filter', 'ExtractStyleBlocksScope', 'p'); $this->config->set('FilterParam', 'ExtractStyleBlocksScope', 'p');
$this->assertCleanCSS( $this->assertCleanCSS(
"div { "div {
text-align:right; text-align:right;

View File

@ -163,5 +163,15 @@ alert("<This is compatible with XHTML>");
); );
} }
function test_addFilter_deprecated() {
$purifier = new HTMLPurifier();
$this->expectError('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom');
generate_mock_once('HTMLPurifier_Filter');
$purifier->addFilter($mock = new HTMLPurifier_FilterMock());
$mock->expectOnce('preFilter');
$mock->expectOnce('postFilter');
$purifier->purify('foo');
}
} }