mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-08-04 21:28:06 +02:00
Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
587d642826 | ||
|
0bef016271 | ||
|
ef6a1c9274 | ||
|
86b1da9b6f | ||
|
00ea2062d4 | ||
|
cb5d5d0648 | ||
|
77ce3e8b4a | ||
|
e0c0d8eab6 | ||
|
ce46fb618c | ||
|
9f37764614 | ||
|
aaf6ba421c | ||
|
4b862f64e6 | ||
|
be2cfb7918 | ||
|
2f29c27a59 | ||
|
144bd6f07a | ||
|
a95f600e76 | ||
|
84aa2ca390 | ||
|
1f8619cda5 | ||
|
04b1ec33cb | ||
|
6d9643a92e | ||
|
438d973073 | ||
|
f295465ad4 | ||
|
eaabccdd9b | ||
|
893cdd0301 | ||
|
1ba77fedd4 | ||
|
fae720115a | ||
|
c0f2e69c9f | ||
|
ca6b20ff2b | ||
|
c4aa3ee40c | ||
|
e9c7873057 | ||
|
d45f42e6a8 | ||
|
f46aef698e |
2
Doxyfile
2
Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 3.1.0rc1
|
||||
PROJECT_NUMBER = 3.1.0
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
@@ -17,7 +17,7 @@ ce document pour quelques choses.
|
||||
|
||||
1. Compatibilité
|
||||
|
||||
HTML Purifier fonctionne dans PHP 5. PHP 5.0.0 est le dernier
|
||||
HTML Purifier fonctionne dans PHP 5. PHP 5.0.5 est le dernier
|
||||
version que je le testais. Il ne dépend de les autre librairies.
|
||||
|
||||
Les extensions optionnel est iconv (en général déjà installer) et
|
||||
@@ -34,19 +34,15 @@ Utilisez:
|
||||
...quand vous devez utiliser HTML Purifier (ne inclure pas quand vous
|
||||
ne devez pas, parce que HTML Purifier est trés grand.)
|
||||
|
||||
Si vous n'aime pas que HTML Purifier change vos include_path, on peut
|
||||
change vos include_path, et:
|
||||
HTML Purifier utilise 'autoload'. Si vous avez définu la fonction
|
||||
__autoload, vous doivez ajoute cet programme:
|
||||
|
||||
require_once 'HTMLPurifier.php';
|
||||
spl_autoload_register('__autoload')
|
||||
|
||||
Seuleument les contents dans library/ est essentiel; vous peut enlever
|
||||
les autre fichiers quand vous est dans une atmosphère professionnel.
|
||||
Plus d'information est dans le document 'INSTALL'.
|
||||
|
||||
|
||||
[En cours de construction]
|
||||
|
||||
|
||||
6. Installation vite
|
||||
3. Installation vite
|
||||
|
||||
Si votre site web est en UTF-8 et XHTML Transitional, utilisez:
|
||||
|
||||
|
54
NEWS
54
NEWS
@@ -9,6 +9,60 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
. Internal change
|
||||
==========================
|
||||
|
||||
3.1.0, released 2008-05-18
|
||||
# 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()
|
||||
# Printer_ConfigForm's get*() functions were static-ified
|
||||
# %HTML.ForbiddenAttributes requires attribute declarations to be in the
|
||||
form of tag@attr, NOT tag.attr (which will throw an error and won't do
|
||||
anything). This is for forwards compatibility with XML; you'd do best
|
||||
to migrate an %HTML.AllowedAttributes directives to this syntax too.
|
||||
! Allow index to be false for config from form creation
|
||||
! Added HTMLPurifier::VERSION constant
|
||||
! Commas, not dashes, used for serializer IDs. This change is forwards-compatible
|
||||
and allows for version numbers like "3.1.0-dev".
|
||||
! %HTML.Allowed deals gracefully with whitespace anywhere, anytime!
|
||||
! HTML Purifier's URI handling is a lot more robust, with much stricter
|
||||
validation checks and better percent encoding handling.
|
||||
! Bootstrap autoloader deals more robustly with classes that don't exist,
|
||||
preventing class_exists($class, true) from barfing.
|
||||
- InterchangeBuilder now alphabetizes its lists
|
||||
- Validation error in configdoc output fixed
|
||||
- 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
|
||||
- HTMLPurifier::instance() created for consistency, is equivalent to getInstance()
|
||||
- Fixed and revamped broken ConfigForm smoketest
|
||||
- Bug with bool/null fields in Printer_ConfigForm fixed
|
||||
- Bug with global forbidden attributes fixed
|
||||
- Improved error messages for allowed and forbidden HTML elements and attributes
|
||||
- Missing (or null) in configdoc documentation restored
|
||||
- If DOM throws and exception during parsing with PH5P (occurs in newer versions
|
||||
of DOM), HTML Purifier punts to DirectLex
|
||||
- Fatal error with unserialization of ScriptRequired
|
||||
- Created directories are now chmod'ed properly
|
||||
- Fixed bug with fallback languages in LanguageFactory
|
||||
- Standalone testing setup properly with autoload
|
||||
. Out-of-date documentation revised
|
||||
. UTF-8 encoding check optimization as suggested by Diego
|
||||
. HTMLPurifier_Error removed in favor of exceptions
|
||||
. More copy() function removed; should use clone instead
|
||||
. More extensive unit tests for HTMLDefinition
|
||||
. assertPurification moved to central harness
|
||||
. HTMLPurifier_Generator accepts $config and $context parameters during
|
||||
instantiation, not runtime
|
||||
. Double-quotes outside of attribute values are now unescaped
|
||||
|
||||
3.1.0rc1, released 2008-04-22
|
||||
# Autoload support added. Internal require_once's removed in favor of an
|
||||
explicit require list or autoloading. To use HTML Purifier,
|
||||
|
118
TODO
118
TODO
@@ -7,48 +7,32 @@ TODO List
|
||||
? Maybe I'll Do It
|
||||
==========================
|
||||
|
||||
If no interest is expressed for a feature that may required a considerable
|
||||
If no interest is expressed for a feature that may require a considerable
|
||||
amount of effort to implement, it may get endlessly delayed. Do not be
|
||||
afraid to cast your vote for the next feature to be implemented!
|
||||
|
||||
|
||||
UPCOMING RELEASE
|
||||
----------------
|
||||
|
||||
IMPORTANT
|
||||
- Release candidate, because of the major changes
|
||||
|
||||
DOCUMENTATION
|
||||
- Update French translation of README
|
||||
|
||||
IMPORTANT FEATURES
|
||||
- Factor out command line parser into its own class, and unit test it
|
||||
|
||||
NICE FEATURES
|
||||
- Factor demo.php into a set of Printer classes, and then create a stub
|
||||
file for users here (inside the actual HTML Purifier library)
|
||||
- Support exporting configuration, so users can easily tweak settings
|
||||
in the demo, and then copy-paste into their own setup
|
||||
|
||||
BUGS
|
||||
- Style attribute height/width limiting for images
|
||||
- Easy way to blacklist elements and attributes
|
||||
- Investigate iconv error emitting
|
||||
- Investigate UTF-8 optimization <http://htmlpurifier.org/phorum/read.php?3,1496>
|
||||
- Figure out what to do about target="" and name="", since they show up so often
|
||||
- Implement validation for query and for fragment
|
||||
|
||||
FUTURE VERSIONS
|
||||
---------------
|
||||
|
||||
3.2 release [Error'ed]
|
||||
# Error logging for filtering/cleanup procedures
|
||||
- XSS-attempt detection
|
||||
3.2 release [It's All About Trust] (floating)
|
||||
# Implement untrusted, dangerous elements/attributes
|
||||
- Objects and Forms are especially wanted
|
||||
# Implement IDREF support (harder than it seems, since you cannot have
|
||||
IDREFs to non-existent IDs)
|
||||
# Frameset XHTML 1.0 and HTML 4.01 doctypes
|
||||
- Research and implement a "safe" version of the Object module
|
||||
|
||||
3.3 release [Do What I Mean, Not What I Say]
|
||||
3.3 release [Error'ed]
|
||||
# Error logging for filtering/cleanup procedures
|
||||
- XSS-attempt detection--certain errors are flagged XSS-like
|
||||
|
||||
3.4 release [Do What I Mean, Not What I Say]
|
||||
# Additional support for poorly written HTML
|
||||
- Microsoft Word HTML cleaning (i.e. MsoNormal, but research essential!)
|
||||
- Friendly strict handling of <address> (block -> <br>)
|
||||
- Remove redundant tags, ex. <u><u>Underlined</u></u>. Implementation notes:
|
||||
? Remove redundant tags, ex. <u><u>Underlined</u></u>. Implementation notes:
|
||||
1. Analyzing which tags to remove duplicants
|
||||
2. Ensure attributes are merged into the parent tag
|
||||
3. Extend the tag exclusion system to specify whether or not the
|
||||
@@ -58,27 +42,21 @@ FUTURE VERSIONS
|
||||
- Remove empty inline tags<i></i>
|
||||
- Append something to duplicate IDs so they're still usable (impl. note: the
|
||||
dupe detector would also need to detect the suffix as well)
|
||||
- Externalize inline CSS to promote clean HTML
|
||||
|
||||
3.4 release [It's All About Trust] (floating)
|
||||
# Implement untrusted, dangerous elements/attributes
|
||||
- Objects and Forms are especially wanted
|
||||
# Implement IDREF support (harder than it seems, since you cannot have
|
||||
IDREFs to non-existent IDs)
|
||||
# Frameset XHTML 1.0 and HTML 4.01 doctypes
|
||||
- Externalize inline CSS to promote clean HTML, proposed by Sander Tekelenburg
|
||||
|
||||
4.0 release [Beyond HTML]
|
||||
# Legit token based CSS parsing (will require revamping almost every
|
||||
AttrDef class). Probably will use CSSTidy class
|
||||
# More control over allowed CSS properties (maybe modularize it in the
|
||||
same fashion!)
|
||||
AttrDef class). Probably will use CSSTidy class?
|
||||
# More control over allowed CSS properties using a modularization
|
||||
# HTML 5 support
|
||||
# IRI support
|
||||
- Standardize token armor for all areas of processing
|
||||
- Convert RTL/LTR override characters to <bdo> tags, or vice versa on demand.
|
||||
Also, enable disabling of directionality
|
||||
- Table of Contents generation (XHTML Compiler might be reusable)
|
||||
|
||||
5.0 release [To XML and Beyond]
|
||||
- AllowedAttributes and ForbiddenAttributes step on the toes of XML by
|
||||
using periods; this needs to be changed.
|
||||
- Extended HTML capabilities based on namespacing and tag transforms (COMPLEX)
|
||||
- Hooks for adding custom processors to custom namespaced tags and
|
||||
attributes, offer default implementation
|
||||
@@ -86,45 +64,63 @@ FUTURE VERSIONS
|
||||
|
||||
Ongoing
|
||||
- More refactoring to take advantage of PHP5's facilities
|
||||
- Lots of profiling, make it faster!
|
||||
- Refactor unit tests into lots of test methods
|
||||
- Plugins for major CMSes (COMPLEX)
|
||||
- phpBB
|
||||
- Drupal needs loving!
|
||||
- Phorum need loving!
|
||||
- more! (look for ones that use WYSIWYGs)
|
||||
- Complete basic smoketests
|
||||
- Also, maybe a FAQ for extension writers with HTML Purifier
|
||||
|
||||
AutoFormat
|
||||
- Smileys
|
||||
- Syntax highlighting with <pre> and possibly <?php
|
||||
- Syntax highlighting (with GeSHi) with <pre> and possibly <?php
|
||||
- Look at http://drupal.org/project/Modules/category/63 for ideas
|
||||
|
||||
Unknown release (on a scratch-an-itch basis)
|
||||
# CHMOD install script for PEAR installs
|
||||
? Have 'lang' attribute be checked against official lists, achieved by
|
||||
encoding all characters that have string entity equivalents
|
||||
- Abstract ChildDef_BlockQuote to work with all elements that only
|
||||
allow blocks in them, required or optional
|
||||
- Reorganize Unit Tests
|
||||
Optimizations
|
||||
- Reduce size of internal data-structures (esp. HTMLDefinition)
|
||||
- Research memory usage of objects versus arrays
|
||||
- Combine multiple strategies into a single, single-pass strategy
|
||||
- Get PH5P working with the latest versions of DOM, which have much more
|
||||
stringent error checking procedures. Maybe convert straight to tokens.
|
||||
- Get rid of set_include_path(). Save this for another major release.
|
||||
|
||||
Neat feature related
|
||||
! Factor demo.php into a set of Printer classes, and then create a stub
|
||||
file for users here (inside the actual HTML Purifier library)
|
||||
! Support exporting configuration, so users can easily tweak settings
|
||||
in the demo, and then copy-paste into their own setup
|
||||
- Advanced URI filtering schemes (see docs/proposal-new-directives.txt)
|
||||
- Implement lenient <ruby> child validation
|
||||
- Allow scoped="scoped" attribute in <style> tags; may be troublesome
|
||||
because regular CSS has no way of uniquely identifying nodes, so we'd
|
||||
have to generate IDs
|
||||
- Explain how to use HTML Purifier in non-PHP languages / create
|
||||
a simple command line stub (or complicated?)
|
||||
- Fixes for Firefox's inability to handle COL alignment props (Bug 915)
|
||||
- Automatically add non-breaking spaces to empty table cells when
|
||||
empty-cells:show is applied to have compatibility with Internet Explorer
|
||||
- Table of Contents generation (XHTML Compiler might be reusable). May also
|
||||
be out-of-band information.
|
||||
- Full set of color keywords. Also, a way to add onto them without
|
||||
finalizing the configuration object.
|
||||
- Write a var_export and memcached DefinitionCache - Denis
|
||||
|
||||
Maintenance related (slightly boring)
|
||||
# CHMOD install script for PEAR installs
|
||||
! Factor out command line parser into its own class, and unit test it
|
||||
! Nested configuration namespaces
|
||||
- Distinguish between default settings and explicitly set settings, so
|
||||
configurations can be merged
|
||||
- Nested configuration namespaces
|
||||
- Allow scoped="scoped" attribute in <style> tags; may be troublesome
|
||||
because regular CSS has no way of uniquely identifying nodes, so we'd
|
||||
have to generate IDs
|
||||
- Time PHPT tests
|
||||
|
||||
Requested
|
||||
ChildDef related (very boring)
|
||||
- Abstract ChildDef_BlockQuote to work with all elements that only
|
||||
allow blocks in them, required or optional
|
||||
- Implement lenient <ruby> child validation
|
||||
|
||||
Wontfix
|
||||
- Non-lossy smart alternate character encoding transformations (unless
|
||||
patch provided)
|
||||
- Pretty-printing HTML: users can use Tidy on the output on entire page
|
||||
- Native content compression, whitespace stripping (don't rely on Tidy, make
|
||||
sure we don't remove from <pre> or related tags): use gzip if this is
|
||||
- Native content compression, whitespace stripping: use gzip if this is
|
||||
really important
|
||||
|
18
WHATSNEW
18
WHATSNEW
@@ -1,8 +1,10 @@
|
||||
Release 3.1.0rc1 is a release candidate aimed primarily at ironing out bugs
|
||||
in HTML Purifier's shiny new __autoload system. There are lots of new features,
|
||||
however; some notable ones include support for the !important CSS modifier,
|
||||
display and visibility CSS properties with %CSS.AllowTricky, marquee
|
||||
with %HTML.Proprietary (had you scared for a moment, hmm?), a kses() wrapper,
|
||||
%CSS.AllowedProperties, %HTML.ForbiddenAttributes and %HTML.ForbiddenElements
|
||||
and a totally revamped ConfigDoc system. And of course, the usual slew of
|
||||
bugfixes.
|
||||
HTML Purifier 3.1.0 is the second release series for HTML Purifier on PHP 5
|
||||
as well as a security update related to URIs. It shifts over to using
|
||||
autoload, and also includes support for the !important CSS modifier,
|
||||
display and visibility CSS properties with %CSS.AllowTricky, marquee with
|
||||
%HTML.Proprietary (had you scared for a moment, hmm?), a kses() wrapper,
|
||||
%CSS.AllowedProperties, %HTML.ForbiddenAttributes and
|
||||
%HTML.ForbiddenElements and a totally revamped ConfigDoc system. Since the
|
||||
release candidate, there have also been a number of stability fixes such as
|
||||
improved URI escaping, a change in serializer ID format, and a relaxed
|
||||
format for %HTML.Allowed. And as always, numerous bugfixes.
|
||||
|
@@ -15,7 +15,7 @@ TODO:
|
||||
- add blurbs to ToC
|
||||
*/
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.2.0', '<')) exit('PHP 5.2.0 or greater required.');
|
||||
if (version_compare(PHP_VERSION, '5.2', '<')) exit('PHP 5.2+ required.');
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
chdir(dirname(__FILE__));
|
||||
@@ -38,6 +38,7 @@ $configdoc_xml = 'configdoc.xml';
|
||||
$xml_builder = new HTMLPurifier_ConfigSchema_Builder_Xml();
|
||||
$xml_builder->openURI($configdoc_xml);
|
||||
$xml_builder->build($interchange);
|
||||
unset($xml_builder); // free handle
|
||||
|
||||
$xslt = new ConfigDoc_HTMLXSLTProcessor();
|
||||
$xslt->importStylesheet(dirname(__FILE__) . "/styles/$style.xsl");
|
||||
|
@@ -227,7 +227,7 @@
|
||||
</tr>
|
||||
</xsl:template>
|
||||
<xsl:template match="constraints/external/project">
|
||||
<xsl:value-of select="." />
|
||||
<li><xsl:value-of select="." /></li>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<line>131</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>93</line>
|
||||
<line>85</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||
<line>50</line>
|
||||
@@ -18,22 +18,22 @@
|
||||
</directive>
|
||||
<directive id="CSS.Proprietary">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>201</line>
|
||||
<line>202</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowTricky">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>205</line>
|
||||
<line>206</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowImportant">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>209</line>
|
||||
<line>210</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowedProperties">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>261</line>
|
||||
<line>262</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Cache.DefinitionImpl">
|
||||
@@ -63,19 +63,19 @@
|
||||
</directive>
|
||||
<directive id="Core.Encoding">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>267</line>
|
||||
<line>285</line>
|
||||
<line>281</line>
|
||||
<line>305</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Test.ForceNoIconv">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>269</line>
|
||||
<line>290</line>
|
||||
<line>283</line>
|
||||
<line>310</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.EscapeNonASCIICharacters">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>287</line>
|
||||
<line>307</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.MaintainLineNumbers">
|
||||
@@ -83,7 +83,7 @@
|
||||
<line>81</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>90</line>
|
||||
<line>82</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||
<line>45</line>
|
||||
@@ -91,17 +91,17 @@
|
||||
</directive>
|
||||
<directive id="Output.CommentScriptContents">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>40</line>
|
||||
<line>41</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.TidyFormat">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>61</line>
|
||||
<line>70</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.Newline">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>86</line>
|
||||
<line>84</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.BlockWrapper">
|
||||
@@ -131,12 +131,12 @@
|
||||
</directive>
|
||||
<directive id="HTML.ForbiddenElements">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>303</line>
|
||||
<line>328</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.ForbiddenAttributes">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>304</line>
|
||||
<line>329</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Trusted">
|
||||
@@ -144,7 +144,7 @@
|
||||
<line>198</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>245</line>
|
||||
<line>238</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||
<line>34</line>
|
||||
@@ -172,17 +172,17 @@
|
||||
</directive>
|
||||
<directive id="Core.Language">
|
||||
<file name="HTMLPurifier/LanguageFactory.php">
|
||||
<line>85</line>
|
||||
<line>88</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.LexerImpl">
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>78</line>
|
||||
<line>70</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.ConvertDocumentToFragment">
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>237</line>
|
||||
<line>230</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.Host">
|
||||
@@ -215,12 +215,12 @@
|
||||
</directive>
|
||||
<directive id="URI.Disable">
|
||||
<file name="HTMLPurifier/AttrDef/URI.php">
|
||||
<line>24</line>
|
||||
<line>23</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.Munge">
|
||||
<file name="HTMLPurifier/AttrDef/URI.php">
|
||||
<line>78</line>
|
||||
<line>68</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.ColorKeywords">
|
||||
|
@@ -367,7 +367,7 @@ Test.Example</pre>
|
||||
For example, <code>HTMLPurifier_ConfigSchema_Builder_ConfigSchema</code>
|
||||
generates a runtime <code>HTMLPurifier_ConfigSchema</code> object,
|
||||
which <code>HTMLPurifier_Config</code> uses to validate its incoming
|
||||
data. There is also a planned documentation builder.
|
||||
data. There is also an XML serializer, which is used to build documentation.
|
||||
</p>
|
||||
|
||||
<div id="version">$Id$</div>
|
||||
|
@@ -158,7 +158,7 @@
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML', 'DefinitionRev', 1);
|
||||
$def =& $config->getHTMLDefinition(true);</pre>
|
||||
$def = $config->getHTMLDefinition(true);</pre>
|
||||
|
||||
<p>
|
||||
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', 'DefinitionRev', 1);
|
||||
<strong>$config->set('Core', 'DefinitionCache', null); // remove this later!</strong>
|
||||
$def =& $config->getHTMLDefinition(true);</pre>
|
||||
$def = $config->getHTMLDefinition(true);</pre>
|
||||
|
||||
<p>
|
||||
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', 'DefinitionRev', 1);
|
||||
$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>
|
||||
|
||||
<p>
|
||||
@@ -388,7 +388,7 @@ $def =& $config->getHTMLDefinition(true);
|
||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML', 'DefinitionRev', 1);
|
||||
$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(
|
||||
array('_blank','_self','_target','_top')
|
||||
));</strong></pre>
|
||||
@@ -735,11 +735,11 @@ $def =& $config->getHTMLDefinition(true);
|
||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML', 'DefinitionRev', 1);
|
||||
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
||||
$def =& $config->getHTMLDefinition(true);
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||
array('_blank','_self','_target','_top')
|
||||
));
|
||||
<strong>$form =& $def->addElement(
|
||||
<strong>$form = $def->addElement(
|
||||
'form', // name
|
||||
'Block', // content set
|
||||
'Flow', // allowed children
|
||||
|
@@ -35,7 +35,7 @@
|
||||
{
|
||||
public $name = '<strong>NameOfFilter</strong>';
|
||||
public function prepare($config) {}
|
||||
public function filter(&$uri, $config, &$context) {}
|
||||
public function filter(&$uri, $config, $context) {}
|
||||
}</pre>
|
||||
|
||||
<p>
|
||||
@@ -60,8 +60,8 @@
|
||||
public function HTMLPurifier_URI($scheme, $userinfo, $host, $port, $path, $query, $fragment);
|
||||
public function toString();
|
||||
public function copy();
|
||||
public function getSchemeObj($config, &$context);
|
||||
public function validate($config, &$context);
|
||||
public function getSchemeObj($config, $context);
|
||||
public function validate($config, $context);
|
||||
}</pre>
|
||||
|
||||
<p>
|
||||
@@ -139,7 +139,7 @@
|
||||
<pre>class HTMLPurifier_URIFilter_ConvertIDNToPunycode extends HTMLPurifier_URIFilter
|
||||
{
|
||||
public $name = 'ConvertIDNToPunycode';
|
||||
public function filter(&$uri, $config, &$context) {
|
||||
public function filter(&$uri, $config, $context) {
|
||||
if (is_null($uri->host)) return true;
|
||||
if ($uri->host == utf8_decode($uri->host)) {
|
||||
// is ASCII, abort
|
||||
@@ -163,7 +163,7 @@
|
||||
to use it. Fortunately, this part's simple:
|
||||
</p>
|
||||
|
||||
<pre>$uri =& $config->getDefinition('URI');
|
||||
<pre>$uri = $config->getDefinition('URI');
|
||||
$uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pre>
|
||||
|
||||
<p>
|
||||
@@ -177,7 +177,7 @@ $uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pr
|
||||
'URI', '<strong>NameOfFilter</strong>', false, 'bool',
|
||||
'<strong>What your filter does.</strong>'
|
||||
);
|
||||
$uri =& $config->getDefinition('URI', true);
|
||||
$uri = $config->getDefinition('URI', true);
|
||||
$uri->registerFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());
|
||||
</pre>
|
||||
|
||||
|
@@ -75,9 +75,7 @@ passes through HTML Purifier <em>unharmed</em>.
|
||||
<p>And the corresponding usage:</p>
|
||||
|
||||
<pre><?php
|
||||
// assuming $purifier is an instance of HTMLPurifier
|
||||
require_once 'HTMLPurifier/Filter/YouTube.php';
|
||||
$purifier->addFilter(new HTMLPurifier_Filter_YouTube());
|
||||
$config->set('Filter', 'YouTube', true);
|
||||
?></pre>
|
||||
|
||||
<p>There is a bit going in the two code snippets, so let's explain.</p>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
|
||||
* FILE, changes will be overwritten the next time the script is run.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @version 3.1.0
|
||||
*
|
||||
* @warning
|
||||
* You must *not* include any other HTML Purifier files before this file,
|
||||
@@ -41,7 +41,6 @@ require 'HTMLPurifier/ElementDef.php';
|
||||
require 'HTMLPurifier/Encoder.php';
|
||||
require 'HTMLPurifier/EntityLookup.php';
|
||||
require 'HTMLPurifier/EntityParser.php';
|
||||
require 'HTMLPurifier/Error.php';
|
||||
require 'HTMLPurifier/ErrorCollector.php';
|
||||
require 'HTMLPurifier/Exception.php';
|
||||
require 'HTMLPurifier/Filter.php';
|
||||
@@ -82,6 +81,7 @@ require 'HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Border.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Color.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Composite.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Filter.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Font.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||
@@ -116,6 +116,7 @@ require 'HTMLPurifier/AttrTransform/ImgSpace.php';
|
||||
require 'HTMLPurifier/AttrTransform/Lang.php';
|
||||
require 'HTMLPurifier/AttrTransform/Length.php';
|
||||
require 'HTMLPurifier/AttrTransform/Name.php';
|
||||
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||
require 'HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require 'HTMLPurifier/ChildDef/Custom.php';
|
||||
require 'HTMLPurifier/ChildDef/Empty.php';
|
||||
|
@@ -15,13 +15,11 @@
|
||||
* -# Generating HTML from the purified tokens.
|
||||
*
|
||||
* However, most users will only need to interface with the HTMLPurifier
|
||||
* class, so this massive amount of infrastructure is usually concealed.
|
||||
* If you plan on working with the internals, be sure to include
|
||||
* HTMLPurifier_ConfigSchema and HTMLPurifier_Config.
|
||||
* and HTMLPurifier_Config.
|
||||
*/
|
||||
|
||||
/*
|
||||
HTML Purifier 3.1.0rc1 - Standards Compliant HTML Filtering
|
||||
HTML Purifier 3.1.0 - Standards Compliant HTML Filtering
|
||||
Copyright (C) 2006-2008 Edward Z. Yang
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
@@ -57,7 +55,10 @@ class HTMLPurifier
|
||||
{
|
||||
|
||||
/** Version of HTML Purifier */
|
||||
public $version = '3.1.0rc1';
|
||||
public $version = '3.1.0';
|
||||
|
||||
/** Constant with version of HTML Purifier */
|
||||
const VERSION = '3.1.0';
|
||||
|
||||
/** Global configuration object */
|
||||
public $config;
|
||||
@@ -89,7 +90,6 @@ class HTMLPurifier
|
||||
$this->config = HTMLPurifier_Config::create($config);
|
||||
|
||||
$this->strategy = new HTMLPurifier_Strategy_Core();
|
||||
$this->generator = new HTMLPurifier_Generator();
|
||||
|
||||
}
|
||||
|
||||
@@ -123,8 +123,8 @@ class HTMLPurifier
|
||||
|
||||
$context = new HTMLPurifier_Context();
|
||||
|
||||
// our friendly neighborhood generator, all primed with configuration too!
|
||||
$this->generator->generateFromTokens(array(), $config, $context);
|
||||
// setup HTML generator
|
||||
$this->generator = new HTMLPurifier_Generator($config, $context);
|
||||
$context->register('Generator', $this->generator);
|
||||
|
||||
// set up global context variables
|
||||
@@ -177,8 +177,7 @@ class HTMLPurifier
|
||||
$html, $config, $context
|
||||
),
|
||||
$config, $context
|
||||
),
|
||||
$config, $context
|
||||
)
|
||||
);
|
||||
|
||||
for ($i = $filter_size - 1; $i >= 0; $i--) {
|
||||
@@ -209,9 +208,10 @@ class HTMLPurifier
|
||||
/**
|
||||
* Singleton for enforcing just one HTML Purifier in your system
|
||||
* @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 ($prototype instanceof HTMLPurifier) {
|
||||
self::$instance = $prototype;
|
||||
@@ -224,4 +224,11 @@ class HTMLPurifier
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Backwards compatibility, see instance()
|
||||
*/
|
||||
public static function getInstance($prototype = null) {
|
||||
return HTMLPurifier::instance($prototype);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -35,7 +35,6 @@ require_once $__dir . '/HTMLPurifier/ElementDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/Encoder.php';
|
||||
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
|
||||
require_once $__dir . '/HTMLPurifier/EntityParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/Error.php';
|
||||
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
|
||||
require_once $__dir . '/HTMLPurifier/Exception.php';
|
||||
require_once $__dir . '/HTMLPurifier/Filter.php';
|
||||
@@ -76,6 +75,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Border.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Color.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Composite.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Filter.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Font.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||
@@ -110,6 +110,7 @@ require_once $__dir . '/HTMLPurifier/AttrTransform/ImgSpace.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
|
||||
|
@@ -70,9 +70,10 @@ abstract class HTMLPurifier_AttrDef
|
||||
* @return Created AttrDef object corresponding to $string
|
||||
*/
|
||||
public function make($string) {
|
||||
// default implementation, return flyweight of this object
|
||||
// if overloaded, it is *necessary* for you to clone the
|
||||
// object (usually by instantiating a new copy) and return that
|
||||
// default implementation, return a flyweight of this object.
|
||||
// If $string has an effect on the returned object (i.e. you
|
||||
// need to overload this method), it is best
|
||||
// to clone or instantiate new copies. (Instantiation is safer.)
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
26
library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php
Normal file
26
library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Decorator which enables CSS properties to be disabled for specific elements.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
|
||||
{
|
||||
protected $def, $element;
|
||||
|
||||
/**
|
||||
* @param $def Definition to wrap
|
||||
* @param $element Element to deny
|
||||
*/
|
||||
public function __construct($def, $element) {
|
||||
$this->def = $def;
|
||||
$this->element = $element;
|
||||
}
|
||||
/**
|
||||
* Checks if CurrentToken is set and equal to $this->element
|
||||
*/
|
||||
public function validate($string, $config, $context) {
|
||||
$token = $context->get('CurrentToken', true);
|
||||
if ($token && $token->name == $this->element) return false;
|
||||
return $this->def->validate($string, $config, $context);
|
||||
}
|
||||
}
|
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Decorator which enables !important to be used in CSS values.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_ImportantDecorator
|
||||
class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef
|
||||
{
|
||||
protected $def, $allow;
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
protected $parser, $percentEncoder;
|
||||
protected $parser;
|
||||
protected $embedsResource;
|
||||
|
||||
/**
|
||||
@@ -15,7 +15,6 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||
*/
|
||||
public function __construct($embeds_resource = false) {
|
||||
$this->parser = new HTMLPurifier_URIParser();
|
||||
$this->percentEncoder = new HTMLPurifier_PercentEncoder();
|
||||
$this->embedsResource = (bool) $embeds_resource;
|
||||
}
|
||||
|
||||
@@ -23,9 +22,7 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||
|
||||
if ($config->get('URI', 'Disable')) return false;
|
||||
|
||||
// initial operations
|
||||
$uri = $this->parseCDATA($uri);
|
||||
$uri = $this->percentEncoder->normalize($uri);
|
||||
|
||||
// parse the URI
|
||||
$uri = $this->parser->parse($uri);
|
||||
@@ -42,7 +39,7 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||
if (!$result) break;
|
||||
|
||||
// chained filtering
|
||||
$uri_def =& $config->getDefinition('URI');
|
||||
$uri_def = $config->getDefinition('URI');
|
||||
$result = $uri_def->filter($uri, $config, $context);
|
||||
if (!$result) break;
|
||||
|
||||
@@ -61,13 +58,6 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||
$context->destroy('EmbeddedURI');
|
||||
if (!$ok) return false;
|
||||
|
||||
// munge scheme off if necessary (this must be last)
|
||||
if (!is_null($uri->scheme) && is_null($uri->host)) {
|
||||
if ($uri_def->defaultScheme == $uri->scheme) {
|
||||
$uri->scheme = null;
|
||||
}
|
||||
}
|
||||
|
||||
// back to string
|
||||
$result = $uri->toString();
|
||||
|
||||
|
@@ -36,11 +36,23 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
|
||||
$ipv4 = $this->ipv4->validate($string, $config, $context);
|
||||
if ($ipv4 !== false) return $ipv4;
|
||||
|
||||
// validate a domain name here, do filtering, etc etc etc
|
||||
// A regular domain name.
|
||||
|
||||
// We could use this, but it would break I18N domain names
|
||||
//$match = preg_match('/^[a-z0-9][\w\-\.]*[a-z0-9]$/i', $string);
|
||||
//if (!$match) return false;
|
||||
// This breaks I18N domain names, but we don't have proper IRI support,
|
||||
// so force users to insert Punycode. If there's complaining we'll
|
||||
// try to fix things into an international friendly form.
|
||||
|
||||
// The productions describing this are:
|
||||
$a = '[a-z]'; // alpha
|
||||
$an = '[a-z0-9]'; // alphanum
|
||||
$and = '[a-z0-9-]'; // alphanum | "-"
|
||||
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
|
||||
$domainlabel = "$an($and*$an)?";
|
||||
// toplabel = alpha | alpha *( alphanum | "-" ) alphanum
|
||||
$toplabel = "$a($and*$an)?";
|
||||
// hostname = *( domainlabel "." ) toplabel [ "." ]
|
||||
$match = preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string);
|
||||
if (!$match) return false;
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
14
library/HTMLPurifier/AttrTransform/ScriptRequired.php
Normal file
14
library/HTMLPurifier/AttrTransform/ScriptRequired.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements required attribute stipulation for <script>
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_ScriptRequired extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
public function transform($attr, $config, $context) {
|
||||
if (!isset($attr['type'])) {
|
||||
$attr['type'] = 'text/javascript';
|
||||
}
|
||||
return $attr;
|
||||
}
|
||||
}
|
@@ -37,7 +37,7 @@ class HTMLPurifier_Bootstrap
|
||||
public static function autoload($class) {
|
||||
$file = HTMLPurifier_Bootstrap::getPath($class);
|
||||
if (!$file) return false;
|
||||
require $file;
|
||||
require HTMLPURIFIER_PREFIX . '/' . $file;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -48,11 +48,13 @@ class HTMLPurifier_Bootstrap
|
||||
if (strncmp('HTMLPurifier', $class, 12) !== 0) return false;
|
||||
// Custom implementations
|
||||
if (strncmp('HTMLPurifier_Language_', $class, 22) === 0) {
|
||||
$code = str_replace('_', '-', substr($class, 22));
|
||||
return 'HTMLPurifier/Language/classes/' . $code . '.php';
|
||||
$code = str_replace('_', '-', substr($class, 22));
|
||||
$file = 'HTMLPurifier/Language/classes/' . $code . '.php';
|
||||
} else {
|
||||
$file = str_replace('_', '/', $class) . '.php';
|
||||
}
|
||||
// Standard implementation
|
||||
return str_replace('_', '/', $class) . '.php';
|
||||
if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) return false;
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -150,12 +150,13 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
||||
));
|
||||
|
||||
$this->info['width'] =
|
||||
$this->info['height'] =
|
||||
$this->info['height'] =
|
||||
new HTMLPurifier_AttrDef_CSS_DenyElementDecorator(
|
||||
new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||
new HTMLPurifier_AttrDef_CSS_Length(true),
|
||||
new HTMLPurifier_AttrDef_CSS_Percentage(true),
|
||||
new HTMLPurifier_AttrDef_Enum(array('auto'))
|
||||
));
|
||||
)), 'img');
|
||||
|
||||
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* 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.
|
||||
@@ -34,9 +34,7 @@ class HTMLPurifier_ChildDef
|
||||
* @return bool false to remove parent node
|
||||
* @return array of replacement child tokens
|
||||
*/
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
trigger_error('Call to abstract function', E_USER_ERROR);
|
||||
}
|
||||
abstract public function validateChildren($tokens_of_children, $config, $context);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -20,7 +20,7 @@ class HTMLPurifier_Config
|
||||
/**
|
||||
* HTML Purifier's version
|
||||
*/
|
||||
public $version = '3.1.0rc1';
|
||||
public $version = '3.1.0';
|
||||
|
||||
/**
|
||||
* Bool indicator whether or not to automatically finalize
|
||||
@@ -72,7 +72,7 @@ class HTMLPurifier_Config
|
||||
* @param $definition HTMLPurifier_ConfigSchema that defines what directives
|
||||
* are allowed.
|
||||
*/
|
||||
public function __construct(&$definition) {
|
||||
public function __construct($definition) {
|
||||
$this->conf = $definition->defaults; // set up, copy in defaults
|
||||
$this->def = $definition; // keep a copy around for checking
|
||||
$this->parser = new HTMLPurifier_VarParser_Flexible();
|
||||
@@ -107,7 +107,7 @@ class HTMLPurifier_Config
|
||||
* @return Default HTMLPurifier_Config object.
|
||||
*/
|
||||
public static function createDefault() {
|
||||
$definition =& HTMLPurifier_ConfigSchema::instance();
|
||||
$definition = HTMLPurifier_ConfigSchema::instance();
|
||||
$config = new HTMLPurifier_Config($definition);
|
||||
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
|
||||
* called before it's been setup, otherwise won't work.
|
||||
*/
|
||||
public function &getHTMLDefinition($raw = false) {
|
||||
$def =& $this->getDefinition('HTML', $raw);
|
||||
return $def; // prevent PHP 4.4.0 from complaining
|
||||
public function getHTMLDefinition($raw = false) {
|
||||
return $this->getDefinition('HTML', $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
$def =& $this->getDefinition('CSS', $raw);
|
||||
return $def;
|
||||
public function getCSSDefinition($raw = false) {
|
||||
return $this->getDefinition('CSS', $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,7 +276,7 @@ class HTMLPurifier_Config
|
||||
* @param $type Type of definition: HTML, CSS, etc
|
||||
* @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();
|
||||
$factory = HTMLPurifier_DefinitionCacheFactory::instance();
|
||||
$cache = $factory->create($type, $this);
|
||||
@@ -310,17 +310,13 @@ class HTMLPurifier_Config
|
||||
} elseif ($type == 'URI') {
|
||||
$this->definitions[$type] = new HTMLPurifier_URIDefinition();
|
||||
} else {
|
||||
trigger_error("Definition of $type type not supported");
|
||||
$false = false;
|
||||
return $false;
|
||||
throw new HTMLPurifier_Exception("Definition of $type type not supported");
|
||||
}
|
||||
// quick abort if raw
|
||||
if ($raw) {
|
||||
if (is_null($this->get($type, 'DefinitionID'))) {
|
||||
// fatally error out if definition ID not set
|
||||
trigger_error("Cannot retrieve raw version without specifying %$type.DefinitionID", E_USER_ERROR);
|
||||
$false = new HTMLPurifier_Error();
|
||||
return $false;
|
||||
throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID");
|
||||
}
|
||||
return $this->definitions[$type];
|
||||
}
|
||||
@@ -407,7 +403,7 @@ class HTMLPurifier_Config
|
||||
* @param $mq_fix Boolean whether or not to enable magic quotes fix
|
||||
* @param $schema Instance of HTMLPurifier_ConfigSchema to use, if not global copy
|
||||
*/
|
||||
public static function loadArrayFromForm($array, $index, $allowed = true, $mq_fix = true, $schema = null) {
|
||||
public static function loadArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) {
|
||||
$ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema);
|
||||
$config = HTMLPurifier_Config::create($ret, $schema);
|
||||
return $config;
|
||||
@@ -417,7 +413,7 @@ class HTMLPurifier_Config
|
||||
* Merges in configuration values from $_GET/$_POST to object. NOT STATIC.
|
||||
* @note Same parameters as loadArrayFromForm
|
||||
*/
|
||||
public function mergeArrayFromForm($array, $index, $allowed = true, $mq_fix = true) {
|
||||
public function mergeArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true) {
|
||||
$ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def);
|
||||
$this->loadArray($ret);
|
||||
}
|
||||
@@ -426,8 +422,8 @@ class HTMLPurifier_Config
|
||||
* Prepares an array from a form into something usable for the more
|
||||
* strict parts of HTMLPurifier_Config
|
||||
*/
|
||||
public static function prepareArrayFromForm($array, $index, $allowed = true, $mq_fix = true, $schema = null) {
|
||||
$array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array();
|
||||
public static function prepareArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) {
|
||||
if ($index !== false) $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array();
|
||||
$mq = $mq_fix && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc();
|
||||
|
||||
$allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema);
|
||||
|
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Base class for configuration entity
|
||||
*/
|
||||
class HTMLPurifier_ConfigDef {
|
||||
abstract class HTMLPurifier_ConfigDef {
|
||||
public $class = false;
|
||||
}
|
||||
|
||||
|
@@ -40,7 +40,7 @@ class HTMLPurifier_ConfigSchema {
|
||||
/**
|
||||
* Retrieves an instance of the application-wide configuration definition.
|
||||
*/
|
||||
public static function &instance($prototype = null) {
|
||||
public static function instance($prototype = null) {
|
||||
if ($prototype !== null) {
|
||||
HTMLPurifier_ConfigSchema::$singleton = $prototype;
|
||||
} elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) {
|
||||
@@ -104,9 +104,8 @@ class HTMLPurifier_ConfigSchema {
|
||||
* @param $allowed Lookup array of allowed values
|
||||
*/
|
||||
public function addAllowedValues($namespace, $name, $allowed) {
|
||||
$directive =& $this->info[$namespace][$name];
|
||||
$type = $directive->type;
|
||||
$directive->allowed = $allowed;
|
||||
$type = $this->info[$namespace][$name]->type;
|
||||
$this->info[$namespace][$name]->allowed = $allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,21 +129,21 @@ class HTMLPurifier_ConfigSchema {
|
||||
$type = $type_values[0];
|
||||
$modifier = isset($type_values[1]) ? $type_values[1] : false;
|
||||
$allow_null = ($modifier === 'null');
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->add($namespace, $name, $default, $type, $allow_null);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addNamespace() */
|
||||
public static function defineNamespace($namespace, $description) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addNamespace($namespace);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addValueAliases() */
|
||||
public static function defineValueAliases($namespace, $name, $aliases) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addValueAliases($namespace, $name, $aliases);
|
||||
}
|
||||
|
||||
@@ -155,14 +154,14 @@ class HTMLPurifier_ConfigSchema {
|
||||
foreach ($allowed_values as $value) {
|
||||
$allowed[$value] = true;
|
||||
}
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addAllowedValues($namespace, $name, $allowed);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addAlias() */
|
||||
public static function defineAlias($namespace, $name, $new_namespace, $new_name) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addAlias($namespace, $name, $new_namespace, $new_name);
|
||||
}
|
||||
|
||||
|
@@ -71,8 +71,10 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
|
||||
|
||||
$this->startElement('constraints');
|
||||
if ($directive->version) $this->writeElement('version', $directive->version);
|
||||
$this->writeElement('type', $directive->type);
|
||||
if ($directive->typeAllowsNull) $this->writeAttribute('allow-null', 'yes');
|
||||
$this->startElement('type');
|
||||
if ($directive->typeAllowsNull) $this->writeAttribute('allow-null', 'yes');
|
||||
$this->text($directive->type);
|
||||
$this->endElement(); // type
|
||||
if ($directive->allowed) {
|
||||
$this->startElement('allowed');
|
||||
foreach ($directive->allowed as $value => $x) $this->writeElement('value', $value);
|
||||
|
@@ -17,21 +17,27 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
|
||||
$builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder();
|
||||
$interchange = new HTMLPurifier_ConfigSchema_Interchange();
|
||||
|
||||
if (!$dir) $dir = realpath(dirname(__FILE__) . '/schema/');
|
||||
if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema/';
|
||||
$info = parse_ini_file($dir . 'info.ini');
|
||||
$interchange->name = $info['name'];
|
||||
|
||||
$files = array();
|
||||
$dh = opendir($dir);
|
||||
while (false !== ($file = readdir($dh))) {
|
||||
if (!$file || $file[0] == '.' || strrchr($file, '.') !== '.txt') {
|
||||
continue;
|
||||
}
|
||||
$files[] = $file;
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
sort($files);
|
||||
foreach ($files as $file) {
|
||||
$builder->build(
|
||||
$interchange,
|
||||
new HTMLPurifier_StringHash( $parser->parseFile($dir . $file) )
|
||||
);
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
return $interchange;
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@@ -21,3 +21,17 @@ $styles = $purifier->context->get('StyleBlocks');
|
||||
foreach ($styles as $style) {
|
||||
echo '<style type="text/css">' . $style . "</style>\n";
|
||||
}]]></pre>
|
||||
<p>
|
||||
<strong>Warning:</strong> It is possible for a user to mount an
|
||||
imagecrash attack using this CSS. Counter-measures are difficult;
|
||||
it is not simply enough to limit the range of CSS lengths (using
|
||||
relative lengths with many nesting levels allows for large values
|
||||
to be attained without actually specifying them in the stylesheet),
|
||||
and the flexible nature of selectors makes it difficult to selectively
|
||||
disable lengths on image tags (HTML Purifier, however, does disable
|
||||
CSS width and height in inline styling). There are probably two effective
|
||||
counter measures: an explicit width and height set to auto in all
|
||||
images in your document (unlikely) or the disabling of width and
|
||||
height (somewhat reasonable). Whether or not these measures should be
|
||||
used is left to the reader.
|
||||
</p>
|
||||
|
@@ -4,7 +4,17 @@ VERSION: 3.1.0
|
||||
DEFAULT: array()
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
This directive complements %HTML.ForbiddenElements and is the inverse of
|
||||
%HTML.AllowedAttributes. Please see the former for a discussion of why you
|
||||
While this directive is similar to %HTML.AllowedAttributes, for
|
||||
forwards-compatibility with XML, this attribute has a different syntax. Instead of
|
||||
<code>tag.attr</code>, use <code>tag@attr</code>. To disallow <code>href</code>
|
||||
attributes in <code>a</code> tags, set this directive to
|
||||
<code>a@href</code>. You can also disallow an attribute globally with
|
||||
<code>attr</code> or <code>*@attr</code> (either syntax is fine; the latter
|
||||
is provided for consistency with %HTML.AllowedAttributes).
|
||||
</p>
|
||||
<p>
|
||||
<strong>Warning:</strong> This directive complements %HTML.ForbiddenElements,
|
||||
accordingly, check
|
||||
out that directive for a discussion of why you
|
||||
should think twice before using this directive.
|
||||
</p>
|
||||
|
@@ -4,6 +4,8 @@
|
||||
* Registry object that contains information about the current context.
|
||||
* @warning Is a bit buggy when variables are set to null: it thinks
|
||||
* 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
|
||||
{
|
||||
@@ -16,7 +18,7 @@ class HTMLPurifier_Context
|
||||
/**
|
||||
* Registers a variable into the context.
|
||||
* @param $name String name
|
||||
* @param $ref Variable to be registered
|
||||
* @param $ref Reference to variable to be registered
|
||||
*/
|
||||
public function register($name, &$ref) {
|
||||
if (isset($this->_storage[$name])) {
|
||||
|
@@ -26,8 +26,8 @@ abstract class HTMLPurifier_DefinitionCache
|
||||
* @param Instance of HTMLPurifier_Config
|
||||
*/
|
||||
public function generateKey($config) {
|
||||
return $config->version . '-' . // possibly replace with function calls
|
||||
$config->getBatchSerial($this->type) . '-' .
|
||||
return $config->version . ',' . // possibly replace with function calls
|
||||
$config->getBatchSerial($this->type) . ',' .
|
||||
$config->get($this->type, 'DefinitionRev');
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ abstract class HTMLPurifier_DefinitionCache
|
||||
* @param $config Instance of HTMLPurifier_Config to test against
|
||||
*/
|
||||
public function isOld($key, $config) {
|
||||
if (substr_count($key, '-') < 2) return true;
|
||||
list($version, $hash, $revision) = explode('-', $key, 3);
|
||||
if (substr_count($key, ',') < 2) return true;
|
||||
list($version, $hash, $revision) = explode(',', $key, 3);
|
||||
$compare = version_compare($version, $config->version);
|
||||
// version mismatch, is always old
|
||||
if ($compare != 0) return true;
|
||||
|
@@ -100,18 +100,7 @@ class HTMLPurifier_DefinitionCache_Serializer extends
|
||||
* @return Number of bytes written if success, or false if failure.
|
||||
*/
|
||||
private function _write($file, $data) {
|
||||
static $file_put_contents;
|
||||
if ($file_put_contents === null) {
|
||||
$file_put_contents = function_exists('file_put_contents');
|
||||
}
|
||||
if ($file_put_contents) {
|
||||
return file_put_contents($file, $data);
|
||||
}
|
||||
$fh = fopen($file, 'w');
|
||||
if (!$fh) return false;
|
||||
$status = fwrite($fh, $data);
|
||||
fclose($fh);
|
||||
return $status;
|
||||
return file_put_contents($file, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +119,9 @@ class HTMLPurifier_DefinitionCache_Serializer extends
|
||||
} elseif (!$this->_testPermissions($base)) {
|
||||
return false;
|
||||
}
|
||||
$old = umask(0022); // disable group and world writes
|
||||
mkdir($directory);
|
||||
umask($old);
|
||||
} elseif (!$this->_testPermissions($directory)) {
|
||||
return false;
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ class HTMLPurifier_DefinitionCacheFactory
|
||||
/**
|
||||
* Retrieves an instance of global definition cache factory.
|
||||
*/
|
||||
public static function &instance($prototype = null) {
|
||||
public static function instance($prototype = null) {
|
||||
static $instance;
|
||||
if ($prototype !== null) {
|
||||
$instance = $prototype;
|
||||
@@ -45,11 +45,10 @@ class HTMLPurifier_DefinitionCacheFactory
|
||||
* @param $name Name of definitions handled by cache
|
||||
* @param $config Instance of HTMLPurifier_Config
|
||||
*/
|
||||
public function &create($type, $config) {
|
||||
public function create($type, $config) {
|
||||
$method = $config->get('Cache', 'DefinitionImpl');
|
||||
if ($method === null) {
|
||||
$null = new HTMLPurifier_DefinitionCache_Null($type);
|
||||
return $null;
|
||||
return new HTMLPurifier_DefinitionCache_Null($type);
|
||||
}
|
||||
if (!empty($this->caches[$method][$type])) {
|
||||
return $this->caches[$method][$type];
|
||||
|
@@ -21,9 +21,9 @@ class HTMLPurifier_DoctypeRegistry
|
||||
* @param $modules Modules doctype will load
|
||||
* @param $modules_for_modes Modules doctype will load for certain modes
|
||||
* @param $aliases Alias names for doctype
|
||||
* @return Reference to registered doctype (usable for further editing)
|
||||
* @return Editable registered doctype
|
||||
*/
|
||||
public function ®ister($doctype, $xml = true, $modules = array(),
|
||||
public function register($doctype, $xml = true, $modules = array(),
|
||||
$tidy_modules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null
|
||||
) {
|
||||
if (!is_array($modules)) $modules = array($modules);
|
||||
@@ -34,7 +34,7 @@ class HTMLPurifier_DoctypeRegistry
|
||||
$doctype, $xml, $modules, $tidy_modules, $aliases, $dtd_public, $dtd_system
|
||||
);
|
||||
}
|
||||
$this->doctypes[$doctype->name] =& $doctype;
|
||||
$this->doctypes[$doctype->name] = $doctype;
|
||||
$name = $doctype->name;
|
||||
// hookup aliases
|
||||
foreach ($doctype->aliases as $alias) {
|
||||
@@ -51,9 +51,9 @@ class HTMLPurifier_DoctypeRegistry
|
||||
* @note This function resolves aliases
|
||||
* @note When possible, use the more fully-featured make()
|
||||
* @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->doctypes[$doctype])) {
|
||||
trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR);
|
||||
|
@@ -14,6 +14,11 @@ class HTMLPurifier_Encoder
|
||||
trigger_error('Cannot instantiate encoder, call methods statically', E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error-handler that mutes errors, alternative to shut-up operator.
|
||||
*/
|
||||
private static function muteErrorHandler() {}
|
||||
|
||||
/**
|
||||
* Cleans a UTF-8 string for well-formedness and SGML validity
|
||||
*
|
||||
@@ -57,9 +62,18 @@ class HTMLPurifier_Encoder
|
||||
static $iconv = null;
|
||||
if ($iconv === null) $iconv = function_exists('iconv');
|
||||
|
||||
// UTF-8 validity is checked since PHP 4.3.5
|
||||
// This is an optimization: if the string is already valid UTF-8, no
|
||||
// need to do iconv/php stuff. 99% of the time, this will be the case.
|
||||
if (preg_match('/^.{1}/us', $str)) {
|
||||
return strtr($str, $non_sgml_chars);
|
||||
}
|
||||
|
||||
if ($iconv && !$force_php) {
|
||||
// do the shortcut way
|
||||
$str = @iconv('UTF-8', 'UTF-8//IGNORE', $str);
|
||||
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
||||
$str = iconv('UTF-8', 'UTF-8//IGNORE', $str);
|
||||
restore_error_handler();
|
||||
return strtr($str, $non_sgml_chars);
|
||||
}
|
||||
|
||||
@@ -267,9 +281,15 @@ class HTMLPurifier_Encoder
|
||||
$encoding = $config->get('Core', 'Encoding');
|
||||
if ($encoding === 'utf-8') return $str;
|
||||
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') {
|
||||
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);
|
||||
}
|
||||
@@ -288,9 +308,15 @@ class HTMLPurifier_Encoder
|
||||
$str = HTMLPurifier_Encoder::convertToASCIIDumbLossless($str);
|
||||
}
|
||||
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') {
|
||||
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);
|
||||
}
|
||||
|
@@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Return object from functions that signifies error when null doesn't cut it
|
||||
*/
|
||||
class HTMLPurifier_Error {}
|
||||
|
@@ -15,7 +15,7 @@ class HTMLPurifier_ErrorCollector
|
||||
public function __construct($context) {
|
||||
$this->locale =& $context->get('Locale');
|
||||
$this->generator =& $context->get('Generator');
|
||||
$this->context =& $context;
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -11,81 +11,79 @@ class HTMLPurifier_Generator
|
||||
{
|
||||
|
||||
/**
|
||||
* Bool cache of %HTML.XHTML
|
||||
* @private
|
||||
* Whether or not generator should produce XML output
|
||||
*/
|
||||
private $_xhtml = true;
|
||||
|
||||
/**
|
||||
* Bool cache of %Output.CommentScriptContents
|
||||
* @private
|
||||
* :HACK: Whether or not generator should comment the insides of <script> tags
|
||||
*/
|
||||
private $_scriptFix = false;
|
||||
|
||||
/**
|
||||
* Cache of HTMLDefinition
|
||||
* @private
|
||||
* Cache of HTMLDefinition during HTML output to determine whether or
|
||||
* not attributes should be minimized.
|
||||
*/
|
||||
private $_def;
|
||||
|
||||
/**
|
||||
* Configuration for the generator
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param $config Instance of HTMLPurifier_Config
|
||||
* @param $context Instance of HTMLPurifier_Context
|
||||
*/
|
||||
public function __construct($config = null, $context = null) {
|
||||
if (!$config) $config = HTMLPurifier_Config::createDefault();
|
||||
$this->config = $config;
|
||||
$this->_scriptFix = $config->get('Output', 'CommentScriptContents');
|
||||
$this->_def = $config->getHTMLDefinition();
|
||||
$this->_xhtml = $this->_def->doctype->xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates HTML from an array of tokens.
|
||||
* @param $tokens Array of HTMLPurifier_Token
|
||||
* @param $config HTMLPurifier_Config object
|
||||
* @return Generated HTML
|
||||
*/
|
||||
public function generateFromTokens($tokens, $config, $context) {
|
||||
$html = '';
|
||||
if (!$config) $config = HTMLPurifier_Config::createDefault();
|
||||
$this->_scriptFix = $config->get('Output', 'CommentScriptContents');
|
||||
|
||||
$this->_def = $config->getHTMLDefinition();
|
||||
$this->_xhtml = $this->_def->doctype->xml;
|
||||
|
||||
public function generateFromTokens($tokens) {
|
||||
if (!$tokens) return '';
|
||||
|
||||
// Basic algorithm
|
||||
$html = '';
|
||||
for ($i = 0, $size = count($tokens); $i < $size; $i++) {
|
||||
if ($this->_scriptFix && $tokens[$i]->name === 'script'
|
||||
&& $i + 2 < $size && $tokens[$i+2] instanceof HTMLPurifier_Token_End) {
|
||||
// script special case
|
||||
// the contents of the script block must be ONE token
|
||||
// for this to work
|
||||
// for this to work.
|
||||
$html .= $this->generateFromToken($tokens[$i++]);
|
||||
$html .= $this->generateScriptFromToken($tokens[$i++]);
|
||||
// We're not going to do this: it wouldn't be valid anyway
|
||||
//while ($tokens[$i]->name != 'script') {
|
||||
// $html .= $this->generateScriptFromToken($tokens[$i++]);
|
||||
//}
|
||||
}
|
||||
$html .= $this->generateFromToken($tokens[$i]);
|
||||
}
|
||||
if ($config->get('Output', 'TidyFormat') && extension_loaded('tidy')) {
|
||||
|
||||
$tidy_options = array(
|
||||
|
||||
// Tidy cleanup
|
||||
if (extension_loaded('tidy') && $this->config->get('Output', 'TidyFormat')) {
|
||||
$tidy = new Tidy;
|
||||
$tidy->parseString($html, array(
|
||||
'indent'=> true,
|
||||
'output-xhtml' => $this->_xhtml,
|
||||
'show-body-only' => true,
|
||||
'indent-spaces' => 2,
|
||||
'wrap' => 68,
|
||||
);
|
||||
if (version_compare(PHP_VERSION, '5', '<')) {
|
||||
tidy_set_encoding('utf8');
|
||||
foreach ($tidy_options as $key => $value) {
|
||||
tidy_setopt($key, $value);
|
||||
}
|
||||
tidy_parse_string($html);
|
||||
tidy_clean_repair();
|
||||
$html = tidy_get_output();
|
||||
} else {
|
||||
$tidy = new Tidy;
|
||||
$tidy->parseString($html, $tidy_options, 'utf8');
|
||||
$tidy->cleanRepair();
|
||||
$html = (string) $tidy;
|
||||
}
|
||||
), 'utf8');
|
||||
$tidy->cleanRepair();
|
||||
$html = (string) $tidy; // explicit cast necessary
|
||||
}
|
||||
// normalize newlines to system
|
||||
$nl = $config->get('Output', 'Newline');
|
||||
|
||||
// Normalize newlines to system defined value
|
||||
$nl = $this->config->get('Output', 'Newline');
|
||||
if ($nl === null) $nl = PHP_EOL;
|
||||
$html = str_replace("\n", $nl, $html);
|
||||
if ($nl !== "\n") $html = str_replace("\n", $nl, $html);
|
||||
return $html;
|
||||
}
|
||||
|
||||
@@ -95,8 +93,11 @@ class HTMLPurifier_Generator
|
||||
* @return Generated HTML
|
||||
*/
|
||||
public function generateFromToken($token) {
|
||||
if (!$token instanceof HTMLPurifier_Token) return '';
|
||||
if ($token instanceof HTMLPurifier_Token_Start) {
|
||||
if (!$token instanceof HTMLPurifier_Token) {
|
||||
trigger_error('Cannot generate HTML from non-HTMLPurifier_Token object', E_USER_WARNING);
|
||||
return '';
|
||||
|
||||
} elseif ($token instanceof HTMLPurifier_Token_Start) {
|
||||
$attr = $this->generateAttributes($token->attr, $token->name);
|
||||
return '<' . $token->name . ($attr ? ' ' : '') . $attr . '>';
|
||||
|
||||
@@ -106,11 +107,11 @@ class HTMLPurifier_Generator
|
||||
} elseif ($token instanceof HTMLPurifier_Token_Empty) {
|
||||
$attr = $this->generateAttributes($token->attr, $token->name);
|
||||
return '<' . $token->name . ($attr ? ' ' : '') . $attr .
|
||||
( $this->_xhtml ? ' /': '' )
|
||||
( $this->_xhtml ? ' /': '' ) // <br /> v. <br>
|
||||
. '>';
|
||||
|
||||
} elseif ($token instanceof HTMLPurifier_Token_Text) {
|
||||
return $this->escape($token->data);
|
||||
return $this->escape($token->data, ENT_NOQUOTES);
|
||||
|
||||
} elseif ($token instanceof HTMLPurifier_Token_Comment) {
|
||||
return '<!--' . $token->data . '-->';
|
||||
@@ -127,25 +128,27 @@ class HTMLPurifier_Generator
|
||||
*/
|
||||
public function generateScriptFromToken($token) {
|
||||
if (!$token instanceof HTMLPurifier_Token_Text) return $this->generateFromToken($token);
|
||||
// return '<!--' . "\n" . trim($token->data) . "\n" . '// -->';
|
||||
// more advanced version:
|
||||
// thanks <http://lachy.id.au/log/2005/05/script-comments>
|
||||
// Thanks <http://lachy.id.au/log/2005/05/script-comments>
|
||||
$data = preg_replace('#//\s*$#', '', $token->data);
|
||||
return '<!--//--><![CDATA[//><!--' . "\n" . trim($data) . "\n" . '//--><!]]>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates attribute declarations from attribute array.
|
||||
* @note This does not include the leading or trailing space.
|
||||
* @param $assoc_array_of_attributes Attribute array
|
||||
* @param $element Name of element attributes are for, used to check
|
||||
* attribute minimization.
|
||||
* @return Generate HTML fragment for insertion.
|
||||
*/
|
||||
public function generateAttributes($assoc_array_of_attributes, $element) {
|
||||
public function generateAttributes($assoc_array_of_attributes, $element = false) {
|
||||
$html = '';
|
||||
foreach ($assoc_array_of_attributes as $key => $value) {
|
||||
if (!$this->_xhtml) {
|
||||
// remove namespaced attributes
|
||||
// Remove namespaced attributes
|
||||
if (strpos($key, ':') !== false) continue;
|
||||
if (!empty($this->_def->info[$element]->attr[$key]->minimized)) {
|
||||
// Check if we should minimize the attribute: val="val" -> val
|
||||
if ($element && !empty($this->_def->info[$element]->attr[$key]->minimized)) {
|
||||
$html .= $key . ' ';
|
||||
continue;
|
||||
}
|
||||
@@ -157,11 +160,16 @@ class HTMLPurifier_Generator
|
||||
|
||||
/**
|
||||
* Escapes raw text data.
|
||||
* @todo This really ought to be protected, but until we have a facility
|
||||
* for properly generating HTML here w/o using tokens, it stays
|
||||
* public.
|
||||
* @param $string String data to escape for HTML.
|
||||
* @param $quote Quoting style, like htmlspecialchars. ENT_NOQUOTES is
|
||||
* permissible for non-attribute output.
|
||||
* @return String escaped data.
|
||||
*/
|
||||
public function escape($string) {
|
||||
return htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
|
||||
public function escape($string, $quote = ENT_COMPAT) {
|
||||
return htmlspecialchars($string, $quote, 'UTF-8');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -95,11 +95,11 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
* HTMLPurifier_AttrTypes for details
|
||||
*/
|
||||
public function addAttribute($element_name, $attr_name, $def) {
|
||||
$module =& $this->getAnonymousModule();
|
||||
$module = $this->getAnonymousModule();
|
||||
if (!isset($module->info[$element_name])) {
|
||||
$element =& $module->addBlankElement($element_name);
|
||||
$element = $module->addBlankElement($element_name);
|
||||
} else {
|
||||
$element =& $module->info[$element_name];
|
||||
$element = $module->info[$element_name];
|
||||
}
|
||||
$element->attr[$attr_name] = $def;
|
||||
}
|
||||
@@ -109,11 +109,11 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
* @note See HTMLPurifier_HTMLModule::addElement for detailed
|
||||
* parameter and return value descriptions.
|
||||
*/
|
||||
public function &addElement($element_name, $type, $contents, $attr_collections, $attributes) {
|
||||
$module =& $this->getAnonymousModule();
|
||||
public function addElement($element_name, $type, $contents, $attr_collections, $attributes) {
|
||||
$module = $this->getAnonymousModule();
|
||||
// assume that if the user is calling this, the element
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -123,9 +123,9 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
* @note See HTMLPurifier_HTMLModule::addBlankElement for detailed
|
||||
* parameter and return value descriptions.
|
||||
*/
|
||||
public function &addBlankElement($element_name) {
|
||||
$module =& $this->getAnonymousModule();
|
||||
$element =& $module->addBlankElement($element_name);
|
||||
public function addBlankElement($element_name) {
|
||||
$module = $this->getAnonymousModule();
|
||||
$element = $module->addBlankElement($element_name);
|
||||
return $element;
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
* bust out advanced features without having to make your own
|
||||
* module.
|
||||
*/
|
||||
public function &getAnonymousModule() {
|
||||
public function getAnonymousModule() {
|
||||
if (!$this->_anonModule) {
|
||||
$this->_anonModule = new HTMLPurifier_HTMLModule();
|
||||
$this->_anonModule->name = 'Anonymous';
|
||||
@@ -233,10 +233,10 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
$support = "(for information on implementing this, see the ".
|
||||
"support forums) ";
|
||||
|
||||
// setup allowed elements
|
||||
// setup allowed elements -----------------------------------------
|
||||
|
||||
$allowed_elements = $config->get('HTML', 'AllowedElements');
|
||||
$allowed_attributes = $config->get('HTML', 'AllowedAttributes');
|
||||
$allowed_attributes = $config->get('HTML', 'AllowedAttributes'); // retrieve early
|
||||
|
||||
if (!is_array($allowed_elements) && !is_array($allowed_attributes)) {
|
||||
$allowed = $config->get('HTML', 'Allowed');
|
||||
@@ -252,55 +252,80 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
}
|
||||
// emit errors
|
||||
foreach ($allowed_elements as $element => $d) {
|
||||
// :TODO: Is this htmlspecialchars() call really necessary?
|
||||
$element = htmlspecialchars($element);
|
||||
$element = htmlspecialchars($element); // PHP doesn't escape errors, be careful!
|
||||
trigger_error("Element '$element' is not supported $support", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
// setup allowed attributes ---------------------------------------
|
||||
|
||||
$allowed_attributes_mutable = $allowed_attributes; // by copy!
|
||||
if (is_array($allowed_attributes)) {
|
||||
foreach ($this->info_global_attr as $attr_key => $info) {
|
||||
if (!isset($allowed_attributes["*.$attr_key"])) {
|
||||
unset($this->info_global_attr[$attr_key]);
|
||||
} elseif (isset($allowed_attributes_mutable["*.$attr_key"])) {
|
||||
unset($allowed_attributes_mutable["*.$attr_key"]);
|
||||
|
||||
// This actually doesn't do anything, since we went away from
|
||||
// global attributes. It's possible that userland code uses
|
||||
// it, but HTMLModuleManager doesn't!
|
||||
foreach ($this->info_global_attr as $attr => $x) {
|
||||
$keys = array($attr, "*@$attr", "*.$attr");
|
||||
$delete = true;
|
||||
foreach ($keys as $key) {
|
||||
if ($delete && isset($allowed_attributes[$key])) {
|
||||
$delete = false;
|
||||
}
|
||||
if (isset($allowed_attributes_mutable[$key])) {
|
||||
unset($allowed_attributes_mutable[$key]);
|
||||
}
|
||||
}
|
||||
if ($delete) unset($this->info_global_attr[$attr]);
|
||||
}
|
||||
|
||||
foreach ($this->info as $tag => $info) {
|
||||
foreach ($info->attr as $attr => $attr_info) {
|
||||
if (!isset($allowed_attributes["$tag.$attr"]) &&
|
||||
!isset($allowed_attributes["*.$attr"])) {
|
||||
unset($this->info[$tag]->attr[$attr]);
|
||||
} else {
|
||||
if (isset($allowed_attributes_mutable["$tag.$attr"])) {
|
||||
unset($allowed_attributes_mutable["$tag.$attr"]);
|
||||
} elseif (isset($allowed_attributes_mutable["*.$attr"])) {
|
||||
unset($allowed_attributes_mutable["*.$attr"]);
|
||||
foreach ($info->attr as $attr => $x) {
|
||||
$keys = array("$tag@$attr", $attr, "*@$attr", "$tag.$attr", "*.$attr");
|
||||
$delete = true;
|
||||
foreach ($keys as $key) {
|
||||
if ($delete && isset($allowed_attributes[$key])) {
|
||||
$delete = false;
|
||||
}
|
||||
if (isset($allowed_attributes_mutable[$key])) {
|
||||
unset($allowed_attributes_mutable[$key]);
|
||||
}
|
||||
}
|
||||
if ($delete) unset($this->info[$tag]->attr[$attr]);
|
||||
}
|
||||
}
|
||||
// emit errors
|
||||
foreach ($allowed_attributes_mutable as $elattr => $d) {
|
||||
list($element, $attribute) = explode('.', $elattr);
|
||||
// :TODO: Is this htmlspecialchars() call really necessary?
|
||||
$element = htmlspecialchars($element);
|
||||
$attribute = htmlspecialchars($attribute);
|
||||
if ($element == '*') {
|
||||
trigger_error("Global attribute '$attribute' is not ".
|
||||
"supported in any elements $support",
|
||||
E_USER_WARNING);
|
||||
} else {
|
||||
trigger_error("Attribute '$attribute' in element '$element' not supported $support",
|
||||
E_USER_WARNING);
|
||||
$bits = preg_split('/[.@]/', $elattr, 2);
|
||||
$c = count($bits);
|
||||
switch ($c) {
|
||||
case 2:
|
||||
if ($bits[0] !== '*') {
|
||||
$element = htmlspecialchars($bits[0]);
|
||||
$attribute = htmlspecialchars($bits[1]);
|
||||
if (!isset($this->info[$element])) {
|
||||
trigger_error("Cannot allow attribute '$attribute' if element '$element' is not allowed/supported $support");
|
||||
} else {
|
||||
trigger_error("Attribute '$attribute' in element '$element' not supported $support",
|
||||
E_USER_WARNING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// otherwise fall through
|
||||
case 1:
|
||||
$attribute = htmlspecialchars($bits[0]);
|
||||
trigger_error("Global attribute '$attribute' is not ".
|
||||
"supported in any elements $support",
|
||||
E_USER_WARNING);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// setup forbidden elements
|
||||
$forbidden_elements = $config->get('HTML', 'ForbiddenElements');
|
||||
// setup forbidden elements ---------------------------------------
|
||||
|
||||
$forbidden_elements = $config->get('HTML', 'ForbiddenElements');
|
||||
$forbidden_attributes = $config->get('HTML', 'ForbiddenAttributes');
|
||||
|
||||
foreach ($this->info as $tag => $info) {
|
||||
@@ -308,13 +333,28 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
unset($this->info[$tag]);
|
||||
continue;
|
||||
}
|
||||
foreach ($info->attr as $name => $def) {
|
||||
if (isset($forbidden_attributes["$tag.$name"])) {
|
||||
unset($this->info[$tag]->attr[$name]);
|
||||
foreach ($info->attr as $attr => $x) {
|
||||
if (
|
||||
isset($forbidden_attributes["$tag@$attr"]) ||
|
||||
isset($forbidden_attributes["*@$attr"]) ||
|
||||
isset($forbidden_attributes[$attr])
|
||||
) {
|
||||
unset($this->info[$tag]->attr[$attr]);
|
||||
continue;
|
||||
} // this segment might get removed eventually
|
||||
elseif (isset($forbidden_attributes["$tag.$attr"])) {
|
||||
// $tag.$attr are not user supplied, so no worries!
|
||||
trigger_error("Error with $tag.$attr: tag.attr syntax not supported for HTML.ForbiddenAttributes; use tag@attr instead", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($forbidden_attributes as $key => $v) {
|
||||
if (strlen($key) < 2) continue;
|
||||
if ($key[0] != '*') continue;
|
||||
if ($key[1] == '.') {
|
||||
trigger_error("Error with $key: *.attr syntax not supported for HTML.ForbiddenAttributes; use attr instead", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -329,6 +369,8 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
*/
|
||||
public function parseTinyMCEAllowedList($list) {
|
||||
|
||||
$list = str_replace(array(' ', "\t"), '', $list);
|
||||
|
||||
$elements = array();
|
||||
$attributes = array();
|
||||
|
||||
|
@@ -116,10 +116,10 @@ class HTMLPurifier_HTMLModule
|
||||
* element?
|
||||
* @param $attr What unique attributes does the element define?
|
||||
* @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
|
||||
*/
|
||||
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;
|
||||
// parse content_model
|
||||
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
|
||||
* element.
|
||||
* @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])) {
|
||||
$this->elements[] = $element;
|
||||
$this->info[$element] = new HTMLPurifier_ElementDef();
|
||||
|
@@ -13,7 +13,7 @@ class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule
|
||||
);
|
||||
|
||||
public function __construct() {
|
||||
$bdo =& $this->addElement(
|
||||
$bdo = $this->addElement(
|
||||
'bdo', 'Inline', 'Inline', array('Core', 'Lang'),
|
||||
array(
|
||||
'dir' => 'Enum#ltr,rtl', // required
|
||||
|
@@ -9,7 +9,7 @@ class HTMLPurifier_HTMLModule_Hypertext extends HTMLPurifier_HTMLModule
|
||||
public $name = 'Hypertext';
|
||||
|
||||
public function __construct() {
|
||||
$a =& $this->addElement(
|
||||
$a = $this->addElement(
|
||||
'a', 'Inline', 'Inline', 'Common',
|
||||
array(
|
||||
// 'accesskey' => 'Character',
|
||||
|
@@ -11,7 +11,7 @@ class HTMLPurifier_HTMLModule_Image extends HTMLPurifier_HTMLModule
|
||||
public $name = 'Image';
|
||||
|
||||
public function __construct() {
|
||||
$img =& $this->addElement(
|
||||
$img = $this->addElement(
|
||||
'img', 'Inline', 'Empty', 'Common',
|
||||
array(
|
||||
'alt*' => 'Text',
|
||||
|
@@ -49,40 +49,40 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule
|
||||
|
||||
$align = 'Enum#left,right,center,justify';
|
||||
|
||||
$address =& $this->addBlankElement('address');
|
||||
$address = $this->addBlankElement('address');
|
||||
$address->content_model = 'Inline | #PCDATA | p';
|
||||
$address->content_model_type = 'optional';
|
||||
$address->child = false;
|
||||
|
||||
$blockquote =& $this->addBlankElement('blockquote');
|
||||
$blockquote = $this->addBlankElement('blockquote');
|
||||
$blockquote->content_model = 'Flow | #PCDATA';
|
||||
$blockquote->content_model_type = 'optional';
|
||||
$blockquote->child = false;
|
||||
|
||||
$br =& $this->addBlankElement('br');
|
||||
$br = $this->addBlankElement('br');
|
||||
$br->attr['clear'] = 'Enum#left,all,right,none';
|
||||
|
||||
$caption =& $this->addBlankElement('caption');
|
||||
$caption = $this->addBlankElement('caption');
|
||||
$caption->attr['align'] = 'Enum#top,bottom,left,right';
|
||||
|
||||
$div =& $this->addBlankElement('div');
|
||||
$div = $this->addBlankElement('div');
|
||||
$div->attr['align'] = $align;
|
||||
|
||||
$dl =& $this->addBlankElement('dl');
|
||||
$dl = $this->addBlankElement('dl');
|
||||
$dl->attr['compact'] = 'Bool#compact';
|
||||
|
||||
for ($i = 1; $i <= 6; $i++) {
|
||||
$h =& $this->addBlankElement("h$i");
|
||||
$h = $this->addBlankElement("h$i");
|
||||
$h->attr['align'] = $align;
|
||||
}
|
||||
|
||||
$hr =& $this->addBlankElement('hr');
|
||||
$hr = $this->addBlankElement('hr');
|
||||
$hr->attr['align'] = $align;
|
||||
$hr->attr['noshade'] = 'Bool#noshade';
|
||||
$hr->attr['size'] = 'Pixels';
|
||||
$hr->attr['width'] = 'Length';
|
||||
|
||||
$img =& $this->addBlankElement('img');
|
||||
$img = $this->addBlankElement('img');
|
||||
$img->attr['align'] = 'Enum#top,middle,bottom,left,right';
|
||||
$img->attr['border'] = 'Pixels';
|
||||
$img->attr['hspace'] = 'Pixels';
|
||||
@@ -90,43 +90,43 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule
|
||||
|
||||
// figure out this integer business
|
||||
|
||||
$li =& $this->addBlankElement('li');
|
||||
$li = $this->addBlankElement('li');
|
||||
$li->attr['value'] = new HTMLPurifier_AttrDef_Integer();
|
||||
$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['start'] = new HTMLPurifier_AttrDef_Integer();
|
||||
$ol->attr['type'] = 'Enum#s:1,i,I,a,A';
|
||||
|
||||
$p =& $this->addBlankElement('p');
|
||||
$p = $this->addBlankElement('p');
|
||||
$p->attr['align'] = $align;
|
||||
|
||||
$pre =& $this->addBlankElement('pre');
|
||||
$pre = $this->addBlankElement('pre');
|
||||
$pre->attr['width'] = 'Number';
|
||||
|
||||
// script omitted
|
||||
|
||||
$table =& $this->addBlankElement('table');
|
||||
$table = $this->addBlankElement('table');
|
||||
$table->attr['align'] = 'Enum#left,center,right';
|
||||
$table->attr['bgcolor'] = 'Color';
|
||||
|
||||
$tr =& $this->addBlankElement('tr');
|
||||
$tr = $this->addBlankElement('tr');
|
||||
$tr->attr['bgcolor'] = 'Color';
|
||||
|
||||
$th =& $this->addBlankElement('th');
|
||||
$th = $this->addBlankElement('th');
|
||||
$th->attr['bgcolor'] = 'Color';
|
||||
$th->attr['height'] = 'Length';
|
||||
$th->attr['nowrap'] = 'Bool#nowrap';
|
||||
$th->attr['width'] = 'Length';
|
||||
|
||||
$td =& $this->addBlankElement('td');
|
||||
$td = $this->addBlankElement('td');
|
||||
$td->attr['bgcolor'] = 'Color';
|
||||
$td->attr['height'] = 'Length';
|
||||
$td->attr['nowrap'] = 'Bool#nowrap';
|
||||
$td->attr['width'] = 'Length';
|
||||
|
||||
$ul =& $this->addBlankElement('ul');
|
||||
$ul = $this->addBlankElement('ul');
|
||||
$ul->attr['compact'] = 'Bool#compact';
|
||||
$ul->attr['type'] = 'Enum#square,disc,circle';
|
||||
|
||||
|
@@ -15,9 +15,9 @@ class HTMLPurifier_HTMLModule_Ruby extends HTMLPurifier_HTMLModule
|
||||
'Common');
|
||||
$this->addElement('rbc', false, 'Required: rb', '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);
|
||||
$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);
|
||||
$this->addElement('rp', false, 'Optional: #PCDATA', 'Common');
|
||||
}
|
||||
|
@@ -7,19 +7,6 @@ INSIDE HTML PURIFIER DOCUMENTS. USE ONLY WITH TRUSTED USER INPUT!!!
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements required attribute stipulation for <script>
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_ScriptRequired extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
public function transform($attr, $config, $context) {
|
||||
if (!isset($attr['type'])) {
|
||||
$attr['type'] = 'text/javascript';
|
||||
}
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XHTML 1.1 Scripting module, defines elements that are used to contain
|
||||
* information pertaining to executable scripts or the lack of support
|
||||
|
@@ -11,7 +11,7 @@ class HTMLPurifier_HTMLModule_Target extends HTMLPurifier_HTMLModule
|
||||
public function __construct() {
|
||||
$elements = array('a');
|
||||
foreach ($elements as $name) {
|
||||
$e =& $this->addBlankElement($name);
|
||||
$e = $this->addBlankElement($name);
|
||||
$e->attr = array(
|
||||
'target' => new HTMLPurifier_AttrDef_HTML_FrameTarget()
|
||||
);
|
||||
|
@@ -42,7 +42,7 @@ class HTMLPurifier_HTMLModule_Text extends HTMLPurifier_HTMLModule
|
||||
// Block Phrasal --------------------------------------------------
|
||||
$this->addElement('address', 'Block', 'Inline', 'Common');
|
||||
$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(
|
||||
'img', 'big', 'small', 'object', 'applet', 'font', 'basefont' );
|
||||
$this->addElement('h1', 'Heading', 'Inline', 'Common');
|
||||
|
@@ -128,14 +128,16 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
|
||||
if (isset($params['element'])) {
|
||||
$element = $params['element'];
|
||||
if (empty($this->info[$element])) {
|
||||
$e =& $this->addBlankElement($element);
|
||||
$e = $this->addBlankElement($element);
|
||||
} else {
|
||||
$e =& $this->info[$element];
|
||||
$e = $this->info[$element];
|
||||
}
|
||||
} else {
|
||||
$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[$attr] = $fix;
|
||||
break;
|
||||
@@ -146,9 +148,9 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
|
||||
case 'content_model_type':
|
||||
$element = $params['element'];
|
||||
if (empty($this->info[$element])) {
|
||||
$e =& $this->addBlankElement($element);
|
||||
$e = $this->addBlankElement($element);
|
||||
} else {
|
||||
$e =& $this->info[$element];
|
||||
$e = $this->info[$element];
|
||||
}
|
||||
$e->$type = $fix;
|
||||
break;
|
||||
|
@@ -1,5 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Represents a language and defines localizable string formatting and
|
||||
* other functions, as well as the localized messages for HTML Purifier.
|
||||
*/
|
||||
class HTMLPurifier_Language
|
||||
{
|
||||
|
||||
@@ -23,6 +27,13 @@ class HTMLPurifier_Language
|
||||
*/
|
||||
public $errorNames = array();
|
||||
|
||||
/**
|
||||
* True if no message file was found for this language, so English
|
||||
* is being used instead. Check this if you'd like to notify the
|
||||
* user that they've used a non-supported language.
|
||||
*/
|
||||
public $error = false;
|
||||
|
||||
/**
|
||||
* Has the language object been loaded yet?
|
||||
* @todo Make it private, fix usage in HTMLPurifier_LanguageTest
|
||||
@@ -36,7 +47,7 @@ class HTMLPurifier_Language
|
||||
|
||||
public function __construct($config, $context) {
|
||||
$this->config = $config;
|
||||
$this->context =& $context;
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +133,7 @@ class HTMLPurifier_Language
|
||||
// could be introduced for all types of tokens. This
|
||||
// may need to be factored out into a dedicated class
|
||||
if (!empty($value->attr)) {
|
||||
$stripped_token = $value->copy();
|
||||
$stripped_token = clone $value;
|
||||
$stripped_token->attr = array();
|
||||
$subst['$'.$i.'.Compact'] = $generator->generateFromToken($stripped_token);
|
||||
}
|
||||
|
11
library/HTMLPurifier/Language/messages/en-x-testmini.php
Normal file
11
library/HTMLPurifier/Language/messages/en-x-testmini.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
// private language message file for unit testing purposes
|
||||
// this language file has no class associated with it
|
||||
|
||||
$fallback = 'en';
|
||||
|
||||
$messages = array(
|
||||
'HTMLPurifier' => 'HTML Purifier XNone'
|
||||
);
|
||||
|
@@ -5,6 +5,7 @@
|
||||
* caching and fallbacks.
|
||||
* @note Thanks to MediaWiki for the general logic, although this version
|
||||
* has been entirely rewritten
|
||||
* @todo Serialized cache for languages
|
||||
*/
|
||||
class HTMLPurifier_LanguageFactory
|
||||
{
|
||||
@@ -53,7 +54,7 @@ class HTMLPurifier_LanguageFactory
|
||||
* @param $prototype Optional prototype to overload sole instance with,
|
||||
* or bool true to reset to default factory.
|
||||
*/
|
||||
public static function &instance($prototype = null) {
|
||||
public static function instance($prototype = null) {
|
||||
static $instance = null;
|
||||
if ($prototype !== null) {
|
||||
$instance = $prototype;
|
||||
@@ -77,41 +78,43 @@ class HTMLPurifier_LanguageFactory
|
||||
* Creates a language object, handles class fallbacks
|
||||
* @param $config Instance of HTMLPurifier_Config
|
||||
* @param $context Instance of HTMLPurifier_Context
|
||||
* @param $code Code to override configuration with. Private parameter.
|
||||
*/
|
||||
public function create($config, $context) {
|
||||
public function create($config, $context, $code = false) {
|
||||
|
||||
// validate language code
|
||||
$code = $this->validator->validate(
|
||||
$config->get('Core', 'Language'), $config, $context
|
||||
);
|
||||
if ($code === false) {
|
||||
$code = $this->validator->validate(
|
||||
$config->get('Core', 'Language'), $config, $context
|
||||
);
|
||||
} else {
|
||||
$code = $this->validator->validate($code, $config, $context);
|
||||
}
|
||||
if ($code === false) $code = 'en'; // malformed code becomes English
|
||||
|
||||
$pcode = str_replace('-', '_', $code); // make valid PHP classname
|
||||
static $depth = 0; // recursion protection
|
||||
|
||||
if ($code == 'en') {
|
||||
$class = 'HTMLPurifier_Language';
|
||||
$file = $this->dir . '/Language.php';
|
||||
$lang = new HTMLPurifier_Language($config, $context);
|
||||
} else {
|
||||
$class = 'HTMLPurifier_Language_' . $pcode;
|
||||
$file = $this->dir . '/Language/classes/' . $code . '.php';
|
||||
// PHP5/APC deps bug workaround can go here
|
||||
// you can bypass the conditional include by loading the
|
||||
// file yourself
|
||||
if (file_exists($file) && !class_exists($class, false)) {
|
||||
include_once $file;
|
||||
if (file_exists($file) || class_exists($class, false)) {
|
||||
$lang = new $class($config, $context);
|
||||
} else {
|
||||
// Go fallback
|
||||
$raw_fallback = $this->getFallbackFor($code);
|
||||
$fallback = $raw_fallback ? $raw_fallback : 'en';
|
||||
$depth++;
|
||||
$lang = $this->create($config, $context, $fallback);
|
||||
if (!$raw_fallback) {
|
||||
$lang->error = true;
|
||||
}
|
||||
$depth--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists($class, false)) {
|
||||
// go fallback
|
||||
$fallback = HTMLPurifier_LanguageFactory::getFallbackFor($code);
|
||||
$depth++;
|
||||
$lang = HTMLPurifier_LanguageFactory::factory( $fallback );
|
||||
$depth--;
|
||||
} else {
|
||||
$lang = new $class($config, $context);
|
||||
}
|
||||
$lang->code = $code;
|
||||
|
||||
return $lang;
|
||||
|
@@ -11,7 +11,8 @@
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
*
|
||||
@@ -28,18 +30,14 @@
|
||||
* We use tokens rather than create a DOM representation because DOM would:
|
||||
*
|
||||
* @par
|
||||
* -# Require more processing power to create,
|
||||
* -# Require recursion to iterate,
|
||||
* -# Must be compatible with PHP 5's DOM (otherwise duplication),
|
||||
* -# Has the entire document structure (html and body not needed), and
|
||||
* -# Has unknown readability improvement.
|
||||
* -# Require more processing and memory to create,
|
||||
* -# Is not streamable, and
|
||||
* -# Has the entire document structure (html and body not needed).
|
||||
*
|
||||
* @par
|
||||
* What the last item means is that the functions for manipulating tokens are
|
||||
* already fairly compact, and when well-commented, more abstraction may not
|
||||
* be needed.
|
||||
*
|
||||
* @see HTMLPurifier_Token
|
||||
* However, DOM is helpful in that it makes it easy to move around nodes
|
||||
* without a lot of lookaheads to see when a tag is closed. This is a
|
||||
* limitation of the token system and some workarounds would be nice.
|
||||
*/
|
||||
class HTMLPurifier_Lexer
|
||||
{
|
||||
@@ -49,22 +47,16 @@ class HTMLPurifier_Lexer
|
||||
/**
|
||||
* Retrieves or sets the default Lexer as a Prototype Factory.
|
||||
*
|
||||
* Depending on what PHP version you are running, the abstract base
|
||||
* Lexer class will determine which concrete Lexer is best for you:
|
||||
* HTMLPurifier_Lexer_DirectLex for PHP 4, and HTMLPurifier_Lexer_DOMLex
|
||||
* for PHP 5 and beyond. This general rule has a few exceptions to it
|
||||
* involving special features that only DirectLex implements.
|
||||
* By default HTMLPurifier_Lexer_DOMLex will be returned. There are
|
||||
* a few exceptions involving special features that only DirectLex
|
||||
* implements.
|
||||
*
|
||||
* @note The behavior of this class has changed, rather than accepting
|
||||
* a prototype object, it now accepts a configuration object.
|
||||
* To specify your own prototype, set %Core.LexerImpl to it.
|
||||
* This change in behavior de-singletonizes the lexer object.
|
||||
*
|
||||
* @note In PHP4, it is possible to call this factory method from
|
||||
* subclasses, such usage is not recommended and not
|
||||
* forwards-compatible.
|
||||
*
|
||||
* @param $prototype Optional prototype lexer or configuration object
|
||||
* @param $config Instance of HTMLPurifier_Config
|
||||
* @return Concrete lexer.
|
||||
*/
|
||||
public static function create($config) {
|
||||
@@ -96,8 +88,9 @@ class HTMLPurifier_Lexer
|
||||
break;
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, "5", ">=") && // check for PHP5
|
||||
class_exists('DOMDocument')) { // check for DOM support
|
||||
if (class_exists('DOMDocument')) {
|
||||
// check for DOM support, because, surprisingly enough,
|
||||
// it's *not* part of the core!
|
||||
$lexer = 'DOMLex';
|
||||
} else {
|
||||
$lexer = 'DirectLex';
|
||||
|
@@ -2,17 +2,28 @@
|
||||
|
||||
/**
|
||||
* Experimental HTML5-based parser using Jeroen van der Meer's PH5P library.
|
||||
* Requires PHP5, and occupies space in the HTML5 pseudo-namespace (may
|
||||
* cause conflicts, sorry).
|
||||
* Occupies space in the HTML5 pseudo-namespace, which may cause conflicts.
|
||||
*
|
||||
* @note
|
||||
* Recent changes to PHP's DOM extension have resulted in some fatal
|
||||
* error conditions with the original version of PH5P. Pending changes,
|
||||
* this lexer will punt to DirectLex if DOM throughs an exception.
|
||||
*/
|
||||
|
||||
class HTMLPurifier_Lexer_PH5P extends HTMLPurifier_Lexer_DOMLex {
|
||||
|
||||
public function tokenizeHTML($html, $config, $context) {
|
||||
$html = $this->normalize($html, $config, $context);
|
||||
$html = $this->wrapHTML( $html, $config, $context);
|
||||
$parser = new HTML5($html);
|
||||
$doc = $parser->save();
|
||||
$new_html = $this->normalize($html, $config, $context);
|
||||
$new_html = $this->wrapHTML($new_html, $config, $context);
|
||||
try {
|
||||
$parser = new HTML5($new_html);
|
||||
$doc = $parser->save();
|
||||
} catch (DOMException $e) {
|
||||
// Uh oh, it failed. Punt to DirectLex.
|
||||
$lexer = new HTMLPurifier_Lexer_DirectLex();
|
||||
$context->register('PH5PError', $e); // save the error, so we can detect it
|
||||
return $lexer->tokenizeHTML($html, $config, $context); // use original HTML
|
||||
}
|
||||
$tokens = array();
|
||||
$this->tokenizeDOM(
|
||||
$doc->getElementsByTagName('html')->item(0)-> // <html>
|
||||
|
@@ -2,12 +2,68 @@
|
||||
|
||||
/**
|
||||
* Class that handles operations involving percent-encoding in URIs.
|
||||
*
|
||||
* @warning
|
||||
* Be careful when reusing instances of PercentEncoder. The object
|
||||
* you use for normalize() SHOULD NOT be used for encode(), or
|
||||
* vice-versa.
|
||||
*/
|
||||
class HTMLPurifier_PercentEncoder
|
||||
{
|
||||
|
||||
/**
|
||||
* Fix up percent-encoding by decoding unreserved characters and normalizing
|
||||
* Reserved characters to preserve when using encode().
|
||||
*/
|
||||
protected $preserve = array();
|
||||
|
||||
/**
|
||||
* String of characters that should be preserved while using encode().
|
||||
*/
|
||||
public function __construct($preserve = false) {
|
||||
// unreserved letters, ought to const-ify
|
||||
for ($i = 48; $i <= 57; $i++) $this->preserve[$i] = true; // digits
|
||||
for ($i = 65; $i <= 90; $i++) $this->preserve[$i] = true; // upper-case
|
||||
for ($i = 97; $i <= 122; $i++) $this->preserve[$i] = true; // lower-case
|
||||
$this->preserve[45] = true; // Dash -
|
||||
$this->preserve[46] = true; // Period .
|
||||
$this->preserve[95] = true; // Underscore _
|
||||
$this->preserve[126]= true; // Tilde ~
|
||||
|
||||
// extra letters not to escape
|
||||
if ($preserve !== false) {
|
||||
for ($i = 0, $c = strlen($preserve); $i < $c; $i++) {
|
||||
$this->preserve[ord($preserve[$i])] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Our replacement for urlencode, it encodes all non-reserved characters,
|
||||
* as well as any extra characters that were instructed to be preserved.
|
||||
* @note
|
||||
* Assumes that the string has already been normalized, making any
|
||||
* and all percent escape sequences valid. Percents will not be
|
||||
* re-escaped, regardless of their status in $preserve
|
||||
* @param $string String to be encoded
|
||||
* @return Encoded string.
|
||||
*/
|
||||
public function encode($string) {
|
||||
$ret = '';
|
||||
for ($i = 0, $c = strlen($string); $i < $c; $i++) {
|
||||
if ($string[$i] !== '%' && !isset($this->preserve[$int = ord($string[$i])]) ) {
|
||||
$ret .= '%' . sprintf('%02X', $int);
|
||||
} else {
|
||||
$ret .= $string[$i];
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix up percent-encoding by decoding unreserved characters and normalizing.
|
||||
* @warning This function is affected by $preserve, even though the
|
||||
* usual desired behavior is for this not to preserve those
|
||||
* characters. Be careful when reusing instances of PercentEncoder!
|
||||
* @param $string String to normalize
|
||||
*/
|
||||
public function normalize($string) {
|
||||
@@ -27,12 +83,7 @@ class HTMLPurifier_PercentEncoder
|
||||
continue;
|
||||
}
|
||||
$int = hexdec($encoding);
|
||||
if (
|
||||
($int >= 48 && $int <= 57) || // digits
|
||||
($int >= 65 && $int <= 90) || // uppercase letters
|
||||
($int >= 97 && $int <= 122) || // lowercase letters
|
||||
$int == 126 || $int == 45 || $int == 46 || $int == 95 // ~-._
|
||||
) {
|
||||
if (isset($this->preserve[$int])) {
|
||||
$ret .= chr($int) . $text;
|
||||
continue;
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
// OUT OF DATE, NEEDS UPDATING!
|
||||
// USE XMLWRITER!
|
||||
|
||||
class HTMLPurifier_Printer
|
||||
{
|
||||
|
@@ -55,14 +55,14 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
|
||||
/**
|
||||
* Retrieves styling, in case it is not accessible by webserver
|
||||
*/
|
||||
public function getCSS() {
|
||||
public static function getCSS() {
|
||||
return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves JavaScript, in case it is not accessible by webserver
|
||||
*/
|
||||
public function getJavaScript() {
|
||||
public static function getJavaScript() {
|
||||
return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js');
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
|
||||
$ret .= $this->start('table', array('class' => 'hp-config'));
|
||||
$ret .= $this->start('thead');
|
||||
$ret .= $this->start('tr');
|
||||
$ret .= $this->element('th', 'Directive');
|
||||
$ret .= $this->element('th', 'Value');
|
||||
$ret .= $this->element('th', 'Directive', array('class' => 'hp-directive'));
|
||||
$ret .= $this->element('th', 'Value', array('class' => 'hp-value'));
|
||||
$ret .= $this->end('tr');
|
||||
$ret .= $this->end('thead');
|
||||
foreach ($all as $ns => $directives) {
|
||||
@@ -194,6 +194,10 @@ class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer
|
||||
'id' => "$name:Null_$ns.$directive",
|
||||
'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!!
|
||||
);
|
||||
if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) {
|
||||
// modify inline javascript slightly
|
||||
$attr['onclick'] = "toggleWriteability('$name:Yes_$ns.$directive',checked);toggleWriteability('$name:No_$ns.$directive',checked)";
|
||||
}
|
||||
if ($value === null) $attr['checked'] = 'checked';
|
||||
$ret .= $this->elementEmpty('input', $attr);
|
||||
$ret .= $this->text(' or ');
|
||||
@@ -291,7 +295,8 @@ class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer {
|
||||
'id' => "$name:Yes_$ns.$directive",
|
||||
'value' => '1'
|
||||
);
|
||||
if ($value) $attr['checked'] = 'checked';
|
||||
if ($value === true) $attr['checked'] = 'checked';
|
||||
if ($value === null) $attr['disabled'] = 'disabled';
|
||||
$ret .= $this->elementEmpty('input', $attr);
|
||||
|
||||
$ret .= $this->start('label', array('for' => "$name:No_$ns.$directive"));
|
||||
@@ -305,7 +310,8 @@ class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer {
|
||||
'id' => "$name:No_$ns.$directive",
|
||||
'value' => '0'
|
||||
);
|
||||
if (!$value) $attr['checked'] = 'checked';
|
||||
if ($value === false) $attr['checked'] = 'checked';
|
||||
if ($value === null) $attr['disabled'] = 'disabled';
|
||||
$ret .= $this->elementEmpty('input', $attr);
|
||||
|
||||
$ret .= $this->end('div');
|
||||
|
@@ -37,7 +37,7 @@ class HTMLPurifier_TagTransform_Font extends HTMLPurifier_TagTransform
|
||||
public function transform($tag, $config, $context) {
|
||||
|
||||
if ($tag instanceof HTMLPurifier_Token_End) {
|
||||
$new_tag = $tag->copy();
|
||||
$new_tag = clone $tag;
|
||||
$new_tag->name = $this->transform_to;
|
||||
return $new_tag;
|
||||
}
|
||||
@@ -81,7 +81,7 @@ class HTMLPurifier_TagTransform_Font extends HTMLPurifier_TagTransform
|
||||
$prepend_style;
|
||||
}
|
||||
|
||||
$new_tag = $tag->copy();
|
||||
$new_tag = clone $tag;
|
||||
$new_tag->name = $this->transform_to;
|
||||
$new_tag->attr = $attr;
|
||||
|
||||
|
@@ -20,7 +20,7 @@ class HTMLPurifier_TagTransform_Simple extends HTMLPurifier_TagTransform
|
||||
}
|
||||
|
||||
public function transform($tag, $config, $context) {
|
||||
$new_tag = $tag->copy();
|
||||
$new_tag = clone $tag;
|
||||
$new_tag->name = $this->transform_to;
|
||||
if (!is_null($this->style) &&
|
||||
($new_tag instanceof HTMLPurifier_Token_Start || $new_tag instanceof HTMLPurifier_Token_Empty)
|
||||
|
@@ -14,14 +14,6 @@ class HTMLPurifier_Token {
|
||||
*/
|
||||
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) {
|
||||
if ($n === 'type') {
|
||||
trigger_error('Deprecated type property called; use instanceof', E_USER_NOTICE);
|
||||
|
@@ -1,15 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Factory for token generation (PHP 5 only).
|
||||
* Factory for token generation.
|
||||
*
|
||||
* @note Doing some benchmarking indicates that the new operator is much
|
||||
* slower than the clone operator (even discounting the cost of the
|
||||
* constructor). This class is for that optimization. We may want to
|
||||
* consider porting this to PHP 4 by virtue of the fact it makes the code
|
||||
* easier to read. Other then that, there's not much point as we don't
|
||||
* constructor). This class is for that optimization.
|
||||
* Other then that, there's not much point as we don't
|
||||
* maintain parallel HTMLPurifier_Token hierarchies (the main reason why
|
||||
* you'd want to use an abstract factory).
|
||||
* @todo Port DirectLex to use this
|
||||
*/
|
||||
class HTMLPurifier_TokenFactory
|
||||
{
|
||||
|
@@ -1,7 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HTML Purifier's internal representation of a URI
|
||||
* HTML Purifier's internal representation of a URI.
|
||||
* @note
|
||||
* Internal data-structures are completely escaped. If the data needs
|
||||
* to be used in a non-URI context (which is very unlikely), be sure
|
||||
* to decode it first. The URI may not necessarily be well-formed until
|
||||
* validate() is called.
|
||||
*/
|
||||
class HTMLPurifier_URI
|
||||
{
|
||||
@@ -49,13 +54,27 @@ class HTMLPurifier_URI
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic validation method applicable for all schemes
|
||||
* Generic validation method applicable for all schemes. May modify
|
||||
* this URI in order to get it into a compliant form.
|
||||
* @param $config Instance of HTMLPurifier_Config
|
||||
* @param $context Instance of HTMLPurifier_Context
|
||||
* @return True if validation/filtering succeeds, false if failure
|
||||
*/
|
||||
public function validate($config, $context) {
|
||||
|
||||
// ABNF definitions from RFC 3986
|
||||
$chars_sub_delims = '!$&\'()*+,;=';
|
||||
$chars_gen_delims = ':/?#[]@';
|
||||
$chars_pchar = $chars_sub_delims . ':@';
|
||||
|
||||
// validate scheme (MUST BE FIRST!)
|
||||
if (!is_null($this->scheme) && is_null($this->host)) {
|
||||
$def = $config->getDefinition('URI');
|
||||
if ($def->defaultScheme === $this->scheme) {
|
||||
$this->scheme = null;
|
||||
}
|
||||
}
|
||||
|
||||
// validate host
|
||||
if (!is_null($this->host)) {
|
||||
$host_def = new HTMLPurifier_AttrDef_URI_Host();
|
||||
@@ -63,18 +82,51 @@ class HTMLPurifier_URI
|
||||
if ($this->host === false) $this->host = null;
|
||||
}
|
||||
|
||||
// validate username
|
||||
if (!is_null($this->userinfo)) {
|
||||
$encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . ':');
|
||||
$this->userinfo = $encoder->encode($this->userinfo);
|
||||
}
|
||||
|
||||
// validate port
|
||||
if (!is_null($this->port)) {
|
||||
if ($this->port < 1 || $this->port > 65535) $this->port = null;
|
||||
}
|
||||
|
||||
// query and fragment are quite simple in terms of definition:
|
||||
// *( pchar / "/" / "?" ), so define their validation routines
|
||||
// when we start fixing percent encoding
|
||||
|
||||
// path gets to be validated against a hodge-podge of rules depending
|
||||
// on the status of authority and scheme, but it's not that important,
|
||||
// esp. since it won't be applicable to everyone
|
||||
// validate path
|
||||
$path_parts = array();
|
||||
$segments_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/');
|
||||
if (!is_null($this->host)) {
|
||||
// path-abempty (hier and relative)
|
||||
$this->path = $segments_encoder->encode($this->path);
|
||||
} elseif ($this->path !== '' && $this->path[0] === '/') {
|
||||
// path-absolute (hier and relative)
|
||||
if (strlen($this->path) >= 2 && $this->path[1] === '/') {
|
||||
// This shouldn't ever happen!
|
||||
$this->path = '';
|
||||
} else {
|
||||
$this->path = $segments_encoder->encode($this->path);
|
||||
}
|
||||
} elseif (!is_null($this->scheme) && $this->path !== '') {
|
||||
// path-rootless (hier)
|
||||
// Short circuit evaluation means we don't need to check nz
|
||||
$this->path = $segments_encoder->encode($this->path);
|
||||
} elseif (is_null($this->scheme) && $this->path !== '') {
|
||||
// path-noscheme (relative)
|
||||
// (once again, not checking nz)
|
||||
$segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@');
|
||||
$c = strpos($this->path, '/');
|
||||
if ($c !== false) {
|
||||
$this->path =
|
||||
$segment_nc_encoder->encode(substr($this->path, 0, $c)) .
|
||||
$segments_encoder->encode(substr($this->path, $c));
|
||||
} else {
|
||||
$this->path = $segment_nc_encoder->encode($this->path);
|
||||
}
|
||||
} else {
|
||||
// path-empty (hier and relative)
|
||||
$this->path = ''; // just to be safe
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
@@ -26,7 +26,7 @@ abstract class HTMLPurifier_URIFilter
|
||||
|
||||
/**
|
||||
* Filter a URI object
|
||||
* @param &$uri Reference to URI object
|
||||
* @param $uri Reference to URI object variable
|
||||
* @param $config Instance of HTMLPurifier_Config
|
||||
* @param $context Instance of HTMLPurifier_Context
|
||||
* @return bool Whether or not to continue processing: false indicates
|
||||
|
@@ -2,24 +2,39 @@
|
||||
|
||||
/**
|
||||
* Parses a URI into the components and fragment identifier as specified
|
||||
* by RFC 2396.
|
||||
* @todo Replace regexps with a native PHP parser
|
||||
* by RFC 3986.
|
||||
*/
|
||||
class HTMLPurifier_URIParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Parses a URI
|
||||
* Instance of HTMLPurifier_PercentEncoder to do normalization with.
|
||||
*/
|
||||
protected $percentEncoder;
|
||||
|
||||
public function __construct() {
|
||||
$this->percentEncoder = new HTMLPurifier_PercentEncoder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a URI.
|
||||
* @param $uri string URI to parse
|
||||
* @return HTMLPurifier_URI representation of URI
|
||||
* @return HTMLPurifier_URI representation of URI. This representation has
|
||||
* not been validated yet and may not conform to RFC.
|
||||
*/
|
||||
public function parse($uri) {
|
||||
|
||||
$uri = $this->percentEncoder->normalize($uri);
|
||||
|
||||
// Regexp is as per Appendix B.
|
||||
// Note that ["<>] are an addition to the RFC's recommended
|
||||
// characters, because they represent external delimeters.
|
||||
$r_URI = '!'.
|
||||
'(([^:/?#<>\'"]+):)?'. // 2. Scheme
|
||||
'(//([^/?#<>\'"]*))?'. // 4. Authority
|
||||
'([^?#<>\'"]*)'. // 5. Path
|
||||
'(\?([^#<>\'"]*))?'. // 7. Query
|
||||
'(#([^<>\'"]*))?'. // 8. Fragment
|
||||
'(([^:/?#"<>]+):)?'. // 2. Scheme
|
||||
'(//([^/?#"<>]*))?'. // 4. Authority
|
||||
'([^?#"<>]*)'. // 5. Path
|
||||
'(\?([^#"<>]*))?'. // 7. Query
|
||||
'(#([^"<>]*))?'. // 8. Fragment
|
||||
'!';
|
||||
|
||||
$matches = array();
|
||||
@@ -36,13 +51,7 @@ class HTMLPurifier_URIParser
|
||||
|
||||
// further parse authority
|
||||
if ($authority !== null) {
|
||||
// ridiculously inefficient: it's a stacked regex!
|
||||
$HEXDIG = '[A-Fa-f0-9]';
|
||||
$unreserved = 'A-Za-z0-9-._~'; // make sure you wrap with []
|
||||
$sub_delims = '!$&\'()'; // needs []
|
||||
$pct_encoded = "%$HEXDIG$HEXDIG";
|
||||
$r_userinfo = "(?:[$unreserved$sub_delims:]|$pct_encoded)*";
|
||||
$r_authority = "/^(($r_userinfo)@)?(\[[^\]]+\]|[^:]*)(:(\d*))?/";
|
||||
$r_authority = "/^((.+?)@)?(\[[^\]]+\]|[^:]*)(:(\d*))?/";
|
||||
$matches = array();
|
||||
preg_match($r_authority, $authority, $matches);
|
||||
$userinfo = !empty($matches[1]) ? $matches[2] : null;
|
||||
|
@@ -62,7 +62,19 @@ foreach ($files as $file) {
|
||||
$tokens = token_get_all(file_get_contents($file));
|
||||
$file = str_replace('\\', '/', $file);
|
||||
for ($i = 0, $c = count($tokens); $i < $c; $i++) {
|
||||
if (!testToken($tokens[$i], T_VARIABLE, '$config')) continue;
|
||||
$ok = false;
|
||||
// Match $config
|
||||
if (!$ok && testToken($tokens[$i], T_VARIABLE, '$config')) $ok = true;
|
||||
// Match $this->config
|
||||
while (!$ok && testToken($tokens[$i], T_VARIABLE, '$this')) {
|
||||
consumeWhitespace($tokens, $i);
|
||||
if (!testToken($tokens[$i], T_OBJECT_OPERATOR)) break;
|
||||
consumeWhitespace($tokens, $i);
|
||||
if (testToken($tokens[$i], T_STRING, 'config')) $ok = true;
|
||||
break;
|
||||
}
|
||||
if (!$ok) continue;
|
||||
|
||||
$ok = false;
|
||||
for($i++; $i < $c; $i++) {
|
||||
if ($tokens[$i] === ',' || $tokens[$i] === ')' || $tokens[$i] === ';') {
|
||||
@@ -86,31 +98,40 @@ foreach ($files as $file) {
|
||||
|
||||
$full_counter++;
|
||||
|
||||
// The T_CONSTANT_ENCAPSED_STRING may hide some more obscure use-cases;
|
||||
// it may be useful to log these.
|
||||
consumeWhitespace($tokens, $i);
|
||||
if (!testToken($tokens[$i], T_CONSTANT_ENCAPSED_STRING)) continue;
|
||||
$namespace = substr($tokens[$i][1], 1, -1);
|
||||
$matched = false;
|
||||
do {
|
||||
|
||||
// What we currently don't match are batch retrievals, and
|
||||
// wildcard retrievals. This data might be useful in the future,
|
||||
// which is why we have a do {} while loop that doesn't actually
|
||||
// do anything.
|
||||
|
||||
consumeWhitespace($tokens, $i);
|
||||
if (!testToken($tokens[$i], T_CONSTANT_ENCAPSED_STRING)) continue;
|
||||
$namespace = substr($tokens[$i][1], 1, -1);
|
||||
|
||||
consumeWhitespace($tokens, $i);
|
||||
if (!testToken($tokens[$i], ',')) continue;
|
||||
|
||||
consumeWhitespace($tokens, $i);
|
||||
if (!testToken($tokens[$i], T_CONSTANT_ENCAPSED_STRING)) continue;
|
||||
$directive = substr($tokens[$i][1], 1, -1);
|
||||
|
||||
$counter++;
|
||||
$matched = true;
|
||||
|
||||
$id = "$namespace.$directive";
|
||||
if (!isset($tracker[$id])) $tracker[$id] = array();
|
||||
if (!isset($tracker[$id][$file])) $tracker[$id][$file] = array();
|
||||
$tracker[$id][$file][] = $line;
|
||||
|
||||
} while (0);
|
||||
|
||||
consumeWhitespace($tokens, $i);
|
||||
if (!testToken($tokens[$i], ',')) continue;
|
||||
|
||||
consumeWhitespace($tokens, $i);
|
||||
if (!testToken($tokens[$i], T_CONSTANT_ENCAPSED_STRING)) continue;
|
||||
$directive = substr($tokens[$i][1], 1, -1);
|
||||
|
||||
$counter++;
|
||||
|
||||
$id = "$namespace.$directive";
|
||||
if (!isset($tracker[$id])) $tracker[$id] = array();
|
||||
if (!isset($tracker[$id][$file])) $tracker[$id][$file] = array();
|
||||
$tracker[$id][$file][] = $line;
|
||||
|
||||
// echo "$file:$line uses $namespace.$directive\n";
|
||||
//echo "$file:$line uses $namespace.$directive\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n$counter/$full_counter instances of \$config found in source code.\n";
|
||||
echo "\n$counter/$full_counter instances of \$config or \$this->config found in source code.\n";
|
||||
|
||||
echo "Generating XML... ";
|
||||
|
||||
|
@@ -10,6 +10,7 @@ Changelog HTMLPurifier : Phorum Mod
|
||||
==========================
|
||||
|
||||
Version 3.0.0.1 for Phorum 5.2, unknown release date
|
||||
! Better installation documentation
|
||||
- Fixed double encoded quotes
|
||||
- Fixed fatal error when migrate.php is blank
|
||||
|
||||
|
79
plugins/phorum/INSTALL
Normal file
79
plugins/phorum/INSTALL
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
Install
|
||||
How to install the Phorum HTML Purifier plugin
|
||||
|
||||
1. UNZIP
|
||||
--------
|
||||
Unzip phorum-htmlpurifier-x.y.z, producing an htmlpurifier folder.
|
||||
You've already done this step if you're reading this!
|
||||
|
||||
2. MOVE
|
||||
-------
|
||||
Move the htmlpurifier folder to the mods/ folder of your Phorum
|
||||
installation, so the directory structure looks like:
|
||||
|
||||
phorum/
|
||||
mods/
|
||||
htmlpurifier/
|
||||
INSTALL - this install file
|
||||
info.txt, ... - the module files
|
||||
htmlpurifier/
|
||||
|
||||
3. INSTALL HTML PURIFIER
|
||||
------------------------
|
||||
Download and unzip HTML Purifier <htmlpurifier.org>. Place the contents of
|
||||
the library/ folder in the htmlpurifier/htmlpurifier folder. Your directory
|
||||
structure will look like:
|
||||
|
||||
phorum/
|
||||
mods/
|
||||
htmlpurifier/
|
||||
htmlpurifier/
|
||||
HTMLPurifier.auto.php
|
||||
... - other files
|
||||
HTMLPurifier/
|
||||
|
||||
Advanced users:
|
||||
If you have HTML Purifier installed elsewhere on your server,
|
||||
all you need is an HTMLPurifier.auto.php file in the library folder which
|
||||
includes the HTMLPurifier.auto.php file in your install.
|
||||
|
||||
4. MIGRATE
|
||||
----------
|
||||
If you're setting up a new Phorum installation, all you need to do is create
|
||||
a blank migrate.php file in the htmlpurifier module folder (NOT the library
|
||||
folder.
|
||||
|
||||
If you have an old Phorum installation and was using BBCode,
|
||||
copy migrate.bbcode.php to migrate.php. If you were using a different input
|
||||
format, follow the instructions in migrate.bbcode.php to create your own custom
|
||||
migrate.php file.
|
||||
|
||||
Your directory structure should now look like this:
|
||||
|
||||
phorum/
|
||||
mods/
|
||||
htmlpurifier/
|
||||
migrate.php
|
||||
|
||||
5. ENABLE
|
||||
---------
|
||||
Navigate to your Phorum admin panel at http://example.com/phorum/admin.php,
|
||||
click on Global Settings > Modules, scroll to "HTML Purifier Phorum Mod" and
|
||||
turn it On.
|
||||
|
||||
6. MIGRATE SIGNATURES
|
||||
---------------------
|
||||
If you're setting up a new Phorum installation, skip this step.
|
||||
|
||||
If you allowed your users to make signatures, navigate to the module settings
|
||||
page of HTML Purifier (Global Settings > Modules > HTML Purifier Phorum Mod >
|
||||
Configure), type in "yes" in the "Confirm" box, and press "Migrate."
|
||||
|
||||
ONLY DO THIS ONCE! BE SURE TO BACK UP YOUR DATABASE!
|
||||
|
||||
7. CONFIGURE
|
||||
------------
|
||||
Configure using Edit settings. See that page for more information.
|
||||
|
||||
|
@@ -24,21 +24,23 @@ $version = trim($argv[1]);
|
||||
file_put_contents('VERSION', $version);
|
||||
|
||||
// ...in NEWS
|
||||
$date = date('Y-m-d');
|
||||
$news_c = str_replace(
|
||||
$l = "$version, unknown release date",
|
||||
"$version, released $date",
|
||||
file_get_contents('NEWS'),
|
||||
$c
|
||||
);
|
||||
if (!$c) {
|
||||
echo 'Could not update NEWS, missing ' . $l . PHP_EOL;
|
||||
exit;
|
||||
} elseif ($c > 1) {
|
||||
echo 'More than one release declaration in NEWS replaced' . PHP_EOL;
|
||||
exit;
|
||||
if ($is_dev = (strpos($version, 'dev') === false)) {
|
||||
$date = date('Y-m-d');
|
||||
$news_c = str_replace(
|
||||
$l = "$version, unknown release date",
|
||||
"$version, released $date",
|
||||
file_get_contents('NEWS'),
|
||||
$c
|
||||
);
|
||||
if (!$c) {
|
||||
echo 'Could not update NEWS, missing ' . $l . PHP_EOL;
|
||||
exit;
|
||||
} elseif ($c > 1) {
|
||||
echo 'More than one release declaration in NEWS replaced' . PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
file_put_contents('NEWS', $news_c);
|
||||
}
|
||||
file_put_contents('NEWS', $news_c);
|
||||
|
||||
// ...in Doxyfile
|
||||
$doxyfile_c = preg_replace(
|
||||
@@ -72,7 +74,17 @@ $htmlpurifier_c = preg_replace(
|
||||
1, $c
|
||||
);
|
||||
if (!$c) {
|
||||
echo 'Could not update HTMLPurifier.php, missing var $version.' . PHP_EOL;
|
||||
echo 'Could not update HTMLPurifier.php, missing public $version.' . PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
$htmlpurifier_c = preg_replace(
|
||||
'/const VERSION = \'.+?\';/',
|
||||
"const VERSION = '$version';",
|
||||
$htmlpurifier_c,
|
||||
1, $c
|
||||
);
|
||||
if (!$c) {
|
||||
echo 'Could not update HTMLPurifier.php, missing const $version.' . PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
file_put_contents('library/HTMLPurifier.php', $htmlpurifier_c);
|
||||
@@ -85,10 +97,12 @@ $config_c = preg_replace(
|
||||
1, $c
|
||||
);
|
||||
if (!$c) {
|
||||
echo 'Could not update Config.php, missing var $version.' . PHP_EOL;
|
||||
echo 'Could not update Config.php, missing public $version.' . PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
file_put_contents('library/HTMLPurifier/Config.php', $config_c);
|
||||
|
||||
echo "Review changes, write something in WHATSNEW, and then SVN commit with log 'Release $version.'" . PHP_EOL;
|
||||
passthru('php maintenance/flush.php');
|
||||
|
||||
if ($is_dev) echo "Review changes, write something in WHATSNEW, and then SVN commit with log 'Release $version.'" . PHP_EOL;
|
||||
else echo "Numbers updated to dev, no other modifications necessary!";
|
||||
|
@@ -2,31 +2,37 @@
|
||||
|
||||
require_once 'common.php';
|
||||
|
||||
// Setup environment
|
||||
require_once '../extras/HTMLPurifierExtras.auto.php';
|
||||
$interchange = HTMLPurifier_ConfigSchema_InterchangeBuilder::buildFromDirectory('test-schema/');
|
||||
$interchange->validate();
|
||||
|
||||
if (isset($_GET['doc'])) {
|
||||
|
||||
if (
|
||||
file_exists('testSchema.html') &&
|
||||
filemtime('testSchema.php') < filemtime('testSchema.html') &&
|
||||
!isset($_GET['purge'])
|
||||
) {
|
||||
echo file_get_contents('testSchema.html');
|
||||
// Hijack page generation to supply documentation
|
||||
|
||||
if (file_exists('test-schema.html') && !isset($_GET['purge'])) {
|
||||
echo file_get_contents('test-schema.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (version_compare('5', PHP_VERSION, '>')) exit('Requires PHP 5 or higher.');
|
||||
|
||||
// setup ConfigDoc environment
|
||||
require_once '../configdoc/library/ConfigDoc.auto.php';
|
||||
|
||||
// perform the ConfigDoc generation
|
||||
$configdoc = new ConfigDoc();
|
||||
$html = $configdoc->generate($new_schema, 'plain', array(
|
||||
'css' => '../configdoc/styles/plain.css',
|
||||
'title' => 'Sample Configuration Documentation'
|
||||
$style = 'plain';
|
||||
$configdoc_xml = 'test-schema.xml';
|
||||
|
||||
$xml_builder = new HTMLPurifier_ConfigSchema_Builder_Xml();
|
||||
$xml_builder->openURI($configdoc_xml);
|
||||
$xml_builder->build($interchange);
|
||||
unset($xml_builder); // free handle
|
||||
|
||||
$xslt = new ConfigDoc_HTMLXSLTProcessor();
|
||||
$xslt->importStylesheet("../configdoc/styles/$style.xsl");
|
||||
$xslt->setParameters(array(
|
||||
'css' => '../configdoc/styles/plain.css',
|
||||
));
|
||||
$configdoc->cleanup();
|
||||
$html = $xslt->transformToHTML($configdoc_xml);
|
||||
|
||||
file_put_contents('testSchema.html', $html);
|
||||
unlink('test-schema.xml');
|
||||
file_put_contents('test-schema.html', $html);
|
||||
echo $html;
|
||||
|
||||
exit;
|
||||
@@ -50,15 +56,11 @@ of directive possible.</p>
|
||||
style="float:right;">
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/Printer/ConfigForm.php';
|
||||
$schema_builder = new HTMLPurifier_ConfigSchema_Builder_ConfigSchema();
|
||||
$schema = $schema_builder->build($interchange);
|
||||
HTMLPurifier_ConfigSchema::instance($schema);
|
||||
|
||||
// fictional set, attempts to cover every possible data-type
|
||||
// see source at ConfigTest.php
|
||||
require_once 'testSchema.php';
|
||||
HTMLPurifier_ConfigSchema::instance($custom_schema);
|
||||
|
||||
// cleanup ( this should be rolled into Config )
|
||||
$config = HTMLPurifier_Config::loadArrayFromForm($_GET, 'config');
|
||||
$config = HTMLPurifier_Config::loadArrayFromForm($_GET, 'config');
|
||||
$printer = new HTMLPurifier_Printer_ConfigForm('config', '?doc#%s');
|
||||
echo $printer->render($config);
|
||||
|
||||
@@ -66,7 +68,7 @@ echo $printer->render($config);
|
||||
</form>
|
||||
<pre>
|
||||
<?php
|
||||
echo htmlspecialchars(print_r($config->getAll(), true));
|
||||
echo htmlspecialchars(var_export($config->getAll(), true));
|
||||
?>
|
||||
</pre>
|
||||
</body>
|
||||
|
5
smoketests/test-schema/Directive.Allowed.txt
Normal file
5
smoketests/test-schema/Directive.Allowed.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Directive.Allowed
|
||||
TYPE: string
|
||||
DEFAULT: 'apple'
|
||||
ALLOWED: 'apple', 'orange', 'pear', 'peach', 'mango'
|
||||
DESCRIPTION: This directive has a constrained set of allowed values.
|
6
smoketests/test-schema/Directive.Deprecated.txt
Normal file
6
smoketests/test-schema/Directive.Deprecated.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Directive.Deprecated
|
||||
TYPE: int
|
||||
DEFAULT: 0
|
||||
DESCRIPTION: This is a deprecated directive that shouldn't show up on the form.
|
||||
DEPRECATED-VERSION: 1.0.0
|
||||
DEPRECATED-USE: Directive.Allowed
|
2
smoketests/test-schema/Directive.txt
Normal file
2
smoketests/test-schema/Directive.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Directive
|
||||
DESCRIPTION: Other custom options with directives.
|
4
smoketests/test-schema/Type.bool.txt
Normal file
4
smoketests/test-schema/Type.bool.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.bool
|
||||
TYPE: bool
|
||||
DEFAULT: false
|
||||
DESCRIPTION: The boolean type is true or false.
|
4
smoketests/test-schema/Type.float.txt
Normal file
4
smoketests/test-schema/Type.float.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.float
|
||||
TYPE: float
|
||||
DEFAULT: 3.1415
|
||||
DESCRIPTION: The float type is a floating point number.
|
4
smoketests/test-schema/Type.hash.txt
Normal file
4
smoketests/test-schema/Type.hash.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.hash
|
||||
TYPE: hash
|
||||
DEFAULT: array('key1' => 'val1', 'key2' => 'val2')
|
||||
DESCRIPTION: The hash type is an associative array of string keys and string values.
|
4
smoketests/test-schema/Type.int.txt
Normal file
4
smoketests/test-schema/Type.int.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.int
|
||||
TYPE: int
|
||||
DEFAULT: 23
|
||||
DESCRIPTION: The int type is an signed integer.
|
4
smoketests/test-schema/Type.istring.txt
Normal file
4
smoketests/test-schema/Type.istring.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.istring
|
||||
TYPE: istring
|
||||
DEFAULT: 'case insensitive'
|
||||
DESCRIPTION: The istring type is short (no newlines), must be ASCII and is case-insensitive.
|
4
smoketests/test-schema/Type.itext.txt
Normal file
4
smoketests/test-schema/Type.itext.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.itext
|
||||
TYPE: itext
|
||||
DEFAULT: "case\ninsensitive\nand\npossibly\nquite\nlong"
|
||||
DESCRIPTION: The text type has newlines, must be ASCII and is case-insensitive.
|
4
smoketests/test-schema/Type.list.txt
Normal file
4
smoketests/test-schema/Type.list.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.list
|
||||
TYPE: list
|
||||
DEFAULT: array('item1', 'item2')
|
||||
DESCRIPTION: The list type is a numerically indexed array of strings.
|
4
smoketests/test-schema/Type.lookup.txt
Normal file
4
smoketests/test-schema/Type.lookup.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.lookup
|
||||
TYPE: lookup
|
||||
DEFAULT: array('key1' => true, 'key2' => true)
|
||||
DESCRIPTION: The lookup type acts just like list, except its elements are unique and are checked with <code>isset($var[$key])</code>.
|
4
smoketests/test-schema/Type.mixed.txt
Normal file
4
smoketests/test-schema/Type.mixed.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.mixed
|
||||
TYPE: mixed
|
||||
DEFAULT: new stdclass()
|
||||
DESCRIPTION: The mixed type allows any type, and is not form-editable.
|
6
smoketests/test-schema/Type.nullbool.txt
Normal file
6
smoketests/test-schema/Type.nullbool.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Type.nullbool
|
||||
TYPE: bool/null
|
||||
DEFAULT: null
|
||||
--DESCRIPTION--
|
||||
Null booleans need to be treated a little specially. See %Type.nullstring
|
||||
for information on what the null flag does.
|
8
smoketests/test-schema/Type.nullstring.txt
Normal file
8
smoketests/test-schema/Type.nullstring.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Type.nullstring
|
||||
TYPE: string/null
|
||||
DEFAULT: null
|
||||
--DESCRIPTION--
|
||||
The null type is not a type, but a flag that can be added to any type
|
||||
making null a valid value for that entry. It's useful for saying, "Let
|
||||
the software pick the value for me," or "Don't use this element" when
|
||||
false has a special meaning.
|
4
smoketests/test-schema/Type.string.txt
Normal file
4
smoketests/test-schema/Type.string.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.string
|
||||
TYPE: string
|
||||
DEFAULT: 'Case sensitive'
|
||||
DESCRIPTION: The string type is short (no newlines) and case-sensitive.
|
4
smoketests/test-schema/Type.text.txt
Normal file
4
smoketests/test-schema/Type.text.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Type.text
|
||||
TYPE: text
|
||||
DEFAULT: "Case sensitive\nand\npossibly\nquite long..."
|
||||
DESCRIPTION: The text type has newlines and is case-sensitive.
|
2
smoketests/test-schema/Type.txt
Normal file
2
smoketests/test-schema/Type.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Type
|
||||
DESCRIPTION: Directives demonstration the variable types ConfigSchema supports.
|
1
smoketests/test-schema/info.ini
Normal file
1
smoketests/test-schema/info.ini
Normal file
@@ -0,0 +1 @@
|
||||
name = "Test Schema"
|
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
// overload default configuration schema temporarily
|
||||
$custom_schema = new HTMLPurifier_ConfigSchema();
|
||||
|
||||
$custom_schema->addNamespace('Element', 'Chemical substances that cannot be further decomposed');
|
||||
|
||||
$custom_schema->add('Element', 'Abbr', 'H', 'string', false, 'Abbreviation of element name.');
|
||||
$custom_schema->add('Element', 'Name', 'hydrogen', 'istring', false, 'Full name of atoms.');
|
||||
$custom_schema->add('Element', 'Number', 1, 'int', false, 'Atomic number, is identity.');
|
||||
$custom_schema->add('Element', 'Mass', 1.00794, 'float', false, 'Atomic mass.');
|
||||
$custom_schema->add('Element', 'Radioactive', false, 'bool', false, 'Does it have rapid decay?');
|
||||
$custom_schema->add('Element', 'Isotopes', array('1' => true, '2' => true, '3' => true), 'lookup', false,
|
||||
'What numbers of neutrons for this element have been observed?');
|
||||
$custom_schema->add('Element', 'Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', false,
|
||||
'What are general properties of the element?');
|
||||
$custom_schema->add('Element', 'IsotopeNames', array('1' => 'protium', '2' => 'deuterium', '3' => 'tritium'), 'hash', false,
|
||||
'Lookup hash of neutron counts to formal names.');
|
||||
|
||||
$custom_schema->addNamespace('Instrument', 'Of the musical type.');
|
||||
|
||||
$custom_schema->add('Instrument', 'Manufacturer', 'Yamaha', 'string', false, 'Who made it?');
|
||||
$custom_schema->addAllowedValues('Instrument', 'Manufacturer', array(
|
||||
'Yamaha', 'Conn-Selmer', 'Vandoren', 'Laubin', 'Buffet', 'other'));
|
||||
$custom_schema->addValueAliases('Instrument', 'Manufacturer', array(
|
||||
'Selmer' => 'Conn-Selmer'));
|
||||
|
||||
$custom_schema->add('Instrument', 'Family', 'woodwind', 'istring', false, 'What family is it?');
|
||||
$custom_schema->addAllowedValues('Instrument', 'Family', array(
|
||||
'brass', 'woodwind', 'percussion', 'string', 'keyboard', 'electronic'));
|
||||
$custom_schema->addValueAliases('Instrument', 'Family', array(
|
||||
'synth' => 'electronic'));
|
||||
|
||||
$custom_schema->addNamespace('ReportCard', 'It is for grades.');
|
||||
$custom_schema->add('ReportCard', 'English', null, 'string', true, 'Grade from English class.');
|
||||
$custom_schema->add('ReportCard', 'Absences', 0, 'int', false, 'How many times missing from school?');
|
||||
|
||||
$custom_schema->addNamespace('Text', 'This stuff is long, boring, and English.');
|
||||
$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?');
|
||||
$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.');
|
||||
|
@@ -14,6 +14,27 @@ class HTMLPurifier_AttrDef_URI_HostTest extends HTMLPurifier_AttrDefHarness
|
||||
$this->assertDef('124.15.6.89'); // IPv4
|
||||
$this->assertDef('www.google.com'); // reg-name
|
||||
|
||||
// more domain name tests
|
||||
$this->assertDef('test.');
|
||||
$this->assertDef('sub.test.');
|
||||
$this->assertDef('.test', false);
|
||||
$this->assertDef('ff');
|
||||
$this->assertDef('1f', false);
|
||||
$this->assertDef('-f', false);
|
||||
$this->assertDef('f1');
|
||||
$this->assertDef('f-', false);
|
||||
$this->assertDef('sub.ff');
|
||||
$this->assertDef('sub.1f', false);
|
||||
$this->assertDef('sub.-f', false);
|
||||
$this->assertDef('sub.f1');
|
||||
$this->assertDef('sub.f-', false);
|
||||
$this->assertDef('ff.top');
|
||||
$this->assertDef('1f.top');
|
||||
$this->assertDef('-f.top', false);
|
||||
$this->assertDef('ff.top');
|
||||
$this->assertDef('f1.top');
|
||||
$this->assertDef('f-.top', false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -29,6 +29,19 @@ class HTMLPurifier_AttrDef_URITest extends HTMLPurifier_AttrDefHarness
|
||||
);
|
||||
}
|
||||
|
||||
function testPercentEncoding() {
|
||||
$this->assertDef(
|
||||
'http:colon:mercenary',
|
||||
'colon%3Amercenary'
|
||||
);
|
||||
}
|
||||
|
||||
function testPercentEncodingPreserve() {
|
||||
$this->assertDef(
|
||||
'http://www.example.com/abcABC123-_.!~*()\''
|
||||
);
|
||||
}
|
||||
|
||||
function testEmbeds() {
|
||||
$this->def = new HTMLPurifier_AttrDef_URI(true);
|
||||
$this->assertDef('http://sub.example.com/alas?foo=asd');
|
||||
@@ -65,14 +78,31 @@ class HTMLPurifier_AttrDef_URITest extends HTMLPurifier_AttrDefHarness
|
||||
$parser = new HTMLPurifier_URIParser();
|
||||
$uri = $parser->parse('http://example.com');
|
||||
$this->config->set('URI', 'DefinitionID', 'HTMLPurifier_AttrDef_URITest->testURIDefinitionValidation');
|
||||
$uri_def =& $this->config->getDefinition('URI');
|
||||
// overload with mock
|
||||
|
||||
generate_mock_once('HTMLPurifier_URIDefinition');
|
||||
$uri_def = new HTMLPurifier_URIDefinitionMock();
|
||||
$uri_def->expectOnce('filter', array($uri, '*', '*'));
|
||||
$uri_def->setReturnValue('filter', true, array($uri, '*', '*'));
|
||||
$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');
|
||||
|
||||
HTMLPurifier_DefinitionCacheFactory::instance($old);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -11,7 +11,7 @@ class HTMLPurifier_AttrValidator_ErrorsTest extends HTMLPurifier_ErrorsHarness
|
||||
function testAttributesTransformedGlobalPre() {
|
||||
$this->config->set('HTML', 'DefinitionID',
|
||||
'HTMLPurifier_AttrValidator_ErrorsTest::testAttributesTransformedGlobalPre');
|
||||
$def =& $this->config->getHTMLDefinition(true);
|
||||
$def = $this->config->getHTMLDefinition(true);
|
||||
generate_mock_once('HTMLPurifier_AttrTransform');
|
||||
$transform = new HTMLPurifier_AttrTransformMock();
|
||||
$input = array('original' => 'value');
|
||||
|
@@ -35,11 +35,6 @@ class HTMLPurifier_ComplexHarness extends HTMLPurifier_Harness
|
||||
*/
|
||||
protected $lexer;
|
||||
|
||||
/**
|
||||
* Instance of HTMLPurifier_Generator
|
||||
*/
|
||||
protected $generator;
|
||||
|
||||
/**
|
||||
* Default config to fall back on if no config is available
|
||||
*/
|
||||
@@ -52,7 +47,6 @@ class HTMLPurifier_ComplexHarness extends HTMLPurifier_Harness
|
||||
|
||||
public function __construct() {
|
||||
$this->lexer = new HTMLPurifier_Lexer_DirectLex();
|
||||
$this->generator = new HTMLPurifier_Generator();
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
@@ -110,7 +104,8 @@ class HTMLPurifier_ComplexHarness extends HTMLPurifier_Harness
|
||||
* Generate textual HTML from tokens
|
||||
*/
|
||||
protected function generate($tokens) {
|
||||
return $this->generator->generateFromTokens($tokens, $this->config, $this->context);
|
||||
$generator = new HTMLPurifier_Generator($this->config, $this->context);
|
||||
return $generator->generateFromTokens($tokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -219,27 +219,25 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->assertIsA($def, 'HTMLPurifier_CSSDefinition');
|
||||
|
||||
$def =& $config->getHTMLDefinition();
|
||||
$def2 =& $config->getHTMLDefinition();
|
||||
$def = $config->getHTMLDefinition();
|
||||
$def2 = $config->getHTMLDefinition();
|
||||
$this->assertIsA($def, 'HTMLPurifier_HTMLDefinition');
|
||||
$this->assertReference($def, $def2);
|
||||
$this->assertSame($def, $def2);
|
||||
$this->assertTrue($def->setup);
|
||||
|
||||
// test re-calculation if HTML changes
|
||||
unset($def, $def2);
|
||||
$def2 = $config->getHTMLDefinition(); // forcibly de-reference
|
||||
$old_def = clone $def2;
|
||||
|
||||
$config->set('HTML', 'Doctype', 'HTML 4.01 Transitional');
|
||||
$def = $config->getHTMLDefinition();
|
||||
$this->assertIsA($def, 'HTMLPurifier_HTMLDefinition');
|
||||
$this->assertNotEqual($def, $def2);
|
||||
$this->assertNotEqual($def, $old_def);
|
||||
$this->assertTrue($def->setup);
|
||||
|
||||
// test retrieval of raw definition
|
||||
$config->set('HTML', 'DefinitionID', 'HTMLPurifier_ConfigTest->test_getHTMLDefinition()');
|
||||
$config->set('HTML', 'DefinitionRev', 3);
|
||||
$def =& $config->getHTMLDefinition(true);
|
||||
$this->assertNotEqual($def, $def2);
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
$this->assertNotEqual($def, $old_def);
|
||||
$this->assertEqual(false, $def->setup);
|
||||
|
||||
// auto initialization
|
||||
@@ -250,8 +248,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function test_getHTMLDefinition_rawError() {
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$this->expectError('Cannot retrieve raw version without specifying %HTML.DefinitionID');
|
||||
$def =& $config->getHTMLDefinition(true);
|
||||
$this->expectException(new HTMLPurifier_Exception('Cannot retrieve raw version without specifying %HTML.DefinitionID'));
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
}
|
||||
|
||||
function test_getCSSDefinition() {
|
||||
@@ -265,7 +263,7 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
$this->schema->add('Cache', 'DefinitionImpl', null, 'string', true);
|
||||
$this->schema->addNamespace('Crust', 'Krusty Krabs');
|
||||
$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');
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,7 @@ class HTMLPurifier_DefinitionCache_SerializerTest extends HTMLPurifier_Definitio
|
||||
$config->setReturnValue('get', 2, array('Test', 'DefinitionRev'));
|
||||
$config->version = '1.0.0';
|
||||
|
||||
$config_md5 = '1.0.0-serial-2';
|
||||
$config_md5 = '1.0.0,serial,2';
|
||||
|
||||
$file = realpath(
|
||||
$rel_file = HTMLPURIFIER_PREFIX . '/HTMLPurifier/DefinitionCache/Serializer/Test/' .
|
||||
@@ -186,9 +186,9 @@ class HTMLPurifier_DefinitionCache_SerializerTest extends HTMLPurifier_Definitio
|
||||
|
||||
$def_original = $this->generateDefinition();
|
||||
$cache->add($def_original, $config);
|
||||
$this->assertFileExist($dir . '/Test/1.0.0-serial-1.ser');
|
||||
$this->assertFileExist($dir . '/Test/1.0.0,serial,1.ser');
|
||||
|
||||
unlink($dir . '/Test/1.0.0-serial-1.ser');
|
||||
unlink($dir . '/Test/1.0.0,serial,1.ser');
|
||||
rmdir( $dir . '/Test');
|
||||
|
||||
}
|
||||
|
@@ -13,16 +13,17 @@ class HTMLPurifier_DefinitionCacheTest extends HTMLPurifier_Harness
|
||||
$config->setReturnValue('get', 10, array('Test', 'DefinitionRev'));
|
||||
$config->setReturnValue('getBatchSerial', 'hash', array('Test'));
|
||||
|
||||
$this->assertIdentical($cache->isOld('1.0.0-hash-10', $config), false);
|
||||
$this->assertIdentical($cache->isOld('1.5.0-hash-1', $config), true);
|
||||
$this->assertIdentical($cache->isOld('1.0.0,hash,10', $config), false);
|
||||
$this->assertIdentical($cache->isOld('1.5.0,hash,1', $config), true);
|
||||
|
||||
$this->assertIdentical($cache->isOld('0.9.0-hash-1', $config), true);
|
||||
$this->assertIdentical($cache->isOld('1.0.0-hash-1', $config), true);
|
||||
$this->assertIdentical($cache->isOld('1.0.0beta-hash-11', $config), true);
|
||||
$this->assertIdentical($cache->isOld('0.9.0,hash,1', $config), true);
|
||||
$this->assertIdentical($cache->isOld('1.0.0,hash,1', $config), true);
|
||||
$this->assertIdentical($cache->isOld('1.0.0beta,hash,11', $config), true);
|
||||
|
||||
$this->assertIdentical($cache->isOld('0.9.0-hash2-1', $config), true);
|
||||
$this->assertIdentical($cache->isOld('1.0.0-hash2-1', $config), false); // if hash is different, don't touch!
|
||||
$this->assertIdentical($cache->isOld('1.0.0beta-hash2-11', $config), true);
|
||||
$this->assertIdentical($cache->isOld('0.9.0,hash2,1', $config), true);
|
||||
$this->assertIdentical($cache->isOld('1.0.0,hash2,1', $config), false); // if hash is different, don't touch!
|
||||
$this->assertIdentical($cache->isOld('1.0.0beta,hash2,11', $config), true);
|
||||
$this->assertIdentical($cache->isOld('1.0.0-dev,hash2,11', $config), true);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@ class HTMLPurifier_DoctypeRegistryTest extends HTMLPurifier_Harness
|
||||
|
||||
$registry = new HTMLPurifier_DoctypeRegistry();
|
||||
|
||||
$d =& $registry->register(
|
||||
$d = $registry->register(
|
||||
$name = 'XHTML 1.0 Transitional',
|
||||
$xml = true,
|
||||
$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);
|
||||
|
||||
$this->assertIdentical($d, $d2);
|
||||
$this->assertReference($d, $registry->get('XHTML 1.0 Transitional'));
|
||||
$this->assertSame($d, $registry->get('XHTML 1.0 Transitional'));
|
||||
|
||||
// test shorthand
|
||||
$d =& $registry->register(
|
||||
$d = $registry->register(
|
||||
$name = 'XHTML 1.0 Strict', true, 'module', 'Tidy', '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();
|
||||
|
||||
$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->assertReference($d1, $registry->get('1'));
|
||||
$this->assertSame($d1, $registry->get('Doc1'));
|
||||
$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->assertReference($d2, $registry->get('2'));
|
||||
$this->assertSame($d2, $registry->get('Doc2'));
|
||||
$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
|
||||
$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
|
||||
$this->assertReference($d3, $registry->get('1'));
|
||||
$this->assertSame($d3, $registry->get('1'));
|
||||
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user