0
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2024-12-22 16:31:53 +00:00

[3.1.0] More PHP4->PHP5 conversions, notably reference removal of most methods that return objects

- Removed HTMLPurifier_Error
- Documentation updates
- Removed more copy() methods in favor of clone
- HTMLPurifier::getInstance() to HTMLPurifier::instance()
- Fix InterchangeBuilder to use HTMLPURIFIER_PREFIX

git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1689 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
Edward Z. Yang 2008-04-23 02:40:17 +00:00
parent 893cdd0301
commit eaabccdd9b
49 changed files with 237 additions and 210 deletions

18
NEWS
View File

@ -10,12 +10,28 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
========================== ==========================
3.1.0, unknown release date 3.1.0, unknown release date
# Unnecessary references to objects (vestiges of PHP4) removed from method
signatures. The following methods do not need references when assigning from
them and will result in E_STRICT errors if you try:
+ HTMLPurifier_Config->get*Definition() [* = HTML, CSS]
+ HTMLPurifier_ConfigSchema::instance()
+ HTMLPurifier_DefinitionCacheFactory::instance()
+ HTMLPurifier_DefinitionCacheFactory->create()
+ HTMLPurifier_DoctypeRegistry->register()
+ HTMLPurifier_DoctypeRegistry->get()
+ HTMLPurifier_HTMLModule->addElement()
+ HTMLPurifier_HTMLModule->addBlankElement()
+ HTMLPurifier_LanguageFactory::instance()
- InterchangeBuilder now alphabetizes its lists - InterchangeBuilder now alphabetizes its lists
- Validation error in configdoc output fixed - Validation error in configdoc output fixed
- Iconv errors muted even with custom error handlers - Iconv and other encoding errors muted even with custom error handlers that
do not honor error_reporting
- Add protection against imagecrash attack with CSS height/width - Add protection against imagecrash attack with CSS height/width
- HTMLPurifier::instance() created for consistency, is equivalent to getInstance()
. Out-of-date documentation revised . Out-of-date documentation revised
. UTF-8 encoding check optimization as suggested by Diego . UTF-8 encoding check optimization as suggested by Diego
. HTMLPurifier_Error removed in favor of exceptions
. More copy() function removed; should use clone instead
3.1.0rc1, released 2008-04-22 3.1.0rc1, released 2008-04-22
# Autoload support added. Internal require_once's removed in favor of an # Autoload support added. Internal require_once's removed in favor of an

View File

@ -5,7 +5,7 @@
<line>129</line> <line>129</line>
</file> </file>
<file name="HTMLPurifier/Lexer.php"> <file name="HTMLPurifier/Lexer.php">
<line>93</line> <line>85</line>
</file> </file>
<file name="HTMLPurifier/Lexer/DirectLex.php"> <file name="HTMLPurifier/Lexer/DirectLex.php">
<line>50</line> <line>50</line>
@ -64,18 +64,18 @@
<directive id="Core.Encoding"> <directive id="Core.Encoding">
<file name="HTMLPurifier/Encoder.php"> <file name="HTMLPurifier/Encoder.php">
<line>281</line> <line>281</line>
<line>299</line> <line>305</line>
</file> </file>
</directive> </directive>
<directive id="Test.ForceNoIconv"> <directive id="Test.ForceNoIconv">
<file name="HTMLPurifier/Encoder.php"> <file name="HTMLPurifier/Encoder.php">
<line>283</line> <line>283</line>
<line>304</line> <line>310</line>
</file> </file>
</directive> </directive>
<directive id="Core.EscapeNonASCIICharacters"> <directive id="Core.EscapeNonASCIICharacters">
<file name="HTMLPurifier/Encoder.php"> <file name="HTMLPurifier/Encoder.php">
<line>301</line> <line>307</line>
</file> </file>
</directive> </directive>
<directive id="Core.MaintainLineNumbers"> <directive id="Core.MaintainLineNumbers">
@ -83,7 +83,7 @@
<line>81</line> <line>81</line>
</file> </file>
<file name="HTMLPurifier/Lexer.php"> <file name="HTMLPurifier/Lexer.php">
<line>90</line> <line>82</line>
</file> </file>
<file name="HTMLPurifier/Lexer/DirectLex.php"> <file name="HTMLPurifier/Lexer/DirectLex.php">
<line>45</line> <line>45</line>
@ -91,17 +91,17 @@
</directive> </directive>
<directive id="Output.CommentScriptContents"> <directive id="Output.CommentScriptContents">
<file name="HTMLPurifier/Generator.php"> <file name="HTMLPurifier/Generator.php">
<line>40</line> <line>37</line>
</file> </file>
</directive> </directive>
<directive id="Output.TidyFormat"> <directive id="Output.TidyFormat">
<file name="HTMLPurifier/Generator.php"> <file name="HTMLPurifier/Generator.php">
<line>61</line> <line>58</line>
</file> </file>
</directive> </directive>
<directive id="Output.Newline"> <directive id="Output.Newline">
<file name="HTMLPurifier/Generator.php"> <file name="HTMLPurifier/Generator.php">
<line>86</line> <line>83</line>
</file> </file>
</directive> </directive>
<directive id="HTML.BlockWrapper"> <directive id="HTML.BlockWrapper">
@ -144,7 +144,7 @@
<line>198</line> <line>198</line>
</file> </file>
<file name="HTMLPurifier/Lexer.php"> <file name="HTMLPurifier/Lexer.php">
<line>245</line> <line>238</line>
</file> </file>
<file name="HTMLPurifier/Lexer/DirectLex.php"> <file name="HTMLPurifier/Lexer/DirectLex.php">
<line>34</line> <line>34</line>
@ -177,12 +177,12 @@
</directive> </directive>
<directive id="Core.LexerImpl"> <directive id="Core.LexerImpl">
<file name="HTMLPurifier/Lexer.php"> <file name="HTMLPurifier/Lexer.php">
<line>78</line> <line>70</line>
</file> </file>
</directive> </directive>
<directive id="Core.ConvertDocumentToFragment"> <directive id="Core.ConvertDocumentToFragment">
<file name="HTMLPurifier/Lexer.php"> <file name="HTMLPurifier/Lexer.php">
<line>237</line> <line>230</line>
</file> </file>
</directive> </directive>
<directive id="URI.Host"> <directive id="URI.Host">

View File

@ -158,7 +158,7 @@
<pre>$config = HTMLPurifier_Config::createDefault(); <pre>$config = HTMLPurifier_Config::createDefault();
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial'); $config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
$config->set('HTML', 'DefinitionRev', 1); $config->set('HTML', 'DefinitionRev', 1);
$def =& $config->getHTMLDefinition(true);</pre> $def = $config->getHTMLDefinition(true);</pre>
<p> <p>
Assuming that HTML Purifier has already been properly loaded (hint: Assuming that HTML Purifier has already been properly loaded (hint:
@ -214,7 +214,7 @@ $def =& $config->getHTMLDefinition(true);</pre>
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial'); $config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
$config->set('HTML', 'DefinitionRev', 1); $config->set('HTML', 'DefinitionRev', 1);
<strong>$config->set('Core', 'DefinitionCache', null); // remove this later!</strong> <strong>$config->set('Core', 'DefinitionCache', null); // remove this later!</strong>
$def =& $config->getHTMLDefinition(true);</pre> $def = $config->getHTMLDefinition(true);</pre>
<p> <p>
A few things should be mentioned about the caching mechanism before A few things should be mentioned about the caching mechanism before
@ -270,7 +270,7 @@ $def =& $config->getHTMLDefinition(true);</pre>
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial'); $config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
$config->set('HTML', 'DefinitionRev', 1); $config->set('HTML', 'DefinitionRev', 1);
$config->set('Core', 'DefinitionCache', null); // remove this later! $config->set('Core', 'DefinitionCache', null); // remove this later!
$def =& $config->getHTMLDefinition(true); $def = $config->getHTMLDefinition(true);
<strong>$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');</strong></pre> <strong>$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');</strong></pre>
<p> <p>
@ -388,7 +388,7 @@ $def =& $config->getHTMLDefinition(true);
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial'); $config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
$config->set('HTML', 'DefinitionRev', 1); $config->set('HTML', 'DefinitionRev', 1);
$config->set('Core', 'DefinitionCache', null); // remove this later! $config->set('Core', 'DefinitionCache', null); // remove this later!
$def =& $config->getHTMLDefinition(true); $def = $config->getHTMLDefinition(true);
<strong>$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum( <strong>$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
array('_blank','_self','_target','_top') array('_blank','_self','_target','_top')
));</strong></pre> ));</strong></pre>
@ -735,11 +735,11 @@ $def =& $config->getHTMLDefinition(true);
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial'); $config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
$config->set('HTML', 'DefinitionRev', 1); $config->set('HTML', 'DefinitionRev', 1);
$config->set('Core', 'DefinitionCache', null); // remove this later! $config->set('Core', 'DefinitionCache', null); // remove this later!
$def =& $config->getHTMLDefinition(true); $def = $config->getHTMLDefinition(true);
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum( $def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
array('_blank','_self','_target','_top') array('_blank','_self','_target','_top')
)); ));
<strong>$form =& $def->addElement( <strong>$form = $def->addElement(
'form', // name 'form', // name
'Block', // content set 'Block', // content set
'Flow', // allowed children 'Flow', // allowed children

View File

@ -35,7 +35,7 @@
{ {
public $name = '<strong>NameOfFilter</strong>'; public $name = '<strong>NameOfFilter</strong>';
public function prepare($config) {} public function prepare($config) {}
public function filter(&$uri, $config, &$context) {} public function filter(&$uri, $config, $context) {}
}</pre> }</pre>
<p> <p>
@ -60,8 +60,8 @@
public function HTMLPurifier_URI($scheme, $userinfo, $host, $port, $path, $query, $fragment); public function HTMLPurifier_URI($scheme, $userinfo, $host, $port, $path, $query, $fragment);
public function toString(); public function toString();
public function copy(); public function copy();
public function getSchemeObj($config, &$context); public function getSchemeObj($config, $context);
public function validate($config, &$context); public function validate($config, $context);
}</pre> }</pre>
<p> <p>
@ -139,7 +139,7 @@
<pre>class HTMLPurifier_URIFilter_ConvertIDNToPunycode extends HTMLPurifier_URIFilter <pre>class HTMLPurifier_URIFilter_ConvertIDNToPunycode extends HTMLPurifier_URIFilter
{ {
public $name = 'ConvertIDNToPunycode'; public $name = 'ConvertIDNToPunycode';
public function filter(&$uri, $config, &$context) { public function filter(&$uri, $config, $context) {
if (is_null($uri->host)) return true; if (is_null($uri->host)) return true;
if ($uri->host == utf8_decode($uri->host)) { if ($uri->host == utf8_decode($uri->host)) {
// is ASCII, abort // is ASCII, abort
@ -163,7 +163,7 @@
to use it. Fortunately, this part's simple: to use it. Fortunately, this part's simple:
</p> </p>
<pre>$uri =& $config->getDefinition('URI'); <pre>$uri = $config->getDefinition('URI');
$uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pre> $uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pre>
<p> <p>
@ -177,7 +177,7 @@ $uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pr
'URI', '<strong>NameOfFilter</strong>', false, 'bool', 'URI', '<strong>NameOfFilter</strong>', false, 'bool',
'<strong>What your filter does.</strong>' '<strong>What your filter does.</strong>'
); );
$uri =& $config->getDefinition('URI', true); $uri = $config->getDefinition('URI', true);
$uri->registerFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>()); $uri->registerFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());
</pre> </pre>

View File

@ -41,7 +41,6 @@ require 'HTMLPurifier/ElementDef.php';
require 'HTMLPurifier/Encoder.php'; require 'HTMLPurifier/Encoder.php';
require 'HTMLPurifier/EntityLookup.php'; require 'HTMLPurifier/EntityLookup.php';
require 'HTMLPurifier/EntityParser.php'; require 'HTMLPurifier/EntityParser.php';
require 'HTMLPurifier/Error.php';
require 'HTMLPurifier/ErrorCollector.php'; require 'HTMLPurifier/ErrorCollector.php';
require 'HTMLPurifier/Exception.php'; require 'HTMLPurifier/Exception.php';
require 'HTMLPurifier/Filter.php'; require 'HTMLPurifier/Filter.php';

View File

@ -207,9 +207,10 @@ class HTMLPurifier
/** /**
* Singleton for enforcing just one HTML Purifier in your system * Singleton for enforcing just one HTML Purifier in your system
* @param $prototype Optional prototype HTMLPurifier instance to * @param $prototype Optional prototype HTMLPurifier instance to
* overload singleton with. * overload singleton with, or HTMLPurifier_Config
* instance to configure the generated version with.
*/ */
public static function getInstance($prototype = null) { public static function instance($prototype = null) {
if (!self::$instance || $prototype) { if (!self::$instance || $prototype) {
if ($prototype instanceof HTMLPurifier) { if ($prototype instanceof HTMLPurifier) {
self::$instance = $prototype; self::$instance = $prototype;
@ -222,4 +223,11 @@ class HTMLPurifier
return self::$instance; return self::$instance;
} }
/**
* @note Backwards compatibility, see instance()
*/
public static function getInstance($prototype = null) {
return HTMLPurifier::instance($prototype);
}
} }

View File

@ -35,7 +35,6 @@ require_once $__dir . '/HTMLPurifier/ElementDef.php';
require_once $__dir . '/HTMLPurifier/Encoder.php'; require_once $__dir . '/HTMLPurifier/Encoder.php';
require_once $__dir . '/HTMLPurifier/EntityLookup.php'; require_once $__dir . '/HTMLPurifier/EntityLookup.php';
require_once $__dir . '/HTMLPurifier/EntityParser.php'; require_once $__dir . '/HTMLPurifier/EntityParser.php';
require_once $__dir . '/HTMLPurifier/Error.php';
require_once $__dir . '/HTMLPurifier/ErrorCollector.php'; require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
require_once $__dir . '/HTMLPurifier/Exception.php'; require_once $__dir . '/HTMLPurifier/Exception.php';
require_once $__dir . '/HTMLPurifier/Filter.php'; require_once $__dir . '/HTMLPurifier/Filter.php';

View File

@ -70,9 +70,10 @@ abstract class HTMLPurifier_AttrDef
* @return Created AttrDef object corresponding to $string * @return Created AttrDef object corresponding to $string
*/ */
public function make($string) { public function make($string) {
// default implementation, return flyweight of this object // default implementation, return a flyweight of this object.
// if overloaded, it is *necessary* for you to clone the // If $string has an effect on the returned object (i.e. you
// object (usually by instantiating a new copy) and return that // need to overload this method), it is best
// to clone or instantiate new copies. (Instantiation is safer.)
return $this; return $this;
} }

View File

@ -42,7 +42,7 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
if (!$result) break; if (!$result) break;
// chained filtering // chained filtering
$uri_def =& $config->getDefinition('URI'); $uri_def = $config->getDefinition('URI');
$result = $uri_def->filter($uri, $config, $context); $result = $uri_def->filter($uri, $config, $context);
if (!$result) break; if (!$result) break;

View File

@ -3,7 +3,7 @@
/** /**
* Defines allowed child nodes and validates tokens against it. * Defines allowed child nodes and validates tokens against it.
*/ */
class HTMLPurifier_ChildDef abstract class HTMLPurifier_ChildDef
{ {
/** /**
* Type of child definition, usually right-most part of class name lowercase. * Type of child definition, usually right-most part of class name lowercase.
@ -34,9 +34,7 @@ class HTMLPurifier_ChildDef
* @return bool false to remove parent node * @return bool false to remove parent node
* @return array of replacement child tokens * @return array of replacement child tokens
*/ */
public function validateChildren($tokens_of_children, $config, $context) { abstract public function validateChildren($tokens_of_children, $config, $context);
trigger_error('Call to abstract function', E_USER_ERROR);
}
} }

View File

@ -107,7 +107,7 @@ class HTMLPurifier_Config
* @return Default HTMLPurifier_Config object. * @return Default HTMLPurifier_Config object.
*/ */
public static function createDefault() { public static function createDefault() {
$definition =& HTMLPurifier_ConfigSchema::instance(); $definition = HTMLPurifier_ConfigSchema::instance();
$config = new HTMLPurifier_Config($definition); $config = new HTMLPurifier_Config($definition);
return $config; return $config;
} }
@ -254,21 +254,21 @@ class HTMLPurifier_Config
} }
/** /**
* Retrieves reference to the HTML definition. * Retrieves object reference to the HTML definition.
* @param $raw Return a copy that has not been setup yet. Must be * @param $raw Return a copy that has not been setup yet. Must be
* called before it's been setup, otherwise won't work. * called before it's been setup, otherwise won't work.
*/ */
public function &getHTMLDefinition($raw = false) { public function getHTMLDefinition($raw = false) {
$def =& $this->getDefinition('HTML', $raw); return $this->getDefinition('HTML', $raw);
return $def; // prevent PHP 4.4.0 from complaining
} }
/** /**
* Retrieves reference to the CSS definition * Retrieves object reference to the CSS definition
* @param $raw Return a copy that has not been setup yet. Must be
* called before it's been setup, otherwise won't work.
*/ */
public function &getCSSDefinition($raw = false) { public function getCSSDefinition($raw = false) {
$def =& $this->getDefinition('CSS', $raw); return $this->getDefinition('CSS', $raw);
return $def;
} }
/** /**
@ -276,7 +276,7 @@ class HTMLPurifier_Config
* @param $type Type of definition: HTML, CSS, etc * @param $type Type of definition: HTML, CSS, etc
* @param $raw Whether or not definition should be returned raw * @param $raw Whether or not definition should be returned raw
*/ */
public function &getDefinition($type, $raw = false) { public function getDefinition($type, $raw = false) {
if (!$this->finalized && $this->autoFinalize) $this->finalize(); if (!$this->finalized && $this->autoFinalize) $this->finalize();
$factory = HTMLPurifier_DefinitionCacheFactory::instance(); $factory = HTMLPurifier_DefinitionCacheFactory::instance();
$cache = $factory->create($type, $this); $cache = $factory->create($type, $this);
@ -310,17 +310,13 @@ class HTMLPurifier_Config
} elseif ($type == 'URI') { } elseif ($type == 'URI') {
$this->definitions[$type] = new HTMLPurifier_URIDefinition(); $this->definitions[$type] = new HTMLPurifier_URIDefinition();
} else { } else {
trigger_error("Definition of $type type not supported"); throw new HTMLPurifier_Exception("Definition of $type type not supported");
$false = false;
return $false;
} }
// quick abort if raw // quick abort if raw
if ($raw) { if ($raw) {
if (is_null($this->get($type, 'DefinitionID'))) { if (is_null($this->get($type, 'DefinitionID'))) {
// fatally error out if definition ID not set // fatally error out if definition ID not set
trigger_error("Cannot retrieve raw version without specifying %$type.DefinitionID", E_USER_ERROR); throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID");
$false = new HTMLPurifier_Error();
return $false;
} }
return $this->definitions[$type]; return $this->definitions[$type];
} }

View File

@ -3,7 +3,7 @@
/** /**
* Base class for configuration entity * Base class for configuration entity
*/ */
class HTMLPurifier_ConfigDef { abstract class HTMLPurifier_ConfigDef {
public $class = false; public $class = false;
} }

View File

@ -40,7 +40,7 @@ class HTMLPurifier_ConfigSchema {
/** /**
* Retrieves an instance of the application-wide configuration definition. * Retrieves an instance of the application-wide configuration definition.
*/ */
public static function &instance($prototype = null) { public static function instance($prototype = null) {
if ($prototype !== null) { if ($prototype !== null) {
HTMLPurifier_ConfigSchema::$singleton = $prototype; HTMLPurifier_ConfigSchema::$singleton = $prototype;
} elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) { } elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) {
@ -104,9 +104,8 @@ class HTMLPurifier_ConfigSchema {
* @param $allowed Lookup array of allowed values * @param $allowed Lookup array of allowed values
*/ */
public function addAllowedValues($namespace, $name, $allowed) { public function addAllowedValues($namespace, $name, $allowed) {
$directive =& $this->info[$namespace][$name]; $type = $this->info[$namespace][$name]->type;
$type = $directive->type; $this->info[$namespace][$name]->allowed = $allowed;
$directive->allowed = $allowed;
} }
/** /**
@ -130,21 +129,21 @@ class HTMLPurifier_ConfigSchema {
$type = $type_values[0]; $type = $type_values[0];
$modifier = isset($type_values[1]) ? $type_values[1] : false; $modifier = isset($type_values[1]) ? $type_values[1] : false;
$allow_null = ($modifier === 'null'); $allow_null = ($modifier === 'null');
$def =& HTMLPurifier_ConfigSchema::instance(); $def = HTMLPurifier_ConfigSchema::instance();
$def->add($namespace, $name, $default, $type, $allow_null); $def->add($namespace, $name, $default, $type, $allow_null);
} }
/** @see HTMLPurifier_ConfigSchema->addNamespace() */ /** @see HTMLPurifier_ConfigSchema->addNamespace() */
public static function defineNamespace($namespace, $description) { public static function defineNamespace($namespace, $description) {
HTMLPurifier_ConfigSchema::deprecated(__METHOD__); HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
$def =& HTMLPurifier_ConfigSchema::instance(); $def = HTMLPurifier_ConfigSchema::instance();
$def->addNamespace($namespace); $def->addNamespace($namespace);
} }
/** @see HTMLPurifier_ConfigSchema->addValueAliases() */ /** @see HTMLPurifier_ConfigSchema->addValueAliases() */
public static function defineValueAliases($namespace, $name, $aliases) { public static function defineValueAliases($namespace, $name, $aliases) {
HTMLPurifier_ConfigSchema::deprecated(__METHOD__); HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
$def =& HTMLPurifier_ConfigSchema::instance(); $def = HTMLPurifier_ConfigSchema::instance();
$def->addValueAliases($namespace, $name, $aliases); $def->addValueAliases($namespace, $name, $aliases);
} }
@ -155,14 +154,14 @@ class HTMLPurifier_ConfigSchema {
foreach ($allowed_values as $value) { foreach ($allowed_values as $value) {
$allowed[$value] = true; $allowed[$value] = true;
} }
$def =& HTMLPurifier_ConfigSchema::instance(); $def = HTMLPurifier_ConfigSchema::instance();
$def->addAllowedValues($namespace, $name, $allowed); $def->addAllowedValues($namespace, $name, $allowed);
} }
/** @see HTMLPurifier_ConfigSchema->addAlias() */ /** @see HTMLPurifier_ConfigSchema->addAlias() */
public static function defineAlias($namespace, $name, $new_namespace, $new_name) { public static function defineAlias($namespace, $name, $new_namespace, $new_name) {
HTMLPurifier_ConfigSchema::deprecated(__METHOD__); HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
$def =& HTMLPurifier_ConfigSchema::instance(); $def = HTMLPurifier_ConfigSchema::instance();
$def->addAlias($namespace, $name, $new_namespace, $new_name); $def->addAlias($namespace, $name, $new_namespace, $new_name);
} }

View File

@ -17,7 +17,7 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
$builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder(); $builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder();
$interchange = new HTMLPurifier_ConfigSchema_Interchange(); $interchange = new HTMLPurifier_ConfigSchema_Interchange();
if (!$dir) $dir = dirname(__FILE__) . '/schema/'; if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema/';
$info = parse_ini_file($dir . 'info.ini'); $info = parse_ini_file($dir . 'info.ini');
$interchange->name = $info['name']; $interchange->name = $info['name'];

View File

@ -4,6 +4,8 @@
* Registry object that contains information about the current context. * Registry object that contains information about the current context.
* @warning Is a bit buggy when variables are set to null: it thinks * @warning Is a bit buggy when variables are set to null: it thinks
* they don't exist! So use false instead, please. * they don't exist! So use false instead, please.
* @note Since the variables Context deals with may not be objects,
* references are very important here! Do not remove!
*/ */
class HTMLPurifier_Context class HTMLPurifier_Context
{ {
@ -16,7 +18,7 @@ class HTMLPurifier_Context
/** /**
* Registers a variable into the context. * Registers a variable into the context.
* @param $name String name * @param $name String name
* @param $ref Variable to be registered * @param $ref Reference to variable to be registered
*/ */
public function register($name, &$ref) { public function register($name, &$ref) {
if (isset($this->_storage[$name])) { if (isset($this->_storage[$name])) {

View File

@ -20,7 +20,7 @@ class HTMLPurifier_DefinitionCacheFactory
/** /**
* Retrieves an instance of global definition cache factory. * Retrieves an instance of global definition cache factory.
*/ */
public static function &instance($prototype = null) { public static function instance($prototype = null) {
static $instance; static $instance;
if ($prototype !== null) { if ($prototype !== null) {
$instance = $prototype; $instance = $prototype;
@ -45,7 +45,7 @@ class HTMLPurifier_DefinitionCacheFactory
* @param $name Name of definitions handled by cache * @param $name Name of definitions handled by cache
* @param $config Instance of HTMLPurifier_Config * @param $config Instance of HTMLPurifier_Config
*/ */
public function &create($type, $config) { public function create($type, $config) {
$method = $config->get('Cache', 'DefinitionImpl'); $method = $config->get('Cache', 'DefinitionImpl');
if ($method === null) { if ($method === null) {
$null = new HTMLPurifier_DefinitionCache_Null($type); $null = new HTMLPurifier_DefinitionCache_Null($type);

View File

@ -21,9 +21,9 @@ class HTMLPurifier_DoctypeRegistry
* @param $modules Modules doctype will load * @param $modules Modules doctype will load
* @param $modules_for_modes Modules doctype will load for certain modes * @param $modules_for_modes Modules doctype will load for certain modes
* @param $aliases Alias names for doctype * @param $aliases Alias names for doctype
* @return Reference to registered doctype (usable for further editing) * @return Editable registered doctype
*/ */
public function &register($doctype, $xml = true, $modules = array(), public function register($doctype, $xml = true, $modules = array(),
$tidy_modules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null $tidy_modules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null
) { ) {
if (!is_array($modules)) $modules = array($modules); if (!is_array($modules)) $modules = array($modules);
@ -34,7 +34,7 @@ class HTMLPurifier_DoctypeRegistry
$doctype, $xml, $modules, $tidy_modules, $aliases, $dtd_public, $dtd_system $doctype, $xml, $modules, $tidy_modules, $aliases, $dtd_public, $dtd_system
); );
} }
$this->doctypes[$doctype->name] =& $doctype; $this->doctypes[$doctype->name] = $doctype;
$name = $doctype->name; $name = $doctype->name;
// hookup aliases // hookup aliases
foreach ($doctype->aliases as $alias) { foreach ($doctype->aliases as $alias) {
@ -51,9 +51,9 @@ class HTMLPurifier_DoctypeRegistry
* @note This function resolves aliases * @note This function resolves aliases
* @note When possible, use the more fully-featured make() * @note When possible, use the more fully-featured make()
* @param $doctype Name of doctype * @param $doctype Name of doctype
* @return Reference to doctype object * @return Editable doctype object
*/ */
public function &get($doctype) { public function get($doctype) {
if (isset($this->aliases[$doctype])) $doctype = $this->aliases[$doctype]; if (isset($this->aliases[$doctype])) $doctype = $this->aliases[$doctype];
if (!isset($this->doctypes[$doctype])) { if (!isset($this->doctypes[$doctype])) {
trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR); trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR);

View File

@ -281,9 +281,15 @@ class HTMLPurifier_Encoder
$encoding = $config->get('Core', 'Encoding'); $encoding = $config->get('Core', 'Encoding');
if ($encoding === 'utf-8') return $str; if ($encoding === 'utf-8') return $str;
if ($iconv && !$config->get('Test', 'ForceNoIconv')) { if ($iconv && !$config->get('Test', 'ForceNoIconv')) {
return @iconv($encoding, 'utf-8//IGNORE', $str); set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
$str = iconv($encoding, 'utf-8//IGNORE', $str);
restore_error_handler();
return $str;
} elseif ($encoding === 'iso-8859-1') { } elseif ($encoding === 'iso-8859-1') {
return @utf8_encode($str); set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
$str = utf8_encode($str);
restore_error_handler();
return $str;
} }
trigger_error('Encoding not supported', E_USER_ERROR); trigger_error('Encoding not supported', E_USER_ERROR);
} }
@ -302,9 +308,15 @@ class HTMLPurifier_Encoder
$str = HTMLPurifier_Encoder::convertToASCIIDumbLossless($str); $str = HTMLPurifier_Encoder::convertToASCIIDumbLossless($str);
} }
if ($iconv && !$config->get('Test', 'ForceNoIconv')) { if ($iconv && !$config->get('Test', 'ForceNoIconv')) {
return @iconv('utf-8', $encoding . '//IGNORE', $str); set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
$str = iconv('utf-8', $encoding . '//IGNORE', $str);
restore_error_handler();
return $str;
} elseif ($encoding === 'iso-8859-1') { } elseif ($encoding === 'iso-8859-1') {
return @utf8_decode($str); set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
$str = utf8_decode($str);
restore_error_handler();
return $str;
} }
trigger_error('Encoding not supported', E_USER_ERROR); trigger_error('Encoding not supported', E_USER_ERROR);
} }

View File

@ -1,7 +0,0 @@
<?php
/**
* Return object from functions that signifies error when null doesn't cut it
*/
class HTMLPurifier_Error {}

View File

@ -15,7 +15,7 @@ class HTMLPurifier_ErrorCollector
public function __construct($context) { public function __construct($context) {
$this->locale =& $context->get('Locale'); $this->locale =& $context->get('Locale');
$this->generator =& $context->get('Generator'); $this->generator =& $context->get('Generator');
$this->context =& $context; $this->context = $context;
} }
/** /**

View File

@ -12,19 +12,16 @@ class HTMLPurifier_Generator
/** /**
* Bool cache of %HTML.XHTML * Bool cache of %HTML.XHTML
* @private
*/ */
private $_xhtml = true; private $_xhtml = true;
/** /**
* Bool cache of %Output.CommentScriptContents * Bool cache of %Output.CommentScriptContents
* @private
*/ */
private $_scriptFix = false; private $_scriptFix = false;
/** /**
* Cache of HTMLDefinition * Cache of HTMLDefinition
* @private
*/ */
private $_def; private $_def;

View File

@ -95,11 +95,11 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
* HTMLPurifier_AttrTypes for details * HTMLPurifier_AttrTypes for details
*/ */
public function addAttribute($element_name, $attr_name, $def) { public function addAttribute($element_name, $attr_name, $def) {
$module =& $this->getAnonymousModule(); $module = $this->getAnonymousModule();
if (!isset($module->info[$element_name])) { if (!isset($module->info[$element_name])) {
$element =& $module->addBlankElement($element_name); $element = $module->addBlankElement($element_name);
} else { } else {
$element =& $module->info[$element_name]; $element = $module->info[$element_name];
} }
$element->attr[$attr_name] = $def; $element->attr[$attr_name] = $def;
} }
@ -109,11 +109,11 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
* @note See HTMLPurifier_HTMLModule::addElement for detailed * @note See HTMLPurifier_HTMLModule::addElement for detailed
* parameter and return value descriptions. * parameter and return value descriptions.
*/ */
public function &addElement($element_name, $type, $contents, $attr_collections, $attributes) { public function addElement($element_name, $type, $contents, $attr_collections, $attributes) {
$module =& $this->getAnonymousModule(); $module = $this->getAnonymousModule();
// assume that if the user is calling this, the element // assume that if the user is calling this, the element
// is safe. This may not be a good idea // is safe. This may not be a good idea
$element =& $module->addElement($element_name, $type, $contents, $attr_collections, $attributes); $element = $module->addElement($element_name, $type, $contents, $attr_collections, $attributes);
return $element; return $element;
} }
@ -123,9 +123,9 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
* @note See HTMLPurifier_HTMLModule::addBlankElement for detailed * @note See HTMLPurifier_HTMLModule::addBlankElement for detailed
* parameter and return value descriptions. * parameter and return value descriptions.
*/ */
public function &addBlankElement($element_name) { public function addBlankElement($element_name) {
$module =& $this->getAnonymousModule(); $module = $this->getAnonymousModule();
$element =& $module->addBlankElement($element_name); $element = $module->addBlankElement($element_name);
return $element; return $element;
} }
@ -134,7 +134,7 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
* bust out advanced features without having to make your own * bust out advanced features without having to make your own
* module. * module.
*/ */
public function &getAnonymousModule() { public function getAnonymousModule() {
if (!$this->_anonModule) { if (!$this->_anonModule) {
$this->_anonModule = new HTMLPurifier_HTMLModule(); $this->_anonModule = new HTMLPurifier_HTMLModule();
$this->_anonModule->name = 'Anonymous'; $this->_anonModule->name = 'Anonymous';

View File

@ -116,10 +116,10 @@ class HTMLPurifier_HTMLModule
* element? * element?
* @param $attr What unique attributes does the element define? * @param $attr What unique attributes does the element define?
* @note See ElementDef for in-depth descriptions of these parameters. * @note See ElementDef for in-depth descriptions of these parameters.
* @return Reference to created element definition object, so you * @return Created element definition object, so you
* can set advanced parameters * can set advanced parameters
*/ */
public function &addElement($element, $type, $contents, $attr_includes = array(), $attr = array()) { public function addElement($element, $type, $contents, $attr_includes = array(), $attr = array()) {
$this->elements[] = $element; $this->elements[] = $element;
// parse content_model // parse content_model
list($content_model_type, $content_model) = $this->parseContents($contents); list($content_model_type, $content_model) = $this->parseContents($contents);
@ -140,9 +140,9 @@ class HTMLPurifier_HTMLModule
* Convenience function that creates a totally blank, non-standalone * Convenience function that creates a totally blank, non-standalone
* element. * element.
* @param $element Name of element to create * @param $element Name of element to create
* @return Reference to created element * @return Created element
*/ */
public function &addBlankElement($element) { public function addBlankElement($element) {
if (!isset($this->info[$element])) { if (!isset($this->info[$element])) {
$this->elements[] = $element; $this->elements[] = $element;
$this->info[$element] = new HTMLPurifier_ElementDef(); $this->info[$element] = new HTMLPurifier_ElementDef();

View File

@ -13,7 +13,7 @@ class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule
); );
public function __construct() { public function __construct() {
$bdo =& $this->addElement( $bdo = $this->addElement(
'bdo', 'Inline', 'Inline', array('Core', 'Lang'), 'bdo', 'Inline', 'Inline', array('Core', 'Lang'),
array( array(
'dir' => 'Enum#ltr,rtl', // required 'dir' => 'Enum#ltr,rtl', // required

View File

@ -9,7 +9,7 @@ class HTMLPurifier_HTMLModule_Hypertext extends HTMLPurifier_HTMLModule
public $name = 'Hypertext'; public $name = 'Hypertext';
public function __construct() { public function __construct() {
$a =& $this->addElement( $a = $this->addElement(
'a', 'Inline', 'Inline', 'Common', 'a', 'Inline', 'Inline', 'Common',
array( array(
// 'accesskey' => 'Character', // 'accesskey' => 'Character',

View File

@ -11,7 +11,7 @@ class HTMLPurifier_HTMLModule_Image extends HTMLPurifier_HTMLModule
public $name = 'Image'; public $name = 'Image';
public function __construct() { public function __construct() {
$img =& $this->addElement( $img = $this->addElement(
'img', 'Inline', 'Empty', 'Common', 'img', 'Inline', 'Empty', 'Common',
array( array(
'alt*' => 'Text', 'alt*' => 'Text',

View File

@ -49,40 +49,40 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule
$align = 'Enum#left,right,center,justify'; $align = 'Enum#left,right,center,justify';
$address =& $this->addBlankElement('address'); $address = $this->addBlankElement('address');
$address->content_model = 'Inline | #PCDATA | p'; $address->content_model = 'Inline | #PCDATA | p';
$address->content_model_type = 'optional'; $address->content_model_type = 'optional';
$address->child = false; $address->child = false;
$blockquote =& $this->addBlankElement('blockquote'); $blockquote = $this->addBlankElement('blockquote');
$blockquote->content_model = 'Flow | #PCDATA'; $blockquote->content_model = 'Flow | #PCDATA';
$blockquote->content_model_type = 'optional'; $blockquote->content_model_type = 'optional';
$blockquote->child = false; $blockquote->child = false;
$br =& $this->addBlankElement('br'); $br = $this->addBlankElement('br');
$br->attr['clear'] = 'Enum#left,all,right,none'; $br->attr['clear'] = 'Enum#left,all,right,none';
$caption =& $this->addBlankElement('caption'); $caption = $this->addBlankElement('caption');
$caption->attr['align'] = 'Enum#top,bottom,left,right'; $caption->attr['align'] = 'Enum#top,bottom,left,right';
$div =& $this->addBlankElement('div'); $div = $this->addBlankElement('div');
$div->attr['align'] = $align; $div->attr['align'] = $align;
$dl =& $this->addBlankElement('dl'); $dl = $this->addBlankElement('dl');
$dl->attr['compact'] = 'Bool#compact'; $dl->attr['compact'] = 'Bool#compact';
for ($i = 1; $i <= 6; $i++) { for ($i = 1; $i <= 6; $i++) {
$h =& $this->addBlankElement("h$i"); $h = $this->addBlankElement("h$i");
$h->attr['align'] = $align; $h->attr['align'] = $align;
} }
$hr =& $this->addBlankElement('hr'); $hr = $this->addBlankElement('hr');
$hr->attr['align'] = $align; $hr->attr['align'] = $align;
$hr->attr['noshade'] = 'Bool#noshade'; $hr->attr['noshade'] = 'Bool#noshade';
$hr->attr['size'] = 'Pixels'; $hr->attr['size'] = 'Pixels';
$hr->attr['width'] = 'Length'; $hr->attr['width'] = 'Length';
$img =& $this->addBlankElement('img'); $img = $this->addBlankElement('img');
$img->attr['align'] = 'Enum#top,middle,bottom,left,right'; $img->attr['align'] = 'Enum#top,middle,bottom,left,right';
$img->attr['border'] = 'Pixels'; $img->attr['border'] = 'Pixels';
$img->attr['hspace'] = 'Pixels'; $img->attr['hspace'] = 'Pixels';
@ -90,43 +90,43 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule
// figure out this integer business // figure out this integer business
$li =& $this->addBlankElement('li'); $li = $this->addBlankElement('li');
$li->attr['value'] = new HTMLPurifier_AttrDef_Integer(); $li->attr['value'] = new HTMLPurifier_AttrDef_Integer();
$li->attr['type'] = 'Enum#s:1,i,I,a,A,disc,square,circle'; $li->attr['type'] = 'Enum#s:1,i,I,a,A,disc,square,circle';
$ol =& $this->addBlankElement('ol'); $ol = $this->addBlankElement('ol');
$ol->attr['compact'] = 'Bool#compact'; $ol->attr['compact'] = 'Bool#compact';
$ol->attr['start'] = new HTMLPurifier_AttrDef_Integer(); $ol->attr['start'] = new HTMLPurifier_AttrDef_Integer();
$ol->attr['type'] = 'Enum#s:1,i,I,a,A'; $ol->attr['type'] = 'Enum#s:1,i,I,a,A';
$p =& $this->addBlankElement('p'); $p = $this->addBlankElement('p');
$p->attr['align'] = $align; $p->attr['align'] = $align;
$pre =& $this->addBlankElement('pre'); $pre = $this->addBlankElement('pre');
$pre->attr['width'] = 'Number'; $pre->attr['width'] = 'Number';
// script omitted // script omitted
$table =& $this->addBlankElement('table'); $table = $this->addBlankElement('table');
$table->attr['align'] = 'Enum#left,center,right'; $table->attr['align'] = 'Enum#left,center,right';
$table->attr['bgcolor'] = 'Color'; $table->attr['bgcolor'] = 'Color';
$tr =& $this->addBlankElement('tr'); $tr = $this->addBlankElement('tr');
$tr->attr['bgcolor'] = 'Color'; $tr->attr['bgcolor'] = 'Color';
$th =& $this->addBlankElement('th'); $th = $this->addBlankElement('th');
$th->attr['bgcolor'] = 'Color'; $th->attr['bgcolor'] = 'Color';
$th->attr['height'] = 'Length'; $th->attr['height'] = 'Length';
$th->attr['nowrap'] = 'Bool#nowrap'; $th->attr['nowrap'] = 'Bool#nowrap';
$th->attr['width'] = 'Length'; $th->attr['width'] = 'Length';
$td =& $this->addBlankElement('td'); $td = $this->addBlankElement('td');
$td->attr['bgcolor'] = 'Color'; $td->attr['bgcolor'] = 'Color';
$td->attr['height'] = 'Length'; $td->attr['height'] = 'Length';
$td->attr['nowrap'] = 'Bool#nowrap'; $td->attr['nowrap'] = 'Bool#nowrap';
$td->attr['width'] = 'Length'; $td->attr['width'] = 'Length';
$ul =& $this->addBlankElement('ul'); $ul = $this->addBlankElement('ul');
$ul->attr['compact'] = 'Bool#compact'; $ul->attr['compact'] = 'Bool#compact';
$ul->attr['type'] = 'Enum#square,disc,circle'; $ul->attr['type'] = 'Enum#square,disc,circle';

View File

@ -15,9 +15,9 @@ class HTMLPurifier_HTMLModule_Ruby extends HTMLPurifier_HTMLModule
'Common'); 'Common');
$this->addElement('rbc', false, 'Required: rb', 'Common'); $this->addElement('rbc', false, 'Required: rb', 'Common');
$this->addElement('rtc', false, 'Required: rt', 'Common'); $this->addElement('rtc', false, 'Required: rt', 'Common');
$rb =& $this->addElement('rb', false, 'Inline', 'Common'); $rb = $this->addElement('rb', false, 'Inline', 'Common');
$rb->excludes = array('ruby' => true); $rb->excludes = array('ruby' => true);
$rt =& $this->addElement('rt', false, 'Inline', 'Common', array('rbspan' => 'Number')); $rt = $this->addElement('rt', false, 'Inline', 'Common', array('rbspan' => 'Number'));
$rt->excludes = array('ruby' => true); $rt->excludes = array('ruby' => true);
$this->addElement('rp', false, 'Optional: #PCDATA', 'Common'); $this->addElement('rp', false, 'Optional: #PCDATA', 'Common');
} }

View File

@ -11,7 +11,7 @@ class HTMLPurifier_HTMLModule_Target extends HTMLPurifier_HTMLModule
public function __construct() { public function __construct() {
$elements = array('a'); $elements = array('a');
foreach ($elements as $name) { foreach ($elements as $name) {
$e =& $this->addBlankElement($name); $e = $this->addBlankElement($name);
$e->attr = array( $e->attr = array(
'target' => new HTMLPurifier_AttrDef_HTML_FrameTarget() 'target' => new HTMLPurifier_AttrDef_HTML_FrameTarget()
); );

View File

@ -42,7 +42,7 @@ class HTMLPurifier_HTMLModule_Text extends HTMLPurifier_HTMLModule
// Block Phrasal -------------------------------------------------- // Block Phrasal --------------------------------------------------
$this->addElement('address', 'Block', 'Inline', 'Common'); $this->addElement('address', 'Block', 'Inline', 'Common');
$this->addElement('blockquote', 'Block', 'Optional: Heading | Block | List', 'Common', array('cite' => 'URI') ); $this->addElement('blockquote', 'Block', 'Optional: Heading | Block | List', 'Common', array('cite' => 'URI') );
$pre =& $this->addElement('pre', 'Block', 'Inline', 'Common'); $pre = $this->addElement('pre', 'Block', 'Inline', 'Common');
$pre->excludes = $this->makeLookup( $pre->excludes = $this->makeLookup(
'img', 'big', 'small', 'object', 'applet', 'font', 'basefont' ); 'img', 'big', 'small', 'object', 'applet', 'font', 'basefont' );
$this->addElement('h1', 'Heading', 'Inline', 'Common'); $this->addElement('h1', 'Heading', 'Inline', 'Common');

View File

@ -128,14 +128,16 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
if (isset($params['element'])) { if (isset($params['element'])) {
$element = $params['element']; $element = $params['element'];
if (empty($this->info[$element])) { if (empty($this->info[$element])) {
$e =& $this->addBlankElement($element); $e = $this->addBlankElement($element);
} else { } else {
$e =& $this->info[$element]; $e = $this->info[$element];
} }
} else { } else {
$type = "info_$type"; $type = "info_$type";
$e =& $this; $e = $this;
} }
// PHP does some weird parsing when I do
// $e->$type[$attr], so I have to assign a ref.
$f =& $e->$type; $f =& $e->$type;
$f[$attr] = $fix; $f[$attr] = $fix;
break; break;
@ -146,9 +148,9 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
case 'content_model_type': case 'content_model_type':
$element = $params['element']; $element = $params['element'];
if (empty($this->info[$element])) { if (empty($this->info[$element])) {
$e =& $this->addBlankElement($element); $e = $this->addBlankElement($element);
} else { } else {
$e =& $this->info[$element]; $e = $this->info[$element];
} }
$e->$type = $fix; $e->$type = $fix;
break; break;

View File

@ -1,5 +1,9 @@
<?php <?php
/**
* Represents a language and defines localizable string formatting and
* other functions, as well as the localized messages for HTML Purifier.
*/
class HTMLPurifier_Language class HTMLPurifier_Language
{ {
@ -36,7 +40,7 @@ class HTMLPurifier_Language
public function __construct($config, $context) { public function __construct($config, $context) {
$this->config = $config; $this->config = $config;
$this->context =& $context; $this->context = $context;
} }
/** /**
@ -122,7 +126,7 @@ class HTMLPurifier_Language
// could be introduced for all types of tokens. This // could be introduced for all types of tokens. This
// may need to be factored out into a dedicated class // may need to be factored out into a dedicated class
if (!empty($value->attr)) { if (!empty($value->attr)) {
$stripped_token = $value->copy(); $stripped_token = clone $value;
$stripped_token->attr = array(); $stripped_token->attr = array();
$subst['$'.$i.'.Compact'] = $generator->generateFromToken($stripped_token); $subst['$'.$i.'.Compact'] = $generator->generateFromToken($stripped_token);
} }

View File

@ -53,7 +53,7 @@ class HTMLPurifier_LanguageFactory
* @param $prototype Optional prototype to overload sole instance with, * @param $prototype Optional prototype to overload sole instance with,
* or bool true to reset to default factory. * or bool true to reset to default factory.
*/ */
public static function &instance($prototype = null) { public static function instance($prototype = null) {
static $instance = null; static $instance = null;
if ($prototype !== null) { if ($prototype !== null) {
$instance = $prototype; $instance = $prototype;

View File

@ -11,7 +11,8 @@
* *
* A lexer is HTML-oriented: it might work with XML, but it's not * A lexer is HTML-oriented: it might work with XML, but it's not
* recommended, as we adhere to a subset of the specification for optimization * recommended, as we adhere to a subset of the specification for optimization
* reasons. * reasons. This might change in the future. Also, most tokenizers are not
* expected to handle DTDs or PIs.
* *
* This class should not be directly instantiated, but you may use create() to * This class should not be directly instantiated, but you may use create() to
* retrieve a default copy of the lexer. Being a supertype, this class * retrieve a default copy of the lexer. Being a supertype, this class
@ -20,7 +21,8 @@
* *
* @note The unit tests will instantiate this class for testing purposes, as * @note The unit tests will instantiate this class for testing purposes, as
* many of the utility functions require a class to be instantiated. * many of the utility functions require a class to be instantiated.
* Be careful when porting this class to PHP 5. * This means that, even though this class is not runnable, it will
* not be declared abstract.
* *
* @par * @par
* *
@ -28,18 +30,14 @@
* We use tokens rather than create a DOM representation because DOM would: * We use tokens rather than create a DOM representation because DOM would:
* *
* @par * @par
* -# Require more processing power to create, * -# Require more processing and memory to create,
* -# Require recursion to iterate, * -# Is not streamable, and
* -# Must be compatible with PHP 5's DOM (otherwise duplication), * -# Has the entire document structure (html and body not needed).
* -# Has the entire document structure (html and body not needed), and
* -# Has unknown readability improvement.
* *
* @par * @par
* What the last item means is that the functions for manipulating tokens are * However, DOM is helpful in that it makes it easy to move around nodes
* already fairly compact, and when well-commented, more abstraction may not * without a lot of lookaheads to see when a tag is closed. This is a
* be needed. * limitation of the token system and some workarounds would be nice.
*
* @see HTMLPurifier_Token
*/ */
class HTMLPurifier_Lexer class HTMLPurifier_Lexer
{ {
@ -49,22 +47,16 @@ class HTMLPurifier_Lexer
/** /**
* Retrieves or sets the default Lexer as a Prototype Factory. * Retrieves or sets the default Lexer as a Prototype Factory.
* *
* Depending on what PHP version you are running, the abstract base * By default HTMLPurifier_Lexer_DOMLex will be returned. There are
* Lexer class will determine which concrete Lexer is best for you: * a few exceptions involving special features that only DirectLex
* HTMLPurifier_Lexer_DirectLex for PHP 4, and HTMLPurifier_Lexer_DOMLex * implements.
* for PHP 5 and beyond. This general rule has a few exceptions to it
* involving special features that only DirectLex implements.
* *
* @note The behavior of this class has changed, rather than accepting * @note The behavior of this class has changed, rather than accepting
* a prototype object, it now accepts a configuration object. * a prototype object, it now accepts a configuration object.
* To specify your own prototype, set %Core.LexerImpl to it. * To specify your own prototype, set %Core.LexerImpl to it.
* This change in behavior de-singletonizes the lexer object. * This change in behavior de-singletonizes the lexer object.
* *
* @note In PHP4, it is possible to call this factory method from * @param $config Instance of HTMLPurifier_Config
* subclasses, such usage is not recommended and not
* forwards-compatible.
*
* @param $prototype Optional prototype lexer or configuration object
* @return Concrete lexer. * @return Concrete lexer.
*/ */
public static function create($config) { public static function create($config) {
@ -96,8 +88,9 @@ class HTMLPurifier_Lexer
break; break;
} }
if (version_compare(PHP_VERSION, "5", ">=") && // check for PHP5 if (class_exists('DOMDocument')) {
class_exists('DOMDocument')) { // check for DOM support // check for DOM support, because, surprisingly enough,
// it's *not* part of the core!
$lexer = 'DOMLex'; $lexer = 'DOMLex';
} else { } else {
$lexer = 'DirectLex'; $lexer = 'DirectLex';

View File

@ -1,6 +1,7 @@
<?php <?php
// OUT OF DATE, NEEDS UPDATING! // OUT OF DATE, NEEDS UPDATING!
// USE XMLWRITER!
class HTMLPurifier_Printer class HTMLPurifier_Printer
{ {

View File

@ -37,7 +37,7 @@ class HTMLPurifier_TagTransform_Font extends HTMLPurifier_TagTransform
public function transform($tag, $config, $context) { public function transform($tag, $config, $context) {
if ($tag instanceof HTMLPurifier_Token_End) { if ($tag instanceof HTMLPurifier_Token_End) {
$new_tag = $tag->copy(); $new_tag = clone $tag;
$new_tag->name = $this->transform_to; $new_tag->name = $this->transform_to;
return $new_tag; return $new_tag;
} }
@ -81,7 +81,7 @@ class HTMLPurifier_TagTransform_Font extends HTMLPurifier_TagTransform
$prepend_style; $prepend_style;
} }
$new_tag = $tag->copy(); $new_tag = clone $tag;
$new_tag->name = $this->transform_to; $new_tag->name = $this->transform_to;
$new_tag->attr = $attr; $new_tag->attr = $attr;

View File

@ -20,7 +20,7 @@ class HTMLPurifier_TagTransform_Simple extends HTMLPurifier_TagTransform
} }
public function transform($tag, $config, $context) { public function transform($tag, $config, $context) {
$new_tag = $tag->copy(); $new_tag = clone $tag;
$new_tag->name = $this->transform_to; $new_tag->name = $this->transform_to;
if (!is_null($this->style) && if (!is_null($this->style) &&
($new_tag instanceof HTMLPurifier_Token_Start || $new_tag instanceof HTMLPurifier_Token_Empty) ($new_tag instanceof HTMLPurifier_Token_Start || $new_tag instanceof HTMLPurifier_Token_Empty)

View File

@ -14,14 +14,6 @@ class HTMLPurifier_Token {
*/ */
public $armor = array(); public $armor = array();
/**
* Copies the tag into a new one (clone substitute).
* @return Copied token
*/
public function copy() {
return unserialize(serialize($this));
}
public function __get($n) { public function __get($n) {
if ($n === 'type') { if ($n === 'type') {
trigger_error('Deprecated type property called; use instanceof', E_USER_NOTICE); trigger_error('Deprecated type property called; use instanceof', E_USER_NOTICE);

View File

@ -1,15 +1,15 @@
<?php <?php
/** /**
* Factory for token generation (PHP 5 only). * Factory for token generation.
* *
* @note Doing some benchmarking indicates that the new operator is much * @note Doing some benchmarking indicates that the new operator is much
* slower than the clone operator (even discounting the cost of the * slower than the clone operator (even discounting the cost of the
* constructor). This class is for that optimization. We may want to * constructor). This class is for that optimization.
* consider porting this to PHP 4 by virtue of the fact it makes the code * Other then that, there's not much point as we don't
* easier to read. Other then that, there's not much point as we don't
* maintain parallel HTMLPurifier_Token hierarchies (the main reason why * maintain parallel HTMLPurifier_Token hierarchies (the main reason why
* you'd want to use an abstract factory). * you'd want to use an abstract factory).
* @todo Port DirectLex to use this
*/ */
class HTMLPurifier_TokenFactory class HTMLPurifier_TokenFactory
{ {

View File

@ -26,7 +26,7 @@ abstract class HTMLPurifier_URIFilter
/** /**
* Filter a URI object * Filter a URI object
* @param &$uri Reference to URI object * @param $uri Reference to URI object variable
* @param $config Instance of HTMLPurifier_Config * @param $config Instance of HTMLPurifier_Config
* @param $context Instance of HTMLPurifier_Context * @param $context Instance of HTMLPurifier_Context
* @return bool Whether or not to continue processing: false indicates * @return bool Whether or not to continue processing: false indicates

View File

@ -65,14 +65,31 @@ class HTMLPurifier_AttrDef_URITest extends HTMLPurifier_AttrDefHarness
$parser = new HTMLPurifier_URIParser(); $parser = new HTMLPurifier_URIParser();
$uri = $parser->parse('http://example.com'); $uri = $parser->parse('http://example.com');
$this->config->set('URI', 'DefinitionID', 'HTMLPurifier_AttrDef_URITest->testURIDefinitionValidation'); $this->config->set('URI', 'DefinitionID', 'HTMLPurifier_AttrDef_URITest->testURIDefinitionValidation');
$uri_def =& $this->config->getDefinition('URI');
// overload with mock
generate_mock_once('HTMLPurifier_URIDefinition'); generate_mock_once('HTMLPurifier_URIDefinition');
$uri_def = new HTMLPurifier_URIDefinitionMock(); $uri_def = new HTMLPurifier_URIDefinitionMock();
$uri_def->expectOnce('filter', array($uri, '*', '*')); $uri_def->expectOnce('filter', array($uri, '*', '*'));
$uri_def->setReturnValue('filter', true, array($uri, '*', '*')); $uri_def->setReturnValue('filter', true, array($uri, '*', '*'));
$uri_def->setup = true; $uri_def->setup = true;
// Since definitions are no longer passed by reference, we need
// to muck around with the cache to insert our mock. This is
// technically a little bad, since the cache shouldn't change
// behavior, but I don't feel too good about letting users
// overload entire definitions.
generate_mock_once('HTMLPurifier_DefinitionCache');
$cache_mock = new HTMLPurifier_DefinitionCacheMock();
$cache_mock->setReturnValue('get', $uri_def);
generate_mock_once('HTMLPurifier_DefinitionCacheFactory');
$factory_mock = new HTMLPurifier_DefinitionCacheFactoryMock();
$old = HTMLPurifier_DefinitionCacheFactory::instance();
HTMLPurifier_DefinitionCacheFactory::instance($factory_mock);
$factory_mock->setReturnValue('create', $cache_mock);
$this->assertDef('http://example.com'); $this->assertDef('http://example.com');
HTMLPurifier_DefinitionCacheFactory::instance($old);
} }
/* /*

View File

@ -11,7 +11,7 @@ class HTMLPurifier_AttrValidator_ErrorsTest extends HTMLPurifier_ErrorsHarness
function testAttributesTransformedGlobalPre() { function testAttributesTransformedGlobalPre() {
$this->config->set('HTML', 'DefinitionID', $this->config->set('HTML', 'DefinitionID',
'HTMLPurifier_AttrValidator_ErrorsTest::testAttributesTransformedGlobalPre'); 'HTMLPurifier_AttrValidator_ErrorsTest::testAttributesTransformedGlobalPre');
$def =& $this->config->getHTMLDefinition(true); $def = $this->config->getHTMLDefinition(true);
generate_mock_once('HTMLPurifier_AttrTransform'); generate_mock_once('HTMLPurifier_AttrTransform');
$transform = new HTMLPurifier_AttrTransformMock(); $transform = new HTMLPurifier_AttrTransformMock();
$input = array('original' => 'value'); $input = array('original' => 'value');

View File

@ -219,27 +219,25 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
$def = $config->getCSSDefinition(); $def = $config->getCSSDefinition();
$this->assertIsA($def, 'HTMLPurifier_CSSDefinition'); $this->assertIsA($def, 'HTMLPurifier_CSSDefinition');
$def =& $config->getHTMLDefinition(); $def = $config->getHTMLDefinition();
$def2 =& $config->getHTMLDefinition(); $def2 = $config->getHTMLDefinition();
$this->assertIsA($def, 'HTMLPurifier_HTMLDefinition'); $this->assertIsA($def, 'HTMLPurifier_HTMLDefinition');
$this->assertReference($def, $def2); $this->assertSame($def, $def2);
$this->assertTrue($def->setup); $this->assertTrue($def->setup);
// test re-calculation if HTML changes $old_def = clone $def2;
unset($def, $def2);
$def2 = $config->getHTMLDefinition(); // forcibly de-reference
$config->set('HTML', 'Doctype', 'HTML 4.01 Transitional'); $config->set('HTML', 'Doctype', 'HTML 4.01 Transitional');
$def = $config->getHTMLDefinition(); $def = $config->getHTMLDefinition();
$this->assertIsA($def, 'HTMLPurifier_HTMLDefinition'); $this->assertIsA($def, 'HTMLPurifier_HTMLDefinition');
$this->assertNotEqual($def, $def2); $this->assertNotEqual($def, $old_def);
$this->assertTrue($def->setup); $this->assertTrue($def->setup);
// test retrieval of raw definition // test retrieval of raw definition
$config->set('HTML', 'DefinitionID', 'HTMLPurifier_ConfigTest->test_getHTMLDefinition()'); $config->set('HTML', 'DefinitionID', 'HTMLPurifier_ConfigTest->test_getHTMLDefinition()');
$config->set('HTML', 'DefinitionRev', 3); $config->set('HTML', 'DefinitionRev', 3);
$def =& $config->getHTMLDefinition(true); $def = $config->getHTMLDefinition(true);
$this->assertNotEqual($def, $def2); $this->assertNotEqual($def, $old_def);
$this->assertEqual(false, $def->setup); $this->assertEqual(false, $def->setup);
// auto initialization // auto initialization
@ -250,8 +248,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
function test_getHTMLDefinition_rawError() { function test_getHTMLDefinition_rawError() {
$config = HTMLPurifier_Config::createDefault(); $config = HTMLPurifier_Config::createDefault();
$this->expectError('Cannot retrieve raw version without specifying %HTML.DefinitionID'); $this->expectException(new HTMLPurifier_Exception('Cannot retrieve raw version without specifying %HTML.DefinitionID'));
$def =& $config->getHTMLDefinition(true); $def = $config->getHTMLDefinition(true);
} }
function test_getCSSDefinition() { function test_getCSSDefinition() {
@ -265,7 +263,7 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
$this->schema->add('Cache', 'DefinitionImpl', null, 'string', true); $this->schema->add('Cache', 'DefinitionImpl', null, 'string', true);
$this->schema->addNamespace('Crust', 'Krusty Krabs'); $this->schema->addNamespace('Crust', 'Krusty Krabs');
$config = new HTMLPurifier_Config($this->schema); $config = new HTMLPurifier_Config($this->schema);
$this->expectError("Definition of Crust type not supported"); $this->expectException(new HTMLPurifier_Exception("Definition of Crust type not supported"));
$config->getDefinition('Crust'); $config->getDefinition('Crust');
} }

View File

@ -7,7 +7,7 @@ class HTMLPurifier_DoctypeRegistryTest extends HTMLPurifier_Harness
$registry = new HTMLPurifier_DoctypeRegistry(); $registry = new HTMLPurifier_DoctypeRegistry();
$d =& $registry->register( $d = $registry->register(
$name = 'XHTML 1.0 Transitional', $name = 'XHTML 1.0 Transitional',
$xml = true, $xml = true,
$modules = array('module-one', 'module-two'), $modules = array('module-one', 'module-two'),
@ -18,10 +18,10 @@ class HTMLPurifier_DoctypeRegistryTest extends HTMLPurifier_Harness
$d2 = new HTMLPurifier_Doctype($name, $xml, $modules, $tidyModules, $aliases); $d2 = new HTMLPurifier_Doctype($name, $xml, $modules, $tidyModules, $aliases);
$this->assertIdentical($d, $d2); $this->assertIdentical($d, $d2);
$this->assertReference($d, $registry->get('XHTML 1.0 Transitional')); $this->assertSame($d, $registry->get('XHTML 1.0 Transitional'));
// test shorthand // test shorthand
$d =& $registry->register( $d = $registry->register(
$name = 'XHTML 1.0 Strict', true, 'module', 'Tidy', 'X10S' $name = 'XHTML 1.0 Strict', true, 'module', 'Tidy', 'X10S'
); );
$d2 = new HTMLPurifier_Doctype($name, true, array('module'), array('Tidy'), array('X10S')); $d2 = new HTMLPurifier_Doctype($name, true, array('module'), array('Tidy'), array('X10S'));
@ -49,26 +49,26 @@ class HTMLPurifier_DoctypeRegistryTest extends HTMLPurifier_Harness
$registry = new HTMLPurifier_DoctypeRegistry(); $registry = new HTMLPurifier_DoctypeRegistry();
$d1 =& $registry->register('Doc1', true, array(), array(), array('1')); $d1 = $registry->register('Doc1', true, array(), array(), array('1'));
$this->assertReference($d1, $registry->get('Doc1')); $this->assertSame($d1, $registry->get('Doc1'));
$this->assertReference($d1, $registry->get('1')); $this->assertSame($d1, $registry->get('1'));
$d2 =& $registry->register('Doc2', true, array(), array(), array('2')); $d2 = $registry->register('Doc2', true, array(), array(), array('2'));
$this->assertReference($d2, $registry->get('Doc2')); $this->assertSame($d2, $registry->get('Doc2'));
$this->assertReference($d2, $registry->get('2')); $this->assertSame($d2, $registry->get('2'));
$d3 =& $registry->register('1', true, array(), array(), array()); $d3 = $registry->register('1', true, array(), array(), array());
// literal name overrides alias // literal name overrides alias
$this->assertReference($d3, $registry->get('1')); $this->assertSame($d3, $registry->get('1'));
$d4 =& $registry->register('One', true, array(), array(), array('1')); $d4 = $registry->register('One', true, array(), array(), array('1'));
$this->assertReference($d4, $registry->get('One')); $this->assertSame($d4, $registry->get('One'));
// still it overrides // still it overrides
$this->assertReference($d3, $registry->get('1')); $this->assertSame($d3, $registry->get('1'));
} }

View File

@ -75,7 +75,7 @@ a[href|title]
$config = HTMLPurifier_Config::create(array( $config = HTMLPurifier_Config::create(array(
'HTML.DefinitionID' => 'HTMLPurifier_HTMLDefinitionTest->test_addAttribute' 'HTML.DefinitionID' => 'HTMLPurifier_HTMLDefinitionTest->test_addAttribute'
)); ));
$def =& $config->getHTMLDefinition(true); $def = $config->getHTMLDefinition(true);
$def->addAttribute('span', 'custom', 'Enum#attribute'); $def->addAttribute('span', 'custom', 'Enum#attribute');
$purifier = new HTMLPurifier($config); $purifier = new HTMLPurifier($config);
@ -90,7 +90,7 @@ a[href|title]
$config = HTMLPurifier_Config::create(array( $config = HTMLPurifier_Config::create(array(
'HTML.DefinitionID' => 'HTMLPurifier_HTMLDefinitionTest->test_addAttribute_multiple' 'HTML.DefinitionID' => 'HTMLPurifier_HTMLDefinitionTest->test_addAttribute_multiple'
)); ));
$def =& $config->getHTMLDefinition(true); $def = $config->getHTMLDefinition(true);
$def->addAttribute('span', 'custom', 'Enum#attribute'); $def->addAttribute('span', 'custom', 'Enum#attribute');
$def->addAttribute('span', 'foo', 'Text'); $def->addAttribute('span', 'foo', 'Text');
@ -106,7 +106,7 @@ a[href|title]
$config = HTMLPurifier_Config::create(array( $config = HTMLPurifier_Config::create(array(
'HTML.DefinitionID' => 'HTMLPurifier_HTMLDefinitionTest->test_addElement' 'HTML.DefinitionID' => 'HTMLPurifier_HTMLDefinitionTest->test_addElement'
)); ));
$def =& $config->getHTMLDefinition(true); $def = $config->getHTMLDefinition(true);
$def->addElement('marquee', 'Inline', 'Inline', 'Common', array('width' => 'Length')); $def->addElement('marquee', 'Inline', 'Inline', 'Common', array('width' => 'Length'));
$purifier = new HTMLPurifier($config); $purifier = new HTMLPurifier($config);

View File

@ -206,7 +206,7 @@ class HTMLPurifier_HTMLModule_TidyTest extends HTMLPurifier_Harness
)); ));
$module2 = new HTMLPurifier_HTMLModule_Tidy(); $module2 = new HTMLPurifier_HTMLModule_Tidy();
$e =& $module2->addBlankElement('element'); $e = $module2->addBlankElement('element');
$e->attr_transform_pre['attr'] = $attr; $e->attr_transform_pre['attr'] = $attr;
$e->attr_transform_post['attr'] = $attr_post; $e->attr_transform_post['attr'] = $attr_post;
$e->child = $child; $e->child = $child;

View File

@ -18,7 +18,7 @@ class HTMLPurifier_HTMLModuleTest extends HTMLPurifier_Harness
function test_addElement() { function test_addElement() {
$module = new HTMLPurifier_HTMLModule(); $module = new HTMLPurifier_HTMLModule();
$def =& $module->addElement( $def = $module->addElement(
'a', 'Inline', 'Optional: #PCDATA', array('Common'), 'a', 'Inline', 'Optional: #PCDATA', array('Common'),
array( array(
'href' => 'URI' 'href' => 'URI'
@ -107,7 +107,7 @@ class HTMLPurifier_HTMLModuleTest extends HTMLPurifier_Harness
function test_addBlankElement() { function test_addBlankElement() {
$module = new HTMLPurifier_HTMLModule(); $module = new HTMLPurifier_HTMLModule();
$def =& $module->addBlankElement('a'); $def = $module->addBlankElement('a');
$def2 = new HTMLPurifier_ElementDef(); $def2 = new HTMLPurifier_ElementDef();
$def2->standalone = false; $def2->standalone = false;

View File

@ -83,7 +83,7 @@ alert(&lt;b&gt;bold&lt;/b&gt;);
$this->config->set('HTML', 'DefinitionID', $this->config->set('HTML', 'DefinitionID',
'HTMLPurifier_Strategy_RemoveForeignElementsTest'. 'HTMLPurifier_Strategy_RemoveForeignElementsTest'.
'->testRequiredAttributesTestNotPerformedOnEndTag'); '->testRequiredAttributesTestNotPerformedOnEndTag');
$def =& $this->config->getHTMLDefinition(true); $def = $this->config->getHTMLDefinition(true);
$def->addElement('f', 'Block', 'Optional: #PCDATA', false, array('req*' => 'Text')); $def->addElement('f', 'Block', 'Optional: #PCDATA', false, array('req*' => 'Text'));
$this->assertResult('<f req="text">Foo</f> Bar'); $this->assertResult('<f req="text">Foo</f> Bar');
} }

View File

@ -92,7 +92,7 @@ require 'HTMLPurifier/Harness.php';
// Now, userland code begins to be executed // Now, userland code begins to be executed
// setup special DefinitionCacheFactory decorator // setup special DefinitionCacheFactory decorator
$factory =& HTMLPurifier_DefinitionCacheFactory::instance(); $factory = HTMLPurifier_DefinitionCacheFactory::instance();
$factory->addDecorator('Memory'); // since we deal with a lot of config objects $factory->addDecorator('Memory'); // since we deal with a lot of config objects
if (!$AC['disable-phpt']) { if (!$AC['disable-phpt']) {