mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-08-05 21:57:26 +02:00
Compare commits
109 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
280211f70b | ||
|
3fd51d527c | ||
|
0e6e2c4edf | ||
|
22d24e6b04 | ||
|
3a2fd0b5db | ||
|
25fa53c15b | ||
|
0b6ae1c3c1 | ||
|
ab263a0bf1 | ||
|
c5b18d345c | ||
|
d26418ca3a | ||
|
d304c5c976 | ||
|
f7bc0b0875 | ||
|
70515dd48f | ||
|
1555cb617f | ||
|
cd4500457e | ||
|
fa413e96ac | ||
|
d0fdcc103e | ||
|
6a06b92f0c | ||
|
3184fee468 | ||
|
ed7983b559 | ||
|
92df9e5b28 | ||
|
2f41bd07fa | ||
|
c6914dce51 | ||
|
9977350143 | ||
|
d9e60350d3 | ||
|
c807ed5fe2 | ||
|
c9b6f125aa | ||
|
dc28346677 | ||
|
8423daef05 | ||
|
617f70a8ac | ||
|
0423985b45 | ||
|
e013bc9126 | ||
|
1d90bb2397 | ||
|
03dabec2c0 | ||
|
85090520f1 | ||
|
3b6aa10592 | ||
|
3a4b92da81 | ||
|
0ec9731184 | ||
|
e05bd77344 | ||
|
334ffac5b4 | ||
|
a227cb483a | ||
|
aa0fdeee30 | ||
|
ba418a1f19 | ||
|
c845f0bb78 | ||
|
594268ca3b | ||
|
965be3bd73 | ||
|
700d5bcbfc | ||
|
fd384129bf | ||
|
f8b47c64dd | ||
|
a5ceb1e22a | ||
|
636e2883df | ||
|
dba3ed7770 | ||
|
de9869d942 | ||
|
cfcdce0db8 | ||
|
6bc04e0e10 | ||
|
24f6db6fb2 | ||
|
85fb192d93 | ||
|
7727cea112 | ||
|
6bb8c1fcac | ||
|
a84b6d5be0 | ||
|
6e43cac9c9 | ||
|
656a0c95bf | ||
|
7015aaff46 | ||
|
1009bd41a6 | ||
|
511dfe2d4a | ||
|
463aa3a0fa | ||
|
7189ec2790 | ||
|
e901d832ab | ||
|
643ed1bddc | ||
|
41830cd902 | ||
|
261aa1aeaa | ||
|
486b401cf7 | ||
|
f2794e59c5 | ||
|
d702077d2e | ||
|
36bd06d53e | ||
|
13eb016e06 | ||
|
32025a12e1 | ||
|
7dae94c44b | ||
|
54cc691ba7 | ||
|
3af2ff8f98 | ||
|
36fb284d2f | ||
|
8d1f1e8e73 | ||
|
322288e6c0 | ||
|
3c4346cb1e | ||
|
14d934c7ca | ||
|
bb16d8eae5 | ||
|
10530d7f81 | ||
|
c7e172f660 | ||
|
917d2ea5ef | ||
|
895141e0b5 | ||
|
8ab30e24b7 | ||
|
9db891c3aa | ||
|
eb9f9bc7f6 | ||
|
fcebb7731d | ||
|
8d0d0d1a03 | ||
|
80f59206d7 | ||
|
af3f5190dc | ||
|
5620241165 | ||
|
c06727190e | ||
|
1a95852007 | ||
|
c3fab7200e | ||
|
6d7a17e9b6 | ||
|
64b5581bf2 | ||
|
d8da5ff406 | ||
|
fda310f1e7 | ||
|
fc7dbdbd33 | ||
|
02ac821503 | ||
|
16fa73afa0 | ||
|
32a6afa27c |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
configdoc/usage.xml -crlf
|
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
conf/
|
||||||
|
test-settings.php
|
||||||
|
library/HTMLPurifier/DefinitionCache/Serializer/*/
|
||||||
|
library/standalone/
|
||||||
|
library/HTMLPurifier.standalone.php
|
||||||
|
configdoc/*.html
|
||||||
|
configdoc/configdoc.xml
|
||||||
|
*.phpt.diff
|
||||||
|
*.phpt.exp
|
||||||
|
*.phpt.log
|
||||||
|
*.phpt.out
|
||||||
|
*.phpt.php
|
||||||
|
*.phpt.skip.php
|
2
Doxyfile
2
Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier
|
|||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 3.1.0
|
PROJECT_NUMBER = 3.2.0
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
|
13
FOCUS
Normal file
13
FOCUS
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
5 - Major feature enhancements
|
||||||
|
|
||||||
|
[ Appendix A: Release focus IDs ]
|
||||||
|
0 - N/A
|
||||||
|
1 - Initial freshmeat announcement
|
||||||
|
2 - Documentation
|
||||||
|
3 - Code cleanup
|
||||||
|
4 - Minor feature enhancements
|
||||||
|
5 - Major feature enhancements
|
||||||
|
6 - Minor bugfixes
|
||||||
|
7 - Major bugfixes
|
||||||
|
8 - Minor security fixes
|
||||||
|
9 - Major security fixes
|
5
INSTALL
5
INSTALL
@@ -23,8 +23,9 @@ August 8, 2008.
|
|||||||
|
|
||||||
These optional extensions can enhance the capabilities of HTML Purifier:
|
These optional extensions can enhance the capabilities of HTML Purifier:
|
||||||
|
|
||||||
* iconv : Converts text to and from non-UTF-8 encodings
|
* iconv : Converts text to and from non-UTF-8 encodings
|
||||||
* tidy : Used for pretty-printing HTML
|
* bcmath : Used for unit conversion and imagecrash protection
|
||||||
|
* tidy : Used for pretty-printing HTML
|
||||||
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
147
NEWS
147
NEWS
@@ -9,6 +9,150 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
. Internal change
|
. Internal change
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
3.2.0, released 2008-10-31
|
||||||
|
# Using %Core.CollectErrors forces line number/column tracking on, whereas
|
||||||
|
previously you could theoretically turn it off.
|
||||||
|
# HTMLPurifier_Injector->notifyEnd() is formally deprecated. Please
|
||||||
|
use handleEnd() instead.
|
||||||
|
! %Output.AttrSort for when you need your attributes in alphabetical order to
|
||||||
|
deal with a bug in FCKEditor. Requested by frank farmer.
|
||||||
|
! Enable HTML comments when %HTML.Trusted is on. Requested by Waldo Jaquith.
|
||||||
|
! Proper support for name attribute. It is now allowed and equivalent to the id
|
||||||
|
attribute in a and img tags, and is only converted to id when %HTML.TidyLevel
|
||||||
|
is heavy (for all doctypes).
|
||||||
|
! %AutoFormat.RemoveEmpty to remove some empty tags from documents. Please don't
|
||||||
|
use on hand-written HTML.
|
||||||
|
! Add error-cases for unsupported elements in MakeWellFormed. This enables
|
||||||
|
the strategy to be used, standalone, on untrusted input.
|
||||||
|
! %Core.AggressivelyFixLt is on by default. This causes more sensible
|
||||||
|
processing of left angled brackets in smileys and other whatnot.
|
||||||
|
! Test scripts now have a 'type' parameter, which lets you say 'htmlpurifier',
|
||||||
|
'phpt', 'vtest', etc. in order to only execute those tests. This supercedes
|
||||||
|
the --only-phpt parameter, although for backwards-compatibility the flag
|
||||||
|
will still work.
|
||||||
|
! AutoParagraph auto-formatter will now preserve double-newlines upon output.
|
||||||
|
Users who are not performing inbound filtering, this may seem a little
|
||||||
|
useless, but as a bonus, the test suite and handling of edge cases is also
|
||||||
|
improved.
|
||||||
|
! Experimental implementation of forms for %HTML.Trusted
|
||||||
|
! Track column numbers when maintain line numbers is on
|
||||||
|
! Proprietary 'background' attribute on table-related elements converted into
|
||||||
|
corresponding CSS. Thanks Fusemail for sponsoring this feature!
|
||||||
|
! Add forward(), forwardUntilEndToken(), backward() and current() to Injector
|
||||||
|
supertype.
|
||||||
|
! HTMLPurifier_Injector->handleEnd() permits modification to end tokens. The
|
||||||
|
time of operation varies slightly from notifyEnd() as *all* end tokens are
|
||||||
|
processed by the injector before they are subject to the well-formedness rules.
|
||||||
|
! %Attr.DefaultImageAlt allows overriding default behavior of setting alt to
|
||||||
|
basename of image when not present.
|
||||||
|
! %AutoFormat.DisplayLinkURI neuters <a> tags into plain text URLs.
|
||||||
|
- Fix two bugs in %URI.MakeAbsolute; one involving empty paths in base URLs,
|
||||||
|
the other involving an undefined $is_folder error.
|
||||||
|
- Throw error when %Core.Encoding is set to a spurious value. Previously,
|
||||||
|
this errored silently and returned false.
|
||||||
|
- Redirected stderr to stdout for flush error output.
|
||||||
|
- %URI.DisableExternal will now use the host in %URI.Base if %URI.Host is not
|
||||||
|
available.
|
||||||
|
- Do not re-munge URL if the output URL has the same host as the input URL.
|
||||||
|
Requested by Chris.
|
||||||
|
- Fix error in documentation regarding %Filter.ExtractStyleBlocks
|
||||||
|
- Prevent <![CDATA[<body></body>]]> from triggering %Core.ConvertDocumentToFragment
|
||||||
|
- Fix bug with inline elements in blockquotes conflicting with strict doctype
|
||||||
|
- Detect if HTML support is disabled for DOM by checking for loadHTML() method.
|
||||||
|
- Fix bug where dots and double-dots in absolute URLs without hostname were
|
||||||
|
not collapsed by URIFilter_MakeAbsolute.
|
||||||
|
- Fix bug with anonymous modules operating on SafeEmbed or SafeObject elements
|
||||||
|
by reordering their addition.
|
||||||
|
- Will now throw exception on many error conditions during lexer creation; also
|
||||||
|
throw an exception when MaintainLineNumbers is true, but a non-tracksLineNumbers
|
||||||
|
is being used.
|
||||||
|
- Detect if domxml extension is loaded, and use DirectLEx accordingly.
|
||||||
|
- Improve handling of big numbers with floating point arithmetic in UnitConverter.
|
||||||
|
Reported by David Morton.
|
||||||
|
. Strategy_MakeWellFormed now operates in-place, saving memory and allowing
|
||||||
|
for more interesting filter-backtracking
|
||||||
|
. New HTMLPurifier_Injector->rewind() functionality, allows injectors to rewind
|
||||||
|
index to reprocess tokens.
|
||||||
|
. StringHashParser now allows for multiline sections with "empty" content;
|
||||||
|
previously the section would remain undefined.
|
||||||
|
. Added --quick option to multitest.php, which tests only the most recent
|
||||||
|
release for each series.
|
||||||
|
. Added --distro option to multitest.php, which accepts either 'normal' or
|
||||||
|
'standalone'. This supercedes --exclude-normal and --exclude-standalone
|
||||||
|
|
||||||
|
3.1.1, released 2008-06-19
|
||||||
|
# %URI.Munge now, by default, does not munge resources (for example, <img src="">)
|
||||||
|
In order to enable this again, please set %URI.MungeResources to true.
|
||||||
|
! More robust imagecrash protection with height/width CSS with %CSS.MaxImgLength,
|
||||||
|
and height/width HTML with %HTML.MaxImgLength.
|
||||||
|
! %URI.MungeSecretKey for secure URI munging. Thanks Chris
|
||||||
|
for sponsoring this feature. Check out the corresponding documentation
|
||||||
|
for details. (Att Nightly testers: The API for this feature changed before
|
||||||
|
the general release. Namely, rename your directives %URI.SecureMungeSecretKey =>
|
||||||
|
%URI.MungeSecretKey and and %URI.SecureMunge => %URI.Munge)
|
||||||
|
! Implemented post URI filtering. Set member variable $post to true to set
|
||||||
|
a URIFilter as such.
|
||||||
|
! Allow modules to define injectors via $info_injector. Injectors are
|
||||||
|
automatically disabled if injector's needed elements are not found.
|
||||||
|
! Support for "safe" objects added, use %HTML.SafeObject and %HTML.SafeEmbed.
|
||||||
|
Thanks Chris for sponsoring. If you've been using ad hoc code from the
|
||||||
|
forums, PLEASE use this instead.
|
||||||
|
! Added substitutions for %e, %n, %a and %p in %URI.Munge (in order,
|
||||||
|
embedded, tag name, attribute name, CSS property name). See %URI.Munge
|
||||||
|
for more details. Requested by Jochem Blok.
|
||||||
|
- Disable percent height/width attributes for img.
|
||||||
|
- AttrValidator operations are now atomic; updates to attributes are not
|
||||||
|
manifest in token until end of operations. This prevents naughty internal
|
||||||
|
code from directly modifying CurrentToken when they're not supposed to.
|
||||||
|
This semantics change was requested by frank farmer.
|
||||||
|
- Percent encoding checks enabled for URI query and fragment
|
||||||
|
- Fix stray backslashes in font-family; CSS Unicode character escapes are
|
||||||
|
now properly resolved (although *only* in font-family). Thanks Takeshi Terada
|
||||||
|
for reporting.
|
||||||
|
- Improve parseCDATA algorithm to take into account newline normalization
|
||||||
|
- Account for browser confusion between Yen character and backslash in
|
||||||
|
Shift_JIS encoding. This fix generalizes to any other encoding which is not
|
||||||
|
a strict superset of printable ASCII. Thanks Takeshi Terada for reporting.
|
||||||
|
- Fix missing configuration parameter in Generator calls. Thanks vs for the
|
||||||
|
partial patch.
|
||||||
|
- Improved adherence to Unicode by checking for non-character codepoints.
|
||||||
|
Thanks Geoffrey Sneddon for reporting. This may result in degraded
|
||||||
|
performance for extremely large inputs.
|
||||||
|
- Allow CSS property-value pair ''text-decoration: none''. Thanks Jochem Blok
|
||||||
|
for reporting.
|
||||||
|
. Added HTMLPurifier_UnitConverter and HTMLPurifier_Length for convenient
|
||||||
|
handling of CSS-style lengths. HTMLPurifier_AttrDef_CSS_Length now uses
|
||||||
|
this class.
|
||||||
|
. API of HTMLPurifier_AttrDef_CSS_Length changed from __construct($disable_negative)
|
||||||
|
to __construct($min, $max). __construct(true) is equivalent to
|
||||||
|
__construct('0').
|
||||||
|
. Added HTMLPurifier_AttrDef_Switch class
|
||||||
|
. Rename HTMLPurifier_HTMLModule_Tidy->construct() to setup() and bubble method
|
||||||
|
up inheritance hierarchy to HTMLPurifier_HTMLModule. All HTMLModules
|
||||||
|
get this called with the configuration object. All modules now
|
||||||
|
use this rather than __construct(), although legacy code using constructors
|
||||||
|
will still work--the new format, however, lets modules access the
|
||||||
|
configuration object for HTML namespace dependant tweaks.
|
||||||
|
. AttrDef_HTML_Pixels now takes a single construction parameter, pixels.
|
||||||
|
. ConfigSchema data-structure heavily optimized; on average it uses a third
|
||||||
|
the memory it did previously. The interface has changed accordingly,
|
||||||
|
consult changes to HTMLPurifier_Config for details.
|
||||||
|
. Variable parsing types now are magic integers instead of strings
|
||||||
|
. Added benchmark for ConfigSchema
|
||||||
|
. HTMLPurifier_Generator requires $config and $context parameters. If you
|
||||||
|
don't know what they should be, use HTMLPurifier_Config::createDefault()
|
||||||
|
and new HTMLPurifier_Context().
|
||||||
|
. Printers now properly distinguish between output configuration, and
|
||||||
|
target configuration. This is not applicable to scripts using
|
||||||
|
the Printers for HTML Purifier related tasks.
|
||||||
|
. HTML/CSS Printers must be primed with prepareGenerator($gen_config), otherwise
|
||||||
|
fatal errors will ensue.
|
||||||
|
. URIFilter->prepare can return false in order to abort loading of the filter
|
||||||
|
. Factory for AttrDef_URI implemented, URI#embedded to indicate URI that embeds
|
||||||
|
an external resource.
|
||||||
|
. %URI.Munge functionality factored out into a post-filter class.
|
||||||
|
. Added CurrentCSSProperty context variable during CSS validation
|
||||||
|
|
||||||
3.1.0, released 2008-05-18
|
3.1.0, released 2008-05-18
|
||||||
# Unnecessary references to objects (vestiges of PHP4) removed from method
|
# Unnecessary references to objects (vestiges of PHP4) removed from method
|
||||||
signatures. The following methods do not need references when assigning from
|
signatures. The following methods do not need references when assigning from
|
||||||
@@ -33,7 +177,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
and allows for version numbers like "3.1.0-dev".
|
and allows for version numbers like "3.1.0-dev".
|
||||||
! %HTML.Allowed deals gracefully with whitespace anywhere, anytime!
|
! %HTML.Allowed deals gracefully with whitespace anywhere, anytime!
|
||||||
! HTML Purifier's URI handling is a lot more robust, with much stricter
|
! HTML Purifier's URI handling is a lot more robust, with much stricter
|
||||||
validation checks and better percent encoding handling.
|
validation checks and better percent encoding handling. Thanks Gareth Heyes
|
||||||
|
for indicating security vulnerabilities from lax percent encoding.
|
||||||
! Bootstrap autoloader deals more robustly with classes that don't exist,
|
! Bootstrap autoloader deals more robustly with classes that don't exist,
|
||||||
preventing class_exists($class, true) from barfing.
|
preventing class_exists($class, true) from barfing.
|
||||||
- InterchangeBuilder now alphabetizes its lists
|
- InterchangeBuilder now alphabetizes its lists
|
||||||
|
22
TODO
22
TODO
@@ -11,24 +11,28 @@ 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
|
amount of effort to implement, it may get endlessly delayed. Do not be
|
||||||
afraid to cast your vote for the next feature to be implemented!
|
afraid to cast your vote for the next feature to be implemented!
|
||||||
|
|
||||||
- Implement validation for query and for fragment
|
- Investigate how early internal structures can be accessed; this would
|
||||||
|
prevent structures from being parsed and serialized multiple times.
|
||||||
|
- Built-in support for target="_blank" on all external links
|
||||||
|
- Allow <a id="asdf" name="asdf">
|
||||||
|
- Implement overflow CSS property (as per jlp09550)
|
||||||
|
|
||||||
FUTURE VERSIONS
|
FUTURE VERSIONS
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
3.2 release [It's All About Trust] (floating)
|
3.3 release [It's All About Trust] (floating)
|
||||||
# Implement untrusted, dangerous elements/attributes
|
# Implement untrusted, dangerous elements/attributes
|
||||||
- Objects and Forms are especially wanted
|
|
||||||
# Implement IDREF support (harder than it seems, since you cannot have
|
# Implement IDREF support (harder than it seems, since you cannot have
|
||||||
IDREFs to non-existent IDs)
|
IDREFs to non-existent IDs)
|
||||||
# Frameset XHTML 1.0 and HTML 4.01 doctypes
|
# Frameset XHTML 1.0 and HTML 4.01 doctypes
|
||||||
- Research and implement a "safe" version of the Object module
|
- Implement <area>
|
||||||
|
- Figure out how to simultaneously set %CSS.Trusted and %HTML.Trusted (?)
|
||||||
|
|
||||||
3.3 release [Error'ed]
|
3.4 release [Error'ed]
|
||||||
# Error logging for filtering/cleanup procedures
|
# Error logging for filtering/cleanup procedures
|
||||||
- XSS-attempt detection--certain errors are flagged XSS-like
|
- XSS-attempt detection--certain errors are flagged XSS-like
|
||||||
|
|
||||||
3.4 release [Do What I Mean, Not What I Say]
|
3.5 release [Do What I Mean, Not What I Say]
|
||||||
# Additional support for poorly written HTML
|
# Additional support for poorly written HTML
|
||||||
- Microsoft Word HTML cleaning (i.e. MsoNormal, but research essential!)
|
- Microsoft Word HTML cleaning (i.e. MsoNormal, but research essential!)
|
||||||
- Friendly strict handling of <address> (block -> <br>)
|
- Friendly strict handling of <address> (block -> <br>)
|
||||||
@@ -39,7 +43,6 @@ FUTURE VERSIONS
|
|||||||
contents should be dropped or not (currently, there's code that could do
|
contents should be dropped or not (currently, there's code that could do
|
||||||
something like this if it didn't drop the inner text too.)
|
something like this if it didn't drop the inner text too.)
|
||||||
- Remove <span> tags that don't do anything (no attributes)
|
- Remove <span> tags that don't do anything (no attributes)
|
||||||
- Remove empty inline tags<i></i>
|
|
||||||
- Append something to duplicate IDs so they're still usable (impl. note: the
|
- Append something to duplicate IDs so they're still usable (impl. note: the
|
||||||
dupe detector would also need to detect the suffix as well)
|
dupe detector would also need to detect the suffix as well)
|
||||||
- Externalize inline CSS to promote clean HTML, proposed by Sander Tekelenburg
|
- Externalize inline CSS to promote clean HTML, proposed by Sander Tekelenburg
|
||||||
@@ -49,14 +52,12 @@ FUTURE VERSIONS
|
|||||||
AttrDef class). Probably will use CSSTidy class?
|
AttrDef class). Probably will use CSSTidy class?
|
||||||
# More control over allowed CSS properties using a modularization
|
# More control over allowed CSS properties using a modularization
|
||||||
# HTML 5 support
|
# HTML 5 support
|
||||||
# IRI support
|
# IRI support (this includes IDN)
|
||||||
- Standardize token armor for all areas of processing
|
- Standardize token armor for all areas of processing
|
||||||
- Convert RTL/LTR override characters to <bdo> tags, or vice versa on demand.
|
- Convert RTL/LTR override characters to <bdo> tags, or vice versa on demand.
|
||||||
Also, enable disabling of directionality
|
Also, enable disabling of directionality
|
||||||
|
|
||||||
5.0 release [To XML and Beyond]
|
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)
|
- Extended HTML capabilities based on namespacing and tag transforms (COMPLEX)
|
||||||
- Hooks for adding custom processors to custom namespaced tags and
|
- Hooks for adding custom processors to custom namespaced tags and
|
||||||
attributes, offer default implementation
|
attributes, offer default implementation
|
||||||
@@ -104,6 +105,7 @@ Neat feature related
|
|||||||
- Full set of color keywords. Also, a way to add onto them without
|
- Full set of color keywords. Also, a way to add onto them without
|
||||||
finalizing the configuration object.
|
finalizing the configuration object.
|
||||||
- Write a var_export and memcached DefinitionCache - Denis
|
- Write a var_export and memcached DefinitionCache - Denis
|
||||||
|
- Allow restriction of allowed class values
|
||||||
|
|
||||||
Maintenance related (slightly boring)
|
Maintenance related (slightly boring)
|
||||||
# CHMOD install script for PEAR installs
|
# CHMOD install script for PEAR installs
|
||||||
|
16
WHATSNEW
16
WHATSNEW
@@ -1,10 +1,6 @@
|
|||||||
HTML Purifier 3.1.0 is the second release series for HTML Purifier on PHP 5
|
HTML Purifier 3.2.0 is an amalgamation of new features and fixes that
|
||||||
as well as a security update related to URIs. It shifts over to using
|
have accumulated over a four month period. Some notable features
|
||||||
autoload, and also includes support for the !important CSS modifier,
|
include %AutoFormat.RemoveEmpty, column tracking for tokens,
|
||||||
display and visibility CSS properties with %CSS.AllowTricky, marquee with
|
%AutoFormat.DisplayLinkURI and %Attr.DefaultImageAlt. There were also
|
||||||
%HTML.Proprietary (had you scared for a moment, hmm?), a kses() wrapper,
|
major improvements to the test suite interface, error collection output
|
||||||
%CSS.AllowedProperties, %HTML.ForbiddenAttributes and
|
and the auto-formatter framework.
|
||||||
%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.
|
|
||||||
|
14
benchmarks/ConfigSchema.php
Normal file
14
benchmarks/ConfigSchema.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
chdir(dirname(__FILE__));
|
||||||
|
|
||||||
|
//require_once '../library/HTMLPurifier.path.php';
|
||||||
|
shell_exec('php ../maintenance/generate-schema-cache.php');
|
||||||
|
require_once '../library/HTMLPurifier.path.php';
|
||||||
|
require_once 'HTMLPurifier.includes.php';
|
||||||
|
|
||||||
|
$begin = xdebug_memory_usage();
|
||||||
|
|
||||||
|
$schema = HTMLPurifier_ConfigSchema::makeFromSerial();
|
||||||
|
|
||||||
|
echo xdebug_memory_usage() - $begin;
|
@@ -19,7 +19,7 @@
|
|||||||
<xsl:variable name="usageLookup" select="document('../usage.xml')/usage" />
|
<xsl:variable name="usageLookup" select="document('../usage.xml')/usage" />
|
||||||
|
|
||||||
<!-- Twiddle this variable to get the columns as even as possible -->
|
<!-- Twiddle this variable to get the columns as even as possible -->
|
||||||
<xsl:variable name="maxNumberAdjust" select="1" />
|
<xsl:variable name="maxNumberAdjust" select="2" />
|
||||||
|
|
||||||
<xsl:template match="/">
|
<xsl:template match="/">
|
||||||
<html lang="en" xml:lang="en">
|
<html lang="en" xml:lang="en">
|
||||||
|
@@ -5,35 +5,40 @@
|
|||||||
<line>131</line>
|
<line>131</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
<file name="HTMLPurifier/Lexer.php">
|
||||||
<line>85</line>
|
<line>81</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||||
<line>50</line>
|
<line>53</line>
|
||||||
<line>62</line>
|
<line>73</line>
|
||||||
<line>327</line>
|
<line>348</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<line>44</line>
|
<line>47</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
|
<directive id="CSS.MaxImgLength">
|
||||||
|
<file name="HTMLPurifier/CSSDefinition.php">
|
||||||
|
<line>157</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="CSS.Proprietary">
|
<directive id="CSS.Proprietary">
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
<file name="HTMLPurifier/CSSDefinition.php">
|
||||||
<line>202</line>
|
<line>214</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="CSS.AllowTricky">
|
<directive id="CSS.AllowTricky">
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
<file name="HTMLPurifier/CSSDefinition.php">
|
||||||
<line>206</line>
|
<line>218</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="CSS.AllowImportant">
|
<directive id="CSS.AllowImportant">
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
<file name="HTMLPurifier/CSSDefinition.php">
|
||||||
<line>210</line>
|
<line>222</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="CSS.AllowedProperties">
|
<directive id="CSS.AllowedProperties">
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
<file name="HTMLPurifier/CSSDefinition.php">
|
||||||
<line>262</line>
|
<line>274</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Cache.DefinitionImpl">
|
<directive id="Cache.DefinitionImpl">
|
||||||
@@ -63,106 +68,116 @@
|
|||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.Encoding">
|
<directive id="Core.Encoding">
|
||||||
<file name="HTMLPurifier/Encoder.php">
|
<file name="HTMLPurifier/Encoder.php">
|
||||||
<line>281</line>
|
<line>267</line>
|
||||||
<line>305</line>
|
<line>300</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Test.ForceNoIconv">
|
<directive id="Test.ForceNoIconv">
|
||||||
<file name="HTMLPurifier/Encoder.php">
|
<file name="HTMLPurifier/Encoder.php">
|
||||||
<line>283</line>
|
<line>272</line>
|
||||||
<line>310</line>
|
<line>308</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.EscapeNonASCIICharacters">
|
<directive id="Core.EscapeNonASCIICharacters">
|
||||||
<file name="HTMLPurifier/Encoder.php">
|
<file name="HTMLPurifier/Encoder.php">
|
||||||
<line>307</line>
|
<line>304</line>
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.MaintainLineNumbers">
|
|
||||||
<file name="HTMLPurifier/ErrorCollector.php">
|
|
||||||
<line>81</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
|
||||||
<line>82</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
|
||||||
<line>45</line>
|
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Output.CommentScriptContents">
|
<directive id="Output.CommentScriptContents">
|
||||||
<file name="HTMLPurifier/Generator.php">
|
<file name="HTMLPurifier/Generator.php">
|
||||||
<line>41</line>
|
<line>45</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
|
<directive id="Output.SortAttr">
|
||||||
|
<file name="HTMLPurifier/Generator.php">
|
||||||
|
<line>46</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Output.TidyFormat">
|
<directive id="Output.TidyFormat">
|
||||||
<file name="HTMLPurifier/Generator.php">
|
<file name="HTMLPurifier/Generator.php">
|
||||||
<line>70</line>
|
<line>75</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Output.Newline">
|
<directive id="Output.Newline">
|
||||||
<file name="HTMLPurifier/Generator.php">
|
<file name="HTMLPurifier/Generator.php">
|
||||||
<line>84</line>
|
<line>89</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.BlockWrapper">
|
<directive id="HTML.BlockWrapper">
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||||
<line>213</line>
|
<line>222</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.Parent">
|
<directive id="HTML.Parent">
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||||
<line>221</line>
|
<line>230</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.AllowedElements">
|
<directive id="HTML.AllowedElements">
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||||
<line>238</line>
|
<line>247</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.AllowedAttributes">
|
<directive id="HTML.AllowedAttributes">
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||||
<line>239</line>
|
<line>248</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.Allowed">
|
<directive id="HTML.Allowed">
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||||
<line>242</line>
|
<line>251</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.ForbiddenElements">
|
<directive id="HTML.ForbiddenElements">
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||||
<line>328</line>
|
<line>337</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.ForbiddenAttributes">
|
<directive id="HTML.ForbiddenAttributes">
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||||
<line>329</line>
|
<line>338</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.Trusted">
|
<directive id="HTML.Trusted">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>198</line>
|
<line>202</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
<file name="HTMLPurifier/Lexer.php">
|
||||||
<line>238</line>
|
<line>258</line>
|
||||||
|
</file>
|
||||||
|
<file name="HTMLPurifier/HTMLModule/Image.php">
|
||||||
|
<line>27</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||||
<line>34</line>
|
<line>36</line>
|
||||||
|
</file>
|
||||||
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
|
<line>23</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.AllowedModules">
|
<directive id="HTML.AllowedModules">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>205</line>
|
<line>209</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.CoreModules">
|
<directive id="HTML.CoreModules">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>206</line>
|
<line>210</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="HTML.Proprietary">
|
<directive id="HTML.Proprietary">
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
<line>220</line>
|
<line>221</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
|
<directive id="HTML.SafeObject">
|
||||||
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
|
<line>226</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
|
<directive id="HTML.SafeEmbed">
|
||||||
|
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||||
|
<line>229</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Attr.IDBlacklist">
|
<directive id="Attr.IDBlacklist">
|
||||||
@@ -177,30 +192,35 @@
|
|||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.LexerImpl">
|
<directive id="Core.LexerImpl">
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
<file name="HTMLPurifier/Lexer.php">
|
||||||
<line>70</line>
|
<line>76</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
|
<directive id="Core.MaintainLineNumbers">
|
||||||
|
<file name="HTMLPurifier/Lexer.php">
|
||||||
|
<line>80</line>
|
||||||
|
</file>
|
||||||
|
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||||
|
<line>48</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.ConvertDocumentToFragment">
|
<directive id="Core.ConvertDocumentToFragment">
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
<file name="HTMLPurifier/Lexer.php">
|
||||||
<line>230</line>
|
<line>267</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.Host">
|
<directive id="URI.Host">
|
||||||
<file name="HTMLPurifier/URIDefinition.php">
|
<file name="HTMLPurifier/URIDefinition.php">
|
||||||
<line>57</line>
|
<line>64</line>
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/URIFilter/DisableExternal.php">
|
|
||||||
<line>8</line>
|
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.Base">
|
<directive id="URI.Base">
|
||||||
<file name="HTMLPurifier/URIDefinition.php">
|
<file name="HTMLPurifier/URIDefinition.php">
|
||||||
<line>58</line>
|
<line>65</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.DefaultScheme">
|
<directive id="URI.DefaultScheme">
|
||||||
<file name="HTMLPurifier/URIDefinition.php">
|
<file name="HTMLPurifier/URIDefinition.php">
|
||||||
<line>65</line>
|
<line>72</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.AllowedSchemes">
|
<directive id="URI.AllowedSchemes">
|
||||||
@@ -215,12 +235,7 @@
|
|||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.Disable">
|
<directive id="URI.Disable">
|
||||||
<file name="HTMLPurifier/AttrDef/URI.php">
|
<file name="HTMLPurifier/AttrDef/URI.php">
|
||||||
<line>23</line>
|
<line>28</line>
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.Munge">
|
|
||||||
<file name="HTMLPurifier/AttrDef/URI.php">
|
|
||||||
<line>68</line>
|
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.ColorKeywords">
|
<directive id="Core.ColorKeywords">
|
||||||
@@ -275,9 +290,14 @@
|
|||||||
<line>19</line>
|
<line>19</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
|
<directive id="Attr.DefaultImageAlt">
|
||||||
|
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
||||||
|
<line>25</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
<directive id="Attr.DefaultInvalidImageAlt">
|
<directive id="Attr.DefaultInvalidImageAlt">
|
||||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
||||||
<line>27</line>
|
<line>32</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.EscapeInvalidChildren">
|
<directive id="Core.EscapeInvalidChildren">
|
||||||
@@ -305,6 +325,17 @@
|
|||||||
<line>123</line>
|
<line>123</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
|
<directive id="HTML.MaxImgLength">
|
||||||
|
<file name="HTMLPurifier/HTMLModule/Image.php">
|
||||||
|
<line>14</line>
|
||||||
|
</file>
|
||||||
|
<file name="HTMLPurifier/HTMLModule/SafeEmbed.php">
|
||||||
|
<line>13</line>
|
||||||
|
</file>
|
||||||
|
<file name="HTMLPurifier/HTMLModule/SafeObject.php">
|
||||||
|
<line>19</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
<directive id="HTML.TidyLevel">
|
<directive id="HTML.TidyLevel">
|
||||||
<file name="HTMLPurifier/HTMLModule/Tidy.php">
|
<file name="HTMLPurifier/HTMLModule/Tidy.php">
|
||||||
<line>45</line>
|
<line>45</line>
|
||||||
@@ -332,12 +363,12 @@
|
|||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.DirectLexLineNumberSyncInterval">
|
<directive id="Core.DirectLexLineNumberSyncInterval">
|
||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||||
<line>59</line>
|
<line>70</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.EscapeInvalidTags">
|
<directive id="Core.EscapeInvalidTags">
|
||||||
<file name="HTMLPurifier/Strategy/MakeWellFormed.php">
|
<file name="HTMLPurifier/Strategy/MakeWellFormed.php">
|
||||||
<line>22</line>
|
<line>45</line>
|
||||||
</file>
|
</file>
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<line>19</line>
|
<line>19</line>
|
||||||
@@ -345,12 +376,12 @@
|
|||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.RemoveScriptContents">
|
<directive id="Core.RemoveScriptContents">
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<line>22</line>
|
<line>25</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="Core.HiddenElements">
|
<directive id="Core.HiddenElements">
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||||
<line>23</line>
|
<line>26</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.HostBlacklist">
|
<directive id="URI.HostBlacklist">
|
||||||
@@ -358,4 +389,14 @@
|
|||||||
<line>8</line>
|
<line>8</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
|
<directive id="URI.MungeResources">
|
||||||
|
<file name="HTMLPurifier/URIFilter/Munge.php">
|
||||||
|
<line>14</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
|
<directive id="URI.MungeSecretKey">
|
||||||
|
<file name="HTMLPurifier/URIFilter/Munge.php">
|
||||||
|
<line>15</line>
|
||||||
|
</file>
|
||||||
|
</directive>
|
||||||
</usage>
|
</usage>
|
||||||
|
@@ -213,6 +213,4 @@ the usual things required are:</p>
|
|||||||
|
|
||||||
<p>See <code>HTMLPurifier/HTMLModule.php</code> for details.</p>
|
<p>See <code>HTMLPurifier/HTMLModule.php</code> for details.</p>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -239,15 +239,15 @@ Test.Example</pre>
|
|||||||
object; users have a little bit of leeway when setting configuration
|
object; users have a little bit of leeway when setting configuration
|
||||||
values (for example, a lookup value can be specified as a list;
|
values (for example, a lookup value can be specified as a list;
|
||||||
HTML Purifier will flip it as necessary.) These types are defined
|
HTML Purifier will flip it as necessary.) These types are defined
|
||||||
in <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/VarParser.php">
|
in <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/VarParser.php">
|
||||||
library/HTMLPurifier/VarParser.php</a>.
|
library/HTMLPurifier/VarParser.php</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
For more information on what values are allowed, and how they are parsed,
|
For more information on what values are allowed, and how they are parsed,
|
||||||
consult <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
consult <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
||||||
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php</a>, as well
|
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php</a>, as well
|
||||||
as <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ConfigSchema/Interchange/Directive.php">
|
as <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/Interchange/Directive.php">
|
||||||
library/HTMLPurifier/ConfigSchema/Interchange/Directive.php</a> for
|
library/HTMLPurifier/ConfigSchema/Interchange/Directive.php</a> for
|
||||||
the semantics of the parsed values.
|
the semantics of the parsed values.
|
||||||
</p>
|
</p>
|
||||||
@@ -272,7 +272,7 @@ Test.Example</pre>
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
All directive files go through a rigorous validation process
|
All directive files go through a rigorous validation process
|
||||||
through <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ConfigSchema/">
|
through <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/Validator.php">
|
||||||
library/HTMLPurifier/ConfigSchema/Validator.php</a>, as well
|
library/HTMLPurifier/ConfigSchema/Validator.php</a>, as well
|
||||||
as some basic checks during building. While
|
as some basic checks during building. While
|
||||||
listing every error out here is out-of-scope for this document, we
|
listing every error out here is out-of-scope for this document, we
|
||||||
@@ -339,7 +339,7 @@ Test.Example</pre>
|
|||||||
The most difficult part is translating the Interchange member variable (valueAliases)
|
The most difficult part is translating the Interchange member variable (valueAliases)
|
||||||
into a directive file key (VALUE-ALIASES), but there's a one-to-one
|
into a directive file key (VALUE-ALIASES), but there's a one-to-one
|
||||||
correspondence currently. If the two formats diverge, any discrepancies
|
correspondence currently. If the two formats diverge, any discrepancies
|
||||||
will be described in <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
will be described in <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
||||||
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php</a>.
|
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -370,7 +370,5 @@ Test.Example</pre>
|
|||||||
data. There is also an XML serializer, which is used to build documentation.
|
data. There is also an XML serializer, which is used to build documentation.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -62,6 +62,4 @@
|
|||||||
do.
|
do.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -77,6 +77,4 @@ help you find the correct functionality more quickly. Here they are:</p>
|
|||||||
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -27,6 +27,4 @@ that itch, put it here!</p>
|
|||||||
<li>Parallelize strategies</li>
|
<li>Parallelize strategies</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -303,6 +303,4 @@ Mozilla on inside and needs -moz-outline, no IE support.</td></tr>
|
|||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -213,7 +213,7 @@ $def = $config->getHTMLDefinition(true);</pre>
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
<strong>$config->set('Core', 'DefinitionCache', null); // remove this later!</strong>
|
<strong>$config->set('Cache', 'DefinitionImpl', null); // remove this later!</strong>
|
||||||
$def = $config->getHTMLDefinition(true);</pre>
|
$def = $config->getHTMLDefinition(true);</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -269,7 +269,7 @@ $def = $config->getHTMLDefinition(true);</pre>
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
$config->set('Cache', 'DefinitionImpl', null); // remove this later!
|
||||||
$def = $config->getHTMLDefinition(true);
|
$def = $config->getHTMLDefinition(true);
|
||||||
<strong>$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');</strong></pre>
|
<strong>$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');</strong></pre>
|
||||||
|
|
||||||
@@ -372,10 +372,10 @@ $def = $config->getHTMLDefinition(true);
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
For a complete list, consult
|
For a complete list, consult
|
||||||
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/AttrTypes.php"><code>library/HTMLPurifier/AttrTypes.php</code></a>;
|
<a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/AttrTypes.php"><code>library/HTMLPurifier/AttrTypes.php</code></a>;
|
||||||
more information on attributes that accept parameters can be found on their
|
more information on attributes that accept parameters can be found on their
|
||||||
respective includes in
|
respective includes in
|
||||||
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/AttrDef/"><code>library/HTMLPurifier/AttrDef</code></a>.
|
<a href="http://repo.or.cz/w/htmlpurifier.git?a=tree;hb=HEAD;f=library/HTMLPurifier/AttrDef"><code>library/HTMLPurifier/AttrDef</code></a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -387,7 +387,7 @@ $def = $config->getHTMLDefinition(true);
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
$config->set('Cache', 'DefinitionImpl', null); // remove this later!
|
||||||
$def = $config->getHTMLDefinition(true);
|
$def = $config->getHTMLDefinition(true);
|
||||||
<strong>$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
<strong>$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||||
array('_blank','_self','_target','_top')
|
array('_blank','_self','_target','_top')
|
||||||
@@ -734,7 +734,7 @@ $def = $config->getHTMLDefinition(true);
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
$config->set('Cache', 'DefinitionImpl', null); // remove this later!
|
||||||
$def = $config->getHTMLDefinition(true);
|
$def = $config->getHTMLDefinition(true);
|
||||||
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||||
array('_blank','_self','_target','_top')
|
array('_blank','_self','_target','_top')
|
||||||
@@ -764,7 +764,7 @@ $form->excludes = array('form' => true);</strong></pre>
|
|||||||
<p>
|
<p>
|
||||||
And that's all there is to it! Implementing the rest of the form
|
And that's all there is to it! Implementing the rest of the form
|
||||||
module is left as an exercise to the user; to see more examples
|
module is left as an exercise to the user; to see more examples
|
||||||
check the <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/HTMLModule/"><code>library/HTMLPurifier/HTMLModule/</code></a> directory
|
check the <a href="http://repo.or.cz/w/htmlpurifier.git?a=tree;hb=HEAD;f=library/HTMLPurifier/HTMLModule"><code>library/HTMLPurifier/HTMLModule/</code></a> directory
|
||||||
in your local HTML Purifier installation.
|
in your local HTML Purifier installation.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -789,10 +789,8 @@ $form->excludes = array('form' => true);</strong></pre>
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/HTMLModule.php"><code>library/HTMLPurifier/HTMLModule.php</code></a></li>
|
<li><a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/HTMLModule.php"><code>library/HTMLPurifier/HTMLModule.php</code></a></li>
|
||||||
<li><a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ElementDef.php"><code>library/HTMLPurifier/ElementDef.php</code></a></li>
|
<li><a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ElementDef.php"><code>library/HTMLPurifier/ElementDef.php</code></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div id="version">$Id: enduser-tidy.html 1158 2007-06-18 19:26:29Z Edward $</div>
|
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -141,7 +141,5 @@ anchors is beyond me.</p>
|
|||||||
|
|
||||||
<p>Don't come crying to me when your page mysteriously stops validating, though.</p>
|
<p>Don't come crying to me when your page mysteriously stops validating, though.</p>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -225,6 +225,4 @@ and if that still doesn't satisfy your appetite, do some fine-tuning.
|
|||||||
Other than that, don't worry about it: this all works silently and
|
Other than that, don't worry about it: this all works silently and
|
||||||
effectively in the background.</p>
|
effectively in the background.</p>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -130,30 +130,26 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Let's suppose I wanted to write a filter that de-internationalized domain
|
Let's suppose I wanted to write a filter that converted links with a
|
||||||
names by converting them to <a href="http://en.wikipedia.org/wiki/Punycode">Punycode</a>.
|
custom <code>image</code> scheme to its corresponding real path on
|
||||||
Assuming that <code>punycode_encode($input)</code> converts <code>$input</code> to
|
our website:
|
||||||
Punycode and returns <code>false</code> on failure:
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>class HTMLPurifier_URIFilter_ConvertIDNToPunycode extends HTMLPurifier_URIFilter
|
<pre>class HTMLPurifier_URIFilter_TransformImageScheme extends HTMLPurifier_URIFilter
|
||||||
{
|
{
|
||||||
public $name = 'ConvertIDNToPunycode';
|
public $name = 'TransformImageScheme';
|
||||||
public function filter(&$uri, $config, $context) {
|
public function filter(&$uri, $config, $context) {
|
||||||
if (is_null($uri->host)) return true;
|
if ($uri->scheme !== 'image') return true;
|
||||||
if ($uri->host == utf8_decode($uri->host)) {
|
$img_name = $uri->path;
|
||||||
// is ASCII, abort
|
// Overwrite the previous URI object
|
||||||
return true;
|
$uri = new HTMLPurifier_URI('http', null, null, null, '/img/' . $img_name . '.png', null, null);
|
||||||
}
|
|
||||||
$host = punycode_encode($uri->host);
|
|
||||||
if ($host === false) return false;
|
|
||||||
$uri->host = $host;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}</pre>
|
}</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Notice I did not <code>return $uri;</code>.
|
Notice I did not <code>return $uri;</code>. This filter would turn
|
||||||
|
<code>image:Foo</code> into <code>/img/Foo.png</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Activating your filter</h2>
|
<h2>Activating your filter</h2>
|
||||||
@@ -186,16 +182,33 @@ $uri->registerFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>())
|
|||||||
is set to true.
|
is set to true.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h2>Post-filter</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Remember our TransformImageScheme filter? That filter acted before we had
|
||||||
|
performed scheme validation; otherwise, the URI would have been filtered
|
||||||
|
out when it was discovered that there was no image scheme. Well, a post-filter
|
||||||
|
is run after scheme specific validation, so it's ideal for bulk
|
||||||
|
post-processing of URIs, including munging. To specify a URI as a post-filter,
|
||||||
|
set the <code>$post</code> member variable to TRUE.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>class HTMLPurifier_URIFilter_MyPostFilter extends HTMLPurifier_URIFilter
|
||||||
|
{
|
||||||
|
public $name = 'MyPostFilter';
|
||||||
|
public $post = true;
|
||||||
|
// ... extra code here
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
<h2>Examples</h2>
|
<h2>Examples</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Check the
|
Check the
|
||||||
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/URIFilter/">URIFilter</a>
|
<a href="http://repo.or.cz/w/htmlpurifier.git?a=tree;hb=HEAD;f=library/HTMLPurifier/URIFilter">URIFilter</a>
|
||||||
directory for more implementation examples, and see <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/docs/proposal-new-directives.txt">the
|
directory for more implementation examples, and see <a href="proposal-new-directives.txt">the
|
||||||
new directives proposal document</a> for ideas on what could be implemented
|
new directives proposal document</a> for ideas on what could be implemented
|
||||||
as a filter.
|
as a filter.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -118,9 +118,8 @@ there are now many character encodings floating around.</p>
|
|||||||
see a page on the web, chances are it's encoded in one
|
see a page on the web, chances are it's encoded in one
|
||||||
of these encodings.</li>
|
of these encodings.</li>
|
||||||
<li><strong>Unicode-based encodings</strong> implement the
|
<li><strong>Unicode-based encodings</strong> implement the
|
||||||
Unicode standard and include UTF-8, UCS-2 and UTF-16.
|
Unicode standard and include UTF-8, UTF-16 and UTF-32/UCS-4.
|
||||||
They go beyond 8-bits (the first two are variable length,
|
They go beyond 8-bits and support almost
|
||||||
while the second one uses 16-bits), and support almost
|
|
||||||
every language in the world. UTF-8 is gaining traction
|
every language in the world. UTF-8 is gaining traction
|
||||||
as the dominant international encoding of the web.</li>
|
as the dominant international encoding of the web.</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -590,8 +589,10 @@ looks something like: <code>%C3%86</code>. There is no official way of
|
|||||||
determining the character encoding of such a request, since the percent
|
determining the character encoding of such a request, since the percent
|
||||||
encoding operates on a byte level, so it is usually assumed that it
|
encoding operates on a byte level, so it is usually assumed that it
|
||||||
is the same as the encoding the page containing the form was submitted
|
is the same as the encoding the page containing the form was submitted
|
||||||
in. You'll run into very few problems if you only use characters in
|
in. (<a href="http://tools.ietf.org/html/rfc3986#section-2.5">RFC 3986</a>
|
||||||
the character encoding you chose.</p>
|
recommends that textual identifiers be translated to UTF-8; however, browser
|
||||||
|
compliance is spotty.) You'll run into very few problems
|
||||||
|
if you only use characters in the character encoding you chose.</p>
|
||||||
|
|
||||||
<p>However, once you start adding characters outside of your encoding
|
<p>However, once you start adding characters outside of your encoding
|
||||||
(and this is a lot more common than you may think: take curly
|
(and this is a lot more common than you may think: take curly
|
||||||
|
@@ -70,7 +70,7 @@ into your documents. YouTube's code goes like this:</p>
|
|||||||
class="embed-youtube">AyPzM5WK8ys</span></code> your
|
class="embed-youtube">AyPzM5WK8ys</span></code> your
|
||||||
application can reconstruct the full object from this small snippet that
|
application can reconstruct the full object from this small snippet that
|
||||||
passes through HTML Purifier <em>unharmed</em>.
|
passes through HTML Purifier <em>unharmed</em>.
|
||||||
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/Filter/YouTube.php">Show me the code!</a></p>
|
<a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/Filter/YouTube.php">Show me the code!</a></p>
|
||||||
|
|
||||||
<p>And the corresponding usage:</p>
|
<p>And the corresponding usage:</p>
|
||||||
|
|
||||||
|
@@ -98,8 +98,8 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
|||||||
<table class="table">
|
<table class="table">
|
||||||
|
|
||||||
<thead><tr>
|
<thead><tr>
|
||||||
<th width="10%">Type</th>
|
<th style="width:10%">Type</th>
|
||||||
<th width="20%">Name</th>
|
<th style="width:20%">Name</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
</tr></thead>
|
</tr></thead>
|
||||||
|
|
||||||
@@ -175,6 +175,5 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
|||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -42,7 +42,5 @@ into the mix.</li>
|
|||||||
something like that?</li>
|
something like that?</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
209
docs/proposal-errors.txt
Normal file
209
docs/proposal-errors.txt
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
Considerations for ErrorCollection
|
||||||
|
|
||||||
|
Presently, HTML Purifier takes a code-execution centric approach to handling
|
||||||
|
errors. Errors are organized and grouped according to which segment of the
|
||||||
|
code triggers them, not necessarily the portion of the input document that
|
||||||
|
triggered the error. This means that errors are pseudo-sorted by category,
|
||||||
|
rather than location in the document.
|
||||||
|
|
||||||
|
One easy way to "fix" this problem would be to re-sort according to line number.
|
||||||
|
However, the "category" style information we derive from naively following
|
||||||
|
program execution is still useful. After all, each of the strategies which
|
||||||
|
can report errors still process the document mostly linearly. Furthermore,
|
||||||
|
not only do they process linearly, but the way they pass off operations to
|
||||||
|
sub-systems mirrors that of the document. For example, AttrValidator will
|
||||||
|
linearly proceed through elements, and on each element will use AttrDef to
|
||||||
|
validate those contents. From there, the attribute might have more
|
||||||
|
sub-components, which have execution passed off accordingly.
|
||||||
|
|
||||||
|
In fact, each strategy handles a very specific class of "error."
|
||||||
|
|
||||||
|
RemoveForeignElements - element tokens
|
||||||
|
MakeWellFormed - element token ordering
|
||||||
|
FixNesting - element token ordering
|
||||||
|
ValidateAttributes - attributes of elements
|
||||||
|
|
||||||
|
The crucial point is that while we care about the hierarchy governing these
|
||||||
|
different errors, we *don't* care about any other information about what actually
|
||||||
|
happens to the elements. This brings up another point: if HTML Purifier fixes
|
||||||
|
something, this is not really a notice/warning/error; it's really a suggestion
|
||||||
|
of a way to fix the aforementioned defects.
|
||||||
|
|
||||||
|
In short, the refactoring to take this into account kinda sucks.
|
||||||
|
|
||||||
|
Errors should not be recorded in order that they are reported. Instead, they
|
||||||
|
should be bound to the line (and preferably element) in which they were found.
|
||||||
|
This means we need some way to uniquely identify every element in the document,
|
||||||
|
which doesn't presently exist. An easy way of adding this would be to track
|
||||||
|
line columns. An important ramification of this is that we *must* use the
|
||||||
|
DirectLex implementation.
|
||||||
|
|
||||||
|
1. Implement column numbers for DirectLex [DONE!]
|
||||||
|
2. Disable error collection when not using DirectLex [DONE!]
|
||||||
|
|
||||||
|
Next, we need to re-orient all of the error declarations to place CurrentToken
|
||||||
|
at utmost important. Since this is passed via Context, it's not always clear
|
||||||
|
if that's available. ErrorCollector should complain HARD if it isn't available.
|
||||||
|
There are some locations when we don't have a token available. These include:
|
||||||
|
|
||||||
|
* Lexing - this can actually have a row and column, but NOT correspond to
|
||||||
|
a token
|
||||||
|
* End of document errors - bump this to the end
|
||||||
|
|
||||||
|
Actually, we *don't* have to complain if CurrentToken isn't available; we just
|
||||||
|
set it as a document-wide error. And actually, nothing needs to be done here.
|
||||||
|
|
||||||
|
Something interesting to consider is whether or not we care about the locations
|
||||||
|
of attributes and CSS properties, i.e. the sub-objects that compose these things.
|
||||||
|
In terms of consistency, at the very least attributes should have column/line
|
||||||
|
numbers attached to them. However, this may be overkill, as attributes are
|
||||||
|
uniquely identifiable. You could go even further, with CSS, but they are also
|
||||||
|
uniquely identifiable.
|
||||||
|
|
||||||
|
Bottom-line is, however, this information must be available, in form of the
|
||||||
|
CurrentAttribute and CurrentCssProperty (theoretical) context variables, and
|
||||||
|
it must be used to organize the errors that the sub-processes may throw.
|
||||||
|
There is also a hierarchy of sorts that may make merging this into one context
|
||||||
|
variable more sense, if it hadn't been for HTML's reasonably rigid structure.
|
||||||
|
A CSS property will never contain an HTML attribute. So we won't ever get
|
||||||
|
recursive relations, and having multiple depths won't ever make sense. Leave
|
||||||
|
this be.
|
||||||
|
|
||||||
|
We already have this information, and consequently, using start and end is
|
||||||
|
*unnecessary*, so long as the context variables are set appropriately. We don't
|
||||||
|
care if an error was thrown by an attribute transform or an attribute definition;
|
||||||
|
to the end user these are the same (for a developer, they are different, but
|
||||||
|
they're better off with a stack trace (which we should add support for) in such
|
||||||
|
cases).
|
||||||
|
|
||||||
|
3. Remove start()/end() code. Don't get rid of recursion, though [DONE]
|
||||||
|
4. Setup ErrorCollector to use context information to setup hierarchies.
|
||||||
|
This may require a different internal format. Use objects if it gets
|
||||||
|
complex. [DONE]
|
||||||
|
|
||||||
|
ASIDE
|
||||||
|
More on this topic: since we are now binding errors to lines
|
||||||
|
and columns, a particular error can have three relationships to that
|
||||||
|
specific location:
|
||||||
|
|
||||||
|
1. The token at that location directly
|
||||||
|
RemoveForeignElements
|
||||||
|
AttrValidator (transforms)
|
||||||
|
MakeWellFormed
|
||||||
|
2. A "component" of that token (i.e. attribute)
|
||||||
|
AttrValidator (removals)
|
||||||
|
3. A modification to that node (i.e. contents from start to end
|
||||||
|
token) as a whole
|
||||||
|
FixNesting
|
||||||
|
|
||||||
|
This needs to be marked accordingly. In the presentation, it might
|
||||||
|
make sense keep (3) separate, have (2) a sublist of (1). (1) can
|
||||||
|
be a closing tag, in which case (3) makes no sense at all, OR it
|
||||||
|
should be related with its opening tag (this may not necessarily
|
||||||
|
be possible before MakeWellFormed is run).
|
||||||
|
|
||||||
|
So, the line and column counts as our identifier, so:
|
||||||
|
|
||||||
|
$errors[$line][$col] = ...
|
||||||
|
|
||||||
|
Then, we need to identify case 1, 2 or 3. They are identified as
|
||||||
|
such:
|
||||||
|
|
||||||
|
1. Need some sort of semaphore in RemoveForeignElements, etc.
|
||||||
|
2. If CurrentAttr/CurrentCssProperty is non-null
|
||||||
|
3. Default (FixNesting, MakeWellFormed)
|
||||||
|
|
||||||
|
One consideration about (1) is that it usually is actually a
|
||||||
|
(3) modification, but we have no way of knowing about that because
|
||||||
|
of various optimizations. However, they can probably be treated
|
||||||
|
the same. The other difficulty is that (3) is never a line and
|
||||||
|
column; rather, it is a range (i.e. a duple) and telling the user
|
||||||
|
the very start of the range may confuse them. For example,
|
||||||
|
|
||||||
|
<b>Foo<div>bar</div></b>
|
||||||
|
^ ^
|
||||||
|
|
||||||
|
The node being operated on is <b>, so the error would be assigned
|
||||||
|
to the first caret, with a "node reorganized" error. Then, the
|
||||||
|
ChildDef would have submitted its own suggestions and errors with
|
||||||
|
regard to what's going in the internals. So I suppose this is
|
||||||
|
ok. :-)
|
||||||
|
|
||||||
|
Now, the structure of the earlier mentioned ... would be something
|
||||||
|
like this:
|
||||||
|
|
||||||
|
object {
|
||||||
|
type = (token|attr|property),
|
||||||
|
value, // appropriate for type
|
||||||
|
errors => array(),
|
||||||
|
sub-errors = [recursive],
|
||||||
|
}
|
||||||
|
|
||||||
|
This helps us keep things agnostic. It is also sufficiently complex
|
||||||
|
enough to warrant an object.
|
||||||
|
|
||||||
|
So, more wanking about the object format is in order. The way HTML Purifier is
|
||||||
|
currently setup, the only possible hierarchy is:
|
||||||
|
|
||||||
|
token -> attr -> css property
|
||||||
|
|
||||||
|
These relations do not exist all of the time; a comment or end token would not
|
||||||
|
ever have any attributes, and non-style attributes would never have CSS properties
|
||||||
|
associated with them.
|
||||||
|
|
||||||
|
I believe that it is worth supporting multiple paths. At some point, we might
|
||||||
|
have a hierarchy like:
|
||||||
|
|
||||||
|
* -> syntax
|
||||||
|
-> token -> attr -> css property
|
||||||
|
-> url
|
||||||
|
-> css stylesheet <style>
|
||||||
|
|
||||||
|
et cetera. Now, one of the practical implications of this is that every "node"
|
||||||
|
on our tree is well-defined, so in theory it should be possible to either 1.
|
||||||
|
create a separate class for each error struct, or 2. embed this information
|
||||||
|
directly into HTML Purifier's token stream. Embedding the information in the
|
||||||
|
token stream is not a terribly good idea, since tokens can be removed, etc.
|
||||||
|
So that leaves us with 1... and if we use a generic interface we can cut down
|
||||||
|
on a lot of code we might need. So let's leave it like this.
|
||||||
|
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
Then we setup suggestions.
|
||||||
|
|
||||||
|
5. Setup a separate error class which tells the user any modifications
|
||||||
|
HTML Purifier made.
|
||||||
|
|
||||||
|
Some information about this:
|
||||||
|
|
||||||
|
Our current paradigm is to tell the user what HTML Purifier did to the HTML.
|
||||||
|
This is the most natural mode of operation, since that's what HTML Purifier
|
||||||
|
is all about; it was not meant to be a validator.
|
||||||
|
|
||||||
|
However, most other people have experience dealing with a validator. In cases
|
||||||
|
where HTML Purifier unambiguously does the right thing, simply giving the user
|
||||||
|
the correct version isn't a bad idea, but problems arise when:
|
||||||
|
|
||||||
|
- The user has such bad HTML we do something odd, when we should have just
|
||||||
|
flagged the HTML as an error. Such examples are when we do things like
|
||||||
|
remove text from directly inside a <table> tag. It was probably meant to
|
||||||
|
be in a <td> tag or be outside the table, but we're not smart enough to
|
||||||
|
realize this so we just remove it. In such a case, we should tell the user
|
||||||
|
that there was foreign data in the table, but then we shouldn't "demand"
|
||||||
|
the user remove the data; it's more of a "here's a possible way of
|
||||||
|
rectifying the problem"
|
||||||
|
|
||||||
|
- Giving line context for input is hard enough, but feasible; giving output
|
||||||
|
line context will be extremely difficult due to shifting lines; we'd probably
|
||||||
|
have to track what the tokens are and then find the appropriate out context
|
||||||
|
and it's not guaranteed to work etc etc etc.
|
||||||
|
|
||||||
|
````````````
|
||||||
|
|
||||||
|
Don't forget to spruce up output.
|
||||||
|
|
||||||
|
6. Output needs to automatically give line and column numbers, basically
|
||||||
|
"at line" on steroids. Look at W3C's output; it's ok. [PARTIALLY DONE]
|
||||||
|
|
||||||
|
- We need a standard CSS to apply (check demo.css for some starting
|
||||||
|
styling; some buttons would also be hip)
|
@@ -40,6 +40,5 @@ the development of this library in these forum threads:</p>
|
|||||||
|
|
||||||
<p>...as well as any I may have forgotten.</p>
|
<p>...as well as any I may have forgotten.</p>
|
||||||
|
|
||||||
<div id="version">$Id$</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
129
docs/specimens/jochem-blok-word.html
Normal file
129
docs/specimens/jochem-blok-word.html
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
|
||||||
|
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
|
||||||
|
<!--[if !mso]>
|
||||||
|
<style>
|
||||||
|
v\:* {behavior:url(#default#VML);}
|
||||||
|
o\:* {behavior:url(#default#VML);}
|
||||||
|
w\:* {behavior:url(#default#VML);}
|
||||||
|
..shape {behavior:url(#default#VML);}
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
<style>
|
||||||
|
<!--
|
||||||
|
/* Font Definitions */
|
||||||
|
@font-face
|
||||||
|
{font-family:"Cambria Math";
|
||||||
|
panose-1:2 4 5 3 5 4 6 3 2 4;}
|
||||||
|
@font-face
|
||||||
|
{font-family:Calibri;
|
||||||
|
panose-1:2 15 5 2 2 2 4 3 2 4;}
|
||||||
|
@font-face
|
||||||
|
{font-family:Tahoma;
|
||||||
|
panose-1:2 11 6 4 3 5 4 4 2 4;}
|
||||||
|
@font-face
|
||||||
|
{font-family:Verdana;
|
||||||
|
panose-1:2 11 6 4 3 5 4 4 2 4;}
|
||||||
|
/* Style Definitions */
|
||||||
|
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
||||||
|
{margin:0cm;
|
||||||
|
margin-bottom:.0001pt;
|
||||||
|
font-size:10.0pt;
|
||||||
|
font-family:"Verdana","sans-serif";}
|
||||||
|
a:link, span.MsoHyperlink
|
||||||
|
{mso-style-priority:99;
|
||||||
|
color:blue;
|
||||||
|
text-decoration:underline;}
|
||||||
|
a:visited, span.MsoHyperlinkFollowed
|
||||||
|
{mso-style-priority:99;
|
||||||
|
color:purple;
|
||||||
|
text-decoration:underline;}
|
||||||
|
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
|
||||||
|
{mso-style-priority:99;
|
||||||
|
mso-style-link:"Balloon Text Char";
|
||||||
|
margin:0cm;
|
||||||
|
margin-bottom:.0001pt;
|
||||||
|
font-size:8.0pt;
|
||||||
|
font-family:"Tahoma","sans-serif";}
|
||||||
|
span.EmailStyle17
|
||||||
|
{mso-style-type:personal-compose;
|
||||||
|
font-family:"Verdana","sans-serif";
|
||||||
|
color:windowtext;}
|
||||||
|
span.BalloonTextChar
|
||||||
|
{mso-style-name:"Balloon Text Char";
|
||||||
|
mso-style-priority:99;
|
||||||
|
mso-style-link:"Balloon Text";
|
||||||
|
font-family:"Tahoma","sans-serif";}
|
||||||
|
..MsoChpDefault
|
||||||
|
{mso-style-type:export-only;}
|
||||||
|
@page Section1
|
||||||
|
{size:612.0pt 792.0pt;
|
||||||
|
margin:70.85pt 70.85pt 70.85pt 70.85pt;}
|
||||||
|
div.Section1
|
||||||
|
{page:Section1;}
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
<!--[if gte mso 9]><xml>
|
||||||
|
<o:shapedefaults v:ext="edit" spidmax="2050" />
|
||||||
|
</xml><![endif]--><!--[if gte mso 9]><xml>
|
||||||
|
<o:shapelayout v:ext="edit">
|
||||||
|
<o:idmap v:ext="edit" data="1" />
|
||||||
|
</o:shapelayout></xml><![endif]-->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body lang=NL link=blue vlink=purple>
|
||||||
|
|
||||||
|
<div class=Section1>
|
||||||
|
|
||||||
|
<p class=MsoNormal><img width=1277 height=994 id="Picture_x0020_1"
|
||||||
|
src="cid:image001.png@01C8CBDF.5D1BAEE0"><o:p></o:p></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><o:p> </o:p></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><b>Name<o:p></o:p></b></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal>E-mail : <a href="mailto:mail@example.com"><span
|
||||||
|
style='color:windowtext'>mail@example.com</span></a><o:p></o:p></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><o:p> </o:p></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><b>Company<o:p></o:p></b></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal>Address 1<o:p></o:p></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal>Address 2<o:p></o:p></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><o:p> </o:p></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal>Telefoon : +xx xx xxx xxx xx <span style='color:black'><o:p></o:p></span></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><span lang=EN-US style='color:black'>Fax : +xx xx xxx xx xx<o:p></o:p></span></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><span lang=EN-US style='color:black'>Internet : </span><span
|
||||||
|
style='color:black'><a href="http://www.example.com/"><span lang=EN-US
|
||||||
|
style='color:black'>http://www.example.com</span></a></span><span
|
||||||
|
lang=EN-US style='color:black'><o:p></o:p></span></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><span lang=EN-US style='color:black'>Kamer van koophandel
|
||||||
|
xxxxxxxxx<o:p></o:p></span></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><span lang=EN-US style='color:black'><o:p> </o:p></span></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><span lang=EN-US style='font-size:7.5pt;color:black'>Op deze
|
||||||
|
e-mail is een disclaimer van toepassing, ga naar </span><span lang=EN-US
|
||||||
|
style='font-size:7.5pt'><a
|
||||||
|
href="http://www.example.com/disclaimer"><span
|
||||||
|
style='color:black'>www.example.com/disclaimer</span></a><br>
|
||||||
|
<span style='color:black'>A disclaimer is applicable to this email, please
|
||||||
|
refer to </span><a href="http://www.example.com/disclaimer"><span
|
||||||
|
style='color:black'>www.example.com/disclaimer</span></a><o:p></o:p></span></p>
|
||||||
|
|
||||||
|
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@@ -7,7 +7,7 @@
|
|||||||
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
|
* 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.
|
* FILE, changes will be overwritten the next time the script is run.
|
||||||
*
|
*
|
||||||
* @version 3.1.0
|
* @version 3.2.0
|
||||||
*
|
*
|
||||||
* @warning
|
* @warning
|
||||||
* You must *not* include any other HTML Purifier files before this file,
|
* You must *not* include any other HTML Purifier files before this file,
|
||||||
@@ -29,7 +29,6 @@ require 'HTMLPurifier/Definition.php';
|
|||||||
require 'HTMLPurifier/CSSDefinition.php';
|
require 'HTMLPurifier/CSSDefinition.php';
|
||||||
require 'HTMLPurifier/ChildDef.php';
|
require 'HTMLPurifier/ChildDef.php';
|
||||||
require 'HTMLPurifier/Config.php';
|
require 'HTMLPurifier/Config.php';
|
||||||
require 'HTMLPurifier/ConfigDef.php';
|
|
||||||
require 'HTMLPurifier/ConfigSchema.php';
|
require 'HTMLPurifier/ConfigSchema.php';
|
||||||
require 'HTMLPurifier/ContentSets.php';
|
require 'HTMLPurifier/ContentSets.php';
|
||||||
require 'HTMLPurifier/Context.php';
|
require 'HTMLPurifier/Context.php';
|
||||||
@@ -42,6 +41,7 @@ require 'HTMLPurifier/Encoder.php';
|
|||||||
require 'HTMLPurifier/EntityLookup.php';
|
require 'HTMLPurifier/EntityLookup.php';
|
||||||
require 'HTMLPurifier/EntityParser.php';
|
require 'HTMLPurifier/EntityParser.php';
|
||||||
require 'HTMLPurifier/ErrorCollector.php';
|
require 'HTMLPurifier/ErrorCollector.php';
|
||||||
|
require 'HTMLPurifier/ErrorStruct.php';
|
||||||
require 'HTMLPurifier/Exception.php';
|
require 'HTMLPurifier/Exception.php';
|
||||||
require 'HTMLPurifier/Filter.php';
|
require 'HTMLPurifier/Filter.php';
|
||||||
require 'HTMLPurifier/Generator.php';
|
require 'HTMLPurifier/Generator.php';
|
||||||
@@ -52,6 +52,7 @@ require 'HTMLPurifier/IDAccumulator.php';
|
|||||||
require 'HTMLPurifier/Injector.php';
|
require 'HTMLPurifier/Injector.php';
|
||||||
require 'HTMLPurifier/Language.php';
|
require 'HTMLPurifier/Language.php';
|
||||||
require 'HTMLPurifier/LanguageFactory.php';
|
require 'HTMLPurifier/LanguageFactory.php';
|
||||||
|
require 'HTMLPurifier/Length.php';
|
||||||
require 'HTMLPurifier/Lexer.php';
|
require 'HTMLPurifier/Lexer.php';
|
||||||
require 'HTMLPurifier/PercentEncoder.php';
|
require 'HTMLPurifier/PercentEncoder.php';
|
||||||
require 'HTMLPurifier/Strategy.php';
|
require 'HTMLPurifier/Strategy.php';
|
||||||
@@ -66,12 +67,14 @@ require 'HTMLPurifier/URIFilter.php';
|
|||||||
require 'HTMLPurifier/URIParser.php';
|
require 'HTMLPurifier/URIParser.php';
|
||||||
require 'HTMLPurifier/URIScheme.php';
|
require 'HTMLPurifier/URIScheme.php';
|
||||||
require 'HTMLPurifier/URISchemeRegistry.php';
|
require 'HTMLPurifier/URISchemeRegistry.php';
|
||||||
|
require 'HTMLPurifier/UnitConverter.php';
|
||||||
require 'HTMLPurifier/VarParser.php';
|
require 'HTMLPurifier/VarParser.php';
|
||||||
require 'HTMLPurifier/VarParserException.php';
|
require 'HTMLPurifier/VarParserException.php';
|
||||||
require 'HTMLPurifier/AttrDef/CSS.php';
|
require 'HTMLPurifier/AttrDef/CSS.php';
|
||||||
require 'HTMLPurifier/AttrDef/Enum.php';
|
require 'HTMLPurifier/AttrDef/Enum.php';
|
||||||
require 'HTMLPurifier/AttrDef/Integer.php';
|
require 'HTMLPurifier/AttrDef/Integer.php';
|
||||||
require 'HTMLPurifier/AttrDef/Lang.php';
|
require 'HTMLPurifier/AttrDef/Lang.php';
|
||||||
|
require 'HTMLPurifier/AttrDef/Switch.php';
|
||||||
require 'HTMLPurifier/AttrDef/Text.php';
|
require 'HTMLPurifier/AttrDef/Text.php';
|
||||||
require 'HTMLPurifier/AttrDef/URI.php';
|
require 'HTMLPurifier/AttrDef/URI.php';
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Number.php';
|
require 'HTMLPurifier/AttrDef/CSS/Number.php';
|
||||||
@@ -106,6 +109,7 @@ require 'HTMLPurifier/AttrDef/URI/Host.php';
|
|||||||
require 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
require 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||||
require 'HTMLPurifier/AttrDef/URI/IPv6.php';
|
require 'HTMLPurifier/AttrDef/URI/IPv6.php';
|
||||||
require 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
require 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
||||||
|
require 'HTMLPurifier/AttrTransform/Background.php';
|
||||||
require 'HTMLPurifier/AttrTransform/BdoDir.php';
|
require 'HTMLPurifier/AttrTransform/BdoDir.php';
|
||||||
require 'HTMLPurifier/AttrTransform/BgColor.php';
|
require 'HTMLPurifier/AttrTransform/BgColor.php';
|
||||||
require 'HTMLPurifier/AttrTransform/BoolToCSS.php';
|
require 'HTMLPurifier/AttrTransform/BoolToCSS.php';
|
||||||
@@ -113,10 +117,15 @@ require 'HTMLPurifier/AttrTransform/Border.php';
|
|||||||
require 'HTMLPurifier/AttrTransform/EnumToCSS.php';
|
require 'HTMLPurifier/AttrTransform/EnumToCSS.php';
|
||||||
require 'HTMLPurifier/AttrTransform/ImgRequired.php';
|
require 'HTMLPurifier/AttrTransform/ImgRequired.php';
|
||||||
require 'HTMLPurifier/AttrTransform/ImgSpace.php';
|
require 'HTMLPurifier/AttrTransform/ImgSpace.php';
|
||||||
|
require 'HTMLPurifier/AttrTransform/Input.php';
|
||||||
require 'HTMLPurifier/AttrTransform/Lang.php';
|
require 'HTMLPurifier/AttrTransform/Lang.php';
|
||||||
require 'HTMLPurifier/AttrTransform/Length.php';
|
require 'HTMLPurifier/AttrTransform/Length.php';
|
||||||
require 'HTMLPurifier/AttrTransform/Name.php';
|
require 'HTMLPurifier/AttrTransform/Name.php';
|
||||||
|
require 'HTMLPurifier/AttrTransform/SafeEmbed.php';
|
||||||
|
require 'HTMLPurifier/AttrTransform/SafeObject.php';
|
||||||
|
require 'HTMLPurifier/AttrTransform/SafeParam.php';
|
||||||
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
|
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||||
|
require 'HTMLPurifier/AttrTransform/Textarea.php';
|
||||||
require 'HTMLPurifier/ChildDef/Chameleon.php';
|
require 'HTMLPurifier/ChildDef/Chameleon.php';
|
||||||
require 'HTMLPurifier/ChildDef/Custom.php';
|
require 'HTMLPurifier/ChildDef/Custom.php';
|
||||||
require 'HTMLPurifier/ChildDef/Empty.php';
|
require 'HTMLPurifier/ChildDef/Empty.php';
|
||||||
@@ -124,9 +133,6 @@ require 'HTMLPurifier/ChildDef/Required.php';
|
|||||||
require 'HTMLPurifier/ChildDef/Optional.php';
|
require 'HTMLPurifier/ChildDef/Optional.php';
|
||||||
require 'HTMLPurifier/ChildDef/StrictBlockquote.php';
|
require 'HTMLPurifier/ChildDef/StrictBlockquote.php';
|
||||||
require 'HTMLPurifier/ChildDef/Table.php';
|
require 'HTMLPurifier/ChildDef/Table.php';
|
||||||
require 'HTMLPurifier/ConfigDef/Directive.php';
|
|
||||||
require 'HTMLPurifier/ConfigDef/DirectiveAlias.php';
|
|
||||||
require 'HTMLPurifier/ConfigDef/Namespace.php';
|
|
||||||
require 'HTMLPurifier/DefinitionCache/Decorator.php';
|
require 'HTMLPurifier/DefinitionCache/Decorator.php';
|
||||||
require 'HTMLPurifier/DefinitionCache/Null.php';
|
require 'HTMLPurifier/DefinitionCache/Null.php';
|
||||||
require 'HTMLPurifier/DefinitionCache/Serializer.php';
|
require 'HTMLPurifier/DefinitionCache/Serializer.php';
|
||||||
@@ -135,15 +141,19 @@ require 'HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
|||||||
require 'HTMLPurifier/HTMLModule/Bdo.php';
|
require 'HTMLPurifier/HTMLModule/Bdo.php';
|
||||||
require 'HTMLPurifier/HTMLModule/CommonAttributes.php';
|
require 'HTMLPurifier/HTMLModule/CommonAttributes.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Edit.php';
|
require 'HTMLPurifier/HTMLModule/Edit.php';
|
||||||
|
require 'HTMLPurifier/HTMLModule/Forms.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Hypertext.php';
|
require 'HTMLPurifier/HTMLModule/Hypertext.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Image.php';
|
require 'HTMLPurifier/HTMLModule/Image.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Legacy.php';
|
require 'HTMLPurifier/HTMLModule/Legacy.php';
|
||||||
require 'HTMLPurifier/HTMLModule/List.php';
|
require 'HTMLPurifier/HTMLModule/List.php';
|
||||||
|
require 'HTMLPurifier/HTMLModule/Name.php';
|
||||||
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Object.php';
|
require 'HTMLPurifier/HTMLModule/Object.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Presentation.php';
|
require 'HTMLPurifier/HTMLModule/Presentation.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Proprietary.php';
|
require 'HTMLPurifier/HTMLModule/Proprietary.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Ruby.php';
|
require 'HTMLPurifier/HTMLModule/Ruby.php';
|
||||||
|
require 'HTMLPurifier/HTMLModule/SafeEmbed.php';
|
||||||
|
require 'HTMLPurifier/HTMLModule/SafeObject.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Scripting.php';
|
require 'HTMLPurifier/HTMLModule/Scripting.php';
|
||||||
require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
|
require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tables.php';
|
require 'HTMLPurifier/HTMLModule/Tables.php';
|
||||||
@@ -151,14 +161,18 @@ require 'HTMLPurifier/HTMLModule/Target.php';
|
|||||||
require 'HTMLPurifier/HTMLModule/Text.php';
|
require 'HTMLPurifier/HTMLModule/Text.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy.php';
|
require 'HTMLPurifier/HTMLModule/Tidy.php';
|
||||||
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||||
|
require 'HTMLPurifier/HTMLModule/Tidy/Name.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
require 'HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
require 'HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
||||||
require 'HTMLPurifier/Injector/AutoParagraph.php';
|
require 'HTMLPurifier/Injector/AutoParagraph.php';
|
||||||
|
require 'HTMLPurifier/Injector/DisplayLinkURI.php';
|
||||||
require 'HTMLPurifier/Injector/Linkify.php';
|
require 'HTMLPurifier/Injector/Linkify.php';
|
||||||
require 'HTMLPurifier/Injector/PurifierLinkify.php';
|
require 'HTMLPurifier/Injector/PurifierLinkify.php';
|
||||||
|
require 'HTMLPurifier/Injector/RemoveEmpty.php';
|
||||||
|
require 'HTMLPurifier/Injector/SafeObject.php';
|
||||||
require 'HTMLPurifier/Lexer/DOMLex.php';
|
require 'HTMLPurifier/Lexer/DOMLex.php';
|
||||||
require 'HTMLPurifier/Lexer/DirectLex.php';
|
require 'HTMLPurifier/Lexer/DirectLex.php';
|
||||||
require 'HTMLPurifier/Strategy/Composite.php';
|
require 'HTMLPurifier/Strategy/Composite.php';
|
||||||
@@ -179,6 +193,7 @@ require 'HTMLPurifier/URIFilter/DisableExternal.php';
|
|||||||
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
|
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
|
||||||
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
|
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
|
||||||
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
|
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||||
|
require 'HTMLPurifier/URIFilter/Munge.php';
|
||||||
require 'HTMLPurifier/URIScheme/ftp.php';
|
require 'HTMLPurifier/URIScheme/ftp.php';
|
||||||
require 'HTMLPurifier/URIScheme/http.php';
|
require 'HTMLPurifier/URIScheme/http.php';
|
||||||
require 'HTMLPurifier/URIScheme/https.php';
|
require 'HTMLPurifier/URIScheme/https.php';
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
HTML Purifier 3.1.0 - Standards Compliant HTML Filtering
|
HTML Purifier 3.2.0 - Standards Compliant HTML Filtering
|
||||||
Copyright (C) 2006-2008 Edward Z. Yang
|
Copyright (C) 2006-2008 Edward Z. Yang
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
@@ -55,10 +55,10 @@ class HTMLPurifier
|
|||||||
{
|
{
|
||||||
|
|
||||||
/** Version of HTML Purifier */
|
/** Version of HTML Purifier */
|
||||||
public $version = '3.1.0';
|
public $version = '3.2.0';
|
||||||
|
|
||||||
/** Constant with version of HTML Purifier */
|
/** Constant with version of HTML Purifier */
|
||||||
const VERSION = '3.1.0';
|
const VERSION = '3.2.0';
|
||||||
|
|
||||||
/** Global configuration object */
|
/** Global configuration object */
|
||||||
public $config;
|
public $config;
|
||||||
|
@@ -23,7 +23,6 @@ require_once $__dir . '/HTMLPurifier/Definition.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/CSSDefinition.php';
|
require_once $__dir . '/HTMLPurifier/CSSDefinition.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef.php';
|
require_once $__dir . '/HTMLPurifier/ChildDef.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Config.php';
|
require_once $__dir . '/HTMLPurifier/Config.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ConfigDef.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ConfigSchema.php';
|
require_once $__dir . '/HTMLPurifier/ConfigSchema.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ContentSets.php';
|
require_once $__dir . '/HTMLPurifier/ContentSets.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Context.php';
|
require_once $__dir . '/HTMLPurifier/Context.php';
|
||||||
@@ -36,6 +35,7 @@ require_once $__dir . '/HTMLPurifier/Encoder.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
|
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
|
||||||
require_once $__dir . '/HTMLPurifier/EntityParser.php';
|
require_once $__dir . '/HTMLPurifier/EntityParser.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
|
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/ErrorStruct.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Exception.php';
|
require_once $__dir . '/HTMLPurifier/Exception.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Filter.php';
|
require_once $__dir . '/HTMLPurifier/Filter.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Generator.php';
|
require_once $__dir . '/HTMLPurifier/Generator.php';
|
||||||
@@ -46,6 +46,7 @@ require_once $__dir . '/HTMLPurifier/IDAccumulator.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/Injector.php';
|
require_once $__dir . '/HTMLPurifier/Injector.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Language.php';
|
require_once $__dir . '/HTMLPurifier/Language.php';
|
||||||
require_once $__dir . '/HTMLPurifier/LanguageFactory.php';
|
require_once $__dir . '/HTMLPurifier/LanguageFactory.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/Length.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Lexer.php';
|
require_once $__dir . '/HTMLPurifier/Lexer.php';
|
||||||
require_once $__dir . '/HTMLPurifier/PercentEncoder.php';
|
require_once $__dir . '/HTMLPurifier/PercentEncoder.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy.php';
|
require_once $__dir . '/HTMLPurifier/Strategy.php';
|
||||||
@@ -60,12 +61,14 @@ require_once $__dir . '/HTMLPurifier/URIFilter.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/URIParser.php';
|
require_once $__dir . '/HTMLPurifier/URIParser.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme.php';
|
require_once $__dir . '/HTMLPurifier/URIScheme.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URISchemeRegistry.php';
|
require_once $__dir . '/HTMLPurifier/URISchemeRegistry.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/UnitConverter.php';
|
||||||
require_once $__dir . '/HTMLPurifier/VarParser.php';
|
require_once $__dir . '/HTMLPurifier/VarParser.php';
|
||||||
require_once $__dir . '/HTMLPurifier/VarParserException.php';
|
require_once $__dir . '/HTMLPurifier/VarParserException.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/CSS.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Enum.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/Enum.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Integer.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/Integer.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Lang.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/Lang.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/AttrDef/Switch.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Text.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/Text.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/URI.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Number.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Number.php';
|
||||||
@@ -100,6 +103,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/URI/Host.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv4.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv6.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv6.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/AttrTransform/Background.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BdoDir.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/BdoDir.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BgColor.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/BgColor.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BoolToCSS.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/BoolToCSS.php';
|
||||||
@@ -107,10 +111,15 @@ require_once $__dir . '/HTMLPurifier/AttrTransform/Border.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/EnumToCSS.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/EnumToCSS.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgRequired.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgRequired.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgSpace.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgSpace.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/AttrTransform/Input.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeEmbed.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php';
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
|
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/AttrTransform/Textarea.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
|
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
|
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
|
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
|
||||||
@@ -118,9 +127,6 @@ require_once $__dir . '/HTMLPurifier/ChildDef/Required.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Optional.php';
|
require_once $__dir . '/HTMLPurifier/ChildDef/Optional.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/StrictBlockquote.php';
|
require_once $__dir . '/HTMLPurifier/ChildDef/StrictBlockquote.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Table.php';
|
require_once $__dir . '/HTMLPurifier/ChildDef/Table.php';
|
||||||
require_once $__dir . '/HTMLPurifier/ConfigDef/Directive.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ConfigDef/DirectiveAlias.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ConfigDef/Namespace.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator.php';
|
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator.php';
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Null.php';
|
require_once $__dir . '/HTMLPurifier/DefinitionCache/Null.php';
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Serializer.php';
|
require_once $__dir . '/HTMLPurifier/DefinitionCache/Serializer.php';
|
||||||
@@ -129,15 +135,19 @@ require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Bdo.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Bdo.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/CommonAttributes.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/CommonAttributes.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Edit.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Edit.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Forms.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Hypertext.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Hypertext.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Proprietary.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Proprietary.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Ruby.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Ruby.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeEmbed.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeObject.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Scripting.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Scripting.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
|
||||||
@@ -145,14 +155,18 @@ require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Name.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/AutoParagraph.php';
|
require_once $__dir . '/HTMLPurifier/Injector/AutoParagraph.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/Injector/DisplayLinkURI.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
|
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
|
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
|
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
|
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy/Composite.php';
|
require_once $__dir . '/HTMLPurifier/Strategy/Composite.php';
|
||||||
@@ -173,6 +187,7 @@ require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternal.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
|
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
|
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
|
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/URIFilter/Munge.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
|
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
|
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
|
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
|
||||||
|
@@ -51,16 +51,13 @@ abstract class HTMLPurifier_AttrDef
|
|||||||
*
|
*
|
||||||
* @warning This processing is inconsistent with XML's whitespace handling
|
* @warning This processing is inconsistent with XML's whitespace handling
|
||||||
* as specified by section 3.3.3 and referenced XHTML 1.0 section
|
* as specified by section 3.3.3 and referenced XHTML 1.0 section
|
||||||
* 4.7. Compliant processing requires all line breaks normalized
|
* 4.7. However, note that we are NOT necessarily
|
||||||
* to "\n", so the fix is not as simple as fixing it in this
|
* parsing XML, thus, this behavior may still be correct. We
|
||||||
* function. Trim and whitespace collapsing are supposed to only
|
* assume that newlines have been normalized.
|
||||||
* occur in NMTOKENs. However, note that we are NOT necessarily
|
|
||||||
* parsing XML, thus, this behavior may still be correct.
|
|
||||||
*/
|
*/
|
||||||
public function parseCDATA($string) {
|
public function parseCDATA($string) {
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
$string = str_replace("\n", '', $string);
|
$string = str_replace(array("\n", "\t", "\r"), ' ', $string);
|
||||||
$string = str_replace(array("\r", "\t"), ' ', $string);
|
|
||||||
return $string;
|
return $string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,6 +29,12 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
|||||||
$declarations = explode(';', $css);
|
$declarations = explode(';', $css);
|
||||||
$propvalues = array();
|
$propvalues = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the current CSS property being validated.
|
||||||
|
*/
|
||||||
|
$property = false;
|
||||||
|
$context->register('CurrentCSSProperty', $property);
|
||||||
|
|
||||||
foreach ($declarations as $declaration) {
|
foreach ($declarations as $declaration) {
|
||||||
if (!$declaration) continue;
|
if (!$declaration) continue;
|
||||||
if (!strpos($declaration, ':')) continue;
|
if (!strpos($declaration, ':')) continue;
|
||||||
@@ -61,6 +67,8 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
|||||||
$propvalues[$property] = $result;
|
$propvalues[$property] = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$context->destroy('CurrentCSSProperty');
|
||||||
|
|
||||||
// procedure does not write the new CSS simultaneously, so it's
|
// procedure does not write the new CSS simultaneously, so it's
|
||||||
// slightly inefficient, but it's the only way of getting rid of
|
// slightly inefficient, but it's the only way of getting rid of
|
||||||
// duplicates. Perhaps config to optimize it, but not now.
|
// duplicates. Perhaps config to optimize it, but not now.
|
||||||
|
@@ -16,7 +16,6 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
|||||||
'cursive' => true
|
'cursive' => true
|
||||||
);
|
);
|
||||||
|
|
||||||
$string = $this->parseCDATA($string);
|
|
||||||
// assume that no font names contain commas in them
|
// assume that no font names contain commas in them
|
||||||
$fonts = explode(',', $string);
|
$fonts = explode(',', $string);
|
||||||
$final = '';
|
$final = '';
|
||||||
@@ -35,13 +34,40 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
|||||||
$quote = $font[0];
|
$quote = $font[0];
|
||||||
if ($font[$length - 1] !== $quote) continue;
|
if ($font[$length - 1] !== $quote) continue;
|
||||||
$font = substr($font, 1, $length - 2);
|
$font = substr($font, 1, $length - 2);
|
||||||
// double-backslash processing is buggy
|
|
||||||
$font = str_replace("\\$quote", $quote, $font); // de-escape quote
|
$new_font = '';
|
||||||
$font = str_replace("\\\n", "\n", $font); // de-escape newlines
|
for ($i = 0, $c = strlen($font); $i < $c; $i++) {
|
||||||
|
if ($font[$i] === '\\') {
|
||||||
|
$i++;
|
||||||
|
if ($i >= $c) {
|
||||||
|
$new_font .= '\\';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ctype_xdigit($font[$i])) {
|
||||||
|
$code = $font[$i];
|
||||||
|
for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) {
|
||||||
|
if (!ctype_xdigit($font[$i])) break;
|
||||||
|
$code .= $font[$i];
|
||||||
|
}
|
||||||
|
// We have to be extremely careful when adding
|
||||||
|
// new characters, to make sure we're not breaking
|
||||||
|
// the encoding.
|
||||||
|
$char = HTMLPurifier_Encoder::unichr(hexdec($code));
|
||||||
|
if (HTMLPurifier_Encoder::cleanUTF8($char) === '') continue;
|
||||||
|
$new_font .= $char;
|
||||||
|
if ($i < $c && trim($font[$i]) !== '') $i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($font[$i] === "\n") continue;
|
||||||
|
}
|
||||||
|
$new_font .= $font[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
$font = $new_font;
|
||||||
}
|
}
|
||||||
// $font is a pure representation of the font name
|
// $font is a pure representation of the font name
|
||||||
|
|
||||||
if (ctype_alnum($font)) {
|
if (ctype_alnum($font) && $font !== '') {
|
||||||
// very simple font, allow it in unharmed
|
// very simple font, allow it in unharmed
|
||||||
$final .= $font . ', ';
|
$final .= $font . ', ';
|
||||||
continue;
|
continue;
|
||||||
@@ -50,8 +76,8 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
|||||||
// complicated font, requires quoting
|
// complicated font, requires quoting
|
||||||
|
|
||||||
// armor single quotes and new lines
|
// armor single quotes and new lines
|
||||||
|
$font = str_replace("\\", "\\\\", $font);
|
||||||
$font = str_replace("'", "\\'", $font);
|
$font = str_replace("'", "\\'", $font);
|
||||||
$font = str_replace("\n", "\\\n", $font);
|
|
||||||
$final .= "'$font', ";
|
$final .= "'$font', ";
|
||||||
}
|
}
|
||||||
$final = rtrim($final, ', ');
|
$final = rtrim($final, ', ');
|
||||||
|
@@ -6,46 +6,40 @@
|
|||||||
class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
protected $min, $max;
|
||||||
* Valid unit lookup table.
|
|
||||||
* @warning The code assumes all units are two characters long. Be careful
|
|
||||||
* if we have to change this behavior!
|
|
||||||
*/
|
|
||||||
protected $units = array('em' => true, 'ex' => true, 'px' => true, 'in' => true,
|
|
||||||
'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true);
|
|
||||||
/**
|
|
||||||
* Instance of HTMLPurifier_AttrDef_Number to defer number validation to
|
|
||||||
*/
|
|
||||||
protected $number_def;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $non_negative Bool indication whether or not negative values are
|
* @param HTMLPurifier_Length $max Minimum length, or null for no bound. String is also acceptable.
|
||||||
* allowed.
|
* @param HTMLPurifier_Length $max Maximum length, or null for no bound. String is also acceptable.
|
||||||
*/
|
*/
|
||||||
public function __construct($non_negative = false) {
|
public function __construct($min = null, $max = null) {
|
||||||
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
|
$this->min = $min !== null ? HTMLPurifier_Length::make($min) : null;
|
||||||
|
$this->max = $max !== null ? HTMLPurifier_Length::make($max) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($length, $config, $context) {
|
public function validate($string, $config, $context) {
|
||||||
|
$string = $this->parseCDATA($string);
|
||||||
|
|
||||||
$length = $this->parseCDATA($length);
|
// Optimizations
|
||||||
if ($length === '') return false;
|
if ($string === '') return false;
|
||||||
if ($length === '0') return '0';
|
if ($string === '0') return '0';
|
||||||
$strlen = strlen($length);
|
if (strlen($string) === 1) return false;
|
||||||
if ($strlen === 1) return false; // impossible!
|
|
||||||
|
|
||||||
// we assume all units are two characters
|
$length = HTMLPurifier_Length::make($string);
|
||||||
$unit = substr($length, $strlen - 2);
|
if (!$length->isValid()) return false;
|
||||||
if (!ctype_lower($unit)) $unit = strtolower($unit);
|
|
||||||
$number = substr($length, 0, $strlen - 2);
|
|
||||||
|
|
||||||
if (!isset($this->units[$unit])) return false;
|
if ($this->min) {
|
||||||
|
$c = $length->compareTo($this->min);
|
||||||
$number = $this->number_def->validate($number, $config, $context);
|
if ($c === false) return false;
|
||||||
if ($number === false) return false;
|
if ($c < 0) return false;
|
||||||
|
}
|
||||||
return $number . $unit;
|
if ($this->max) {
|
||||||
|
$c = $length->compareTo($this->max);
|
||||||
|
if ($c === false) return false;
|
||||||
|
if ($c > 0) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $length->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,10 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
|
|||||||
$this->non_negative = $non_negative;
|
$this->non_negative = $non_negative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @warning Some contexts do not pass $config, $context. These
|
||||||
|
* variables should not be used without checking HTMLPurifier_Length
|
||||||
|
*/
|
||||||
public function validate($number, $config, $context) {
|
public function validate($number, $config, $context) {
|
||||||
|
|
||||||
$number = $this->parseCDATA($number);
|
$number = $this->parseCDATA($number);
|
||||||
|
@@ -13,10 +13,13 @@ class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef
|
|||||||
static $allowed_values = array(
|
static $allowed_values = array(
|
||||||
'line-through' => true,
|
'line-through' => true,
|
||||||
'overline' => true,
|
'overline' => true,
|
||||||
'underline' => true
|
'underline' => true,
|
||||||
);
|
);
|
||||||
|
|
||||||
$string = strtolower($this->parseCDATA($string));
|
$string = strtolower($this->parseCDATA($string));
|
||||||
|
|
||||||
|
if ($string === 'none') return $string;
|
||||||
|
|
||||||
$parts = explode(' ', $string);
|
$parts = explode(' ', $string);
|
||||||
$final = '';
|
$final = '';
|
||||||
foreach ($parts as $part) {
|
foreach ($parts as $part) {
|
||||||
|
@@ -42,10 +42,7 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (empty($ret_lookup)) return false;
|
if (empty($ret_lookup)) return false;
|
||||||
|
$string = implode(' ', array_keys($ret_lookup));
|
||||||
$ret_array = array();
|
|
||||||
foreach ($ret_lookup as $part => $bool) $ret_array[] = $part;
|
|
||||||
$string = implode(' ', $ret_array);
|
|
||||||
|
|
||||||
return $string;
|
return $string;
|
||||||
|
|
||||||
|
@@ -6,6 +6,12 @@
|
|||||||
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protected $max;
|
||||||
|
|
||||||
|
public function __construct($max = null) {
|
||||||
|
$this->max = $max;
|
||||||
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
public function validate($string, $config, $context) {
|
||||||
|
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
@@ -24,11 +30,18 @@ class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
|
|||||||
// crash operating systems, see <http://ha.ckers.org/imagecrash.html>
|
// crash operating systems, see <http://ha.ckers.org/imagecrash.html>
|
||||||
// WARNING, above link WILL crash you if you're using Windows
|
// WARNING, above link WILL crash you if you're using Windows
|
||||||
|
|
||||||
if ($int > 1200) return '1200';
|
if ($this->max !== null && $int > $this->max) return (string) $this->max;
|
||||||
|
|
||||||
return (string) $int;
|
return (string) $int;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function make($string) {
|
||||||
|
if ($string === '') $max = null;
|
||||||
|
else $max = (int) $string;
|
||||||
|
$class = get_class($this);
|
||||||
|
return new $class($max);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
library/HTMLPurifier/AttrDef/Switch.php
Normal file
32
library/HTMLPurifier/AttrDef/Switch.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorator that, depending on a token, switches between two definitions.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_AttrDef_Switch
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $tag;
|
||||||
|
protected $withTag, $withoutTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $tag Tag name to switch upon
|
||||||
|
* @param HTMLPurifier_AttrDef $with_tag Call if token matches tag
|
||||||
|
* @param HTMLPurifier_AttrDef $without_tag Call if token doesn't match, or there is no token
|
||||||
|
*/
|
||||||
|
public function __construct($tag, $with_tag, $without_tag) {
|
||||||
|
$this->tag = $tag;
|
||||||
|
$this->withTag = $with_tag;
|
||||||
|
$this->withoutTag = $without_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validate($string, $config, $context) {
|
||||||
|
$token = $context->get('CurrentToken', true);
|
||||||
|
if (!$token || $token->name !== $this->tag) {
|
||||||
|
return $this->withoutTag->validate($string, $config, $context);
|
||||||
|
} else {
|
||||||
|
return $this->withTag->validate($string, $config, $context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -18,6 +18,11 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
$this->embedsResource = (bool) $embeds_resource;
|
$this->embedsResource = (bool) $embeds_resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function make($string) {
|
||||||
|
$embeds = (bool) $string;
|
||||||
|
return new HTMLPurifier_AttrDef_URI($embeds);
|
||||||
|
}
|
||||||
|
|
||||||
public function validate($uri, $config, $context) {
|
public function validate($uri, $config, $context) {
|
||||||
|
|
||||||
if ($config->get('URI', 'Disable')) return false;
|
if ($config->get('URI', 'Disable')) return false;
|
||||||
@@ -50,6 +55,10 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
$result = $scheme_obj->validate($uri, $config, $context);
|
$result = $scheme_obj->validate($uri, $config, $context);
|
||||||
if (!$result) break;
|
if (!$result) break;
|
||||||
|
|
||||||
|
// Post chained filtering
|
||||||
|
$result = $uri_def->postFilter($uri, $config, $context);
|
||||||
|
if (!$result) break;
|
||||||
|
|
||||||
// survived gauntlet
|
// survived gauntlet
|
||||||
$ok = true;
|
$ok = true;
|
||||||
|
|
||||||
@@ -59,18 +68,7 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
if (!$ok) return false;
|
if (!$ok) return false;
|
||||||
|
|
||||||
// back to string
|
// back to string
|
||||||
$result = $uri->toString();
|
return $uri->toString();
|
||||||
|
|
||||||
// munge entire URI if necessary
|
|
||||||
if (
|
|
||||||
!is_null($uri->host) && // indicator for authority
|
|
||||||
!empty($scheme_obj->browsable) &&
|
|
||||||
!is_null($munge = $config->get('URI', 'Munge'))
|
|
||||||
) {
|
|
||||||
$result = str_replace('%s', rawurlencode($result), $munge);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
library/HTMLPurifier/AttrTransform/Background.php
Normal file
22
library/HTMLPurifier/AttrTransform/Background.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-transform that changes proprietary background attribute to CSS.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_AttrTransform_Background extends HTMLPurifier_AttrTransform {
|
||||||
|
|
||||||
|
public function transform($attr, $config, $context) {
|
||||||
|
|
||||||
|
if (!isset($attr['background'])) return $attr;
|
||||||
|
|
||||||
|
$background = $this->confiscateAttr($attr, 'background');
|
||||||
|
// some validation should happen here
|
||||||
|
|
||||||
|
$this->prependCSS($attr, "background-image:url($background);");
|
||||||
|
|
||||||
|
return $attr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@@ -22,7 +22,12 @@ class HTMLPurifier_AttrTransform_ImgRequired extends HTMLPurifier_AttrTransform
|
|||||||
|
|
||||||
if (!isset($attr['alt'])) {
|
if (!isset($attr['alt'])) {
|
||||||
if ($src) {
|
if ($src) {
|
||||||
$attr['alt'] = basename($attr['src']);
|
$alt = $config->get('Attr', 'DefaultImageAlt');
|
||||||
|
if ($alt === null) {
|
||||||
|
$attr['alt'] = basename($attr['src']);
|
||||||
|
} else {
|
||||||
|
$attr['alt'] = $alt;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$attr['alt'] = $config->get('Attr', 'DefaultInvalidImageAlt');
|
$attr['alt'] = $config->get('Attr', 'DefaultInvalidImageAlt');
|
||||||
}
|
}
|
||||||
|
39
library/HTMLPurifier/AttrTransform/Input.php
Normal file
39
library/HTMLPurifier/AttrTransform/Input.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs miscellaneous cross attribute validation and filtering for
|
||||||
|
* input elements. This is meant to be a post-transform.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_AttrTransform_Input extends HTMLPurifier_AttrTransform {
|
||||||
|
|
||||||
|
protected $pixels;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->pixels = new HTMLPurifier_AttrDef_HTML_Pixels();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function transform($attr, $config, $context) {
|
||||||
|
if (!isset($attr['type'])) $t = 'text';
|
||||||
|
else $t = strtolower($attr['type']);
|
||||||
|
if (isset($attr['checked']) && $t !== 'radio' && $t !== 'checkbox') {
|
||||||
|
unset($attr['checked']);
|
||||||
|
}
|
||||||
|
if (isset($attr['maxlength']) && $t !== 'text' && $t !== 'password') {
|
||||||
|
unset($attr['maxlength']);
|
||||||
|
}
|
||||||
|
if (isset($attr['size']) && $t !== 'text' && $t !== 'password') {
|
||||||
|
$result = $this->pixels->validate($attr['size'], $config, $context);
|
||||||
|
if ($result === false) unset($attr['size']);
|
||||||
|
else $attr['size'] = $result;
|
||||||
|
}
|
||||||
|
if (isset($attr['src']) && $t !== 'image') {
|
||||||
|
unset($attr['src']);
|
||||||
|
}
|
||||||
|
if (!isset($attr['value']) && ($t === 'radio' || $t === 'checkbox')) {
|
||||||
|
$attr['value'] = '';
|
||||||
|
}
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
13
library/HTMLPurifier/AttrTransform/SafeEmbed.php
Normal file
13
library/HTMLPurifier/AttrTransform/SafeEmbed.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class HTMLPurifier_AttrTransform_SafeEmbed extends HTMLPurifier_AttrTransform
|
||||||
|
{
|
||||||
|
public $name = "SafeEmbed";
|
||||||
|
|
||||||
|
public function transform($attr, $config, $context) {
|
||||||
|
$attr['allowscriptaccess'] = 'never';
|
||||||
|
$attr['allownetworking'] = 'internal';
|
||||||
|
$attr['type'] = 'application/x-shockwave-flash';
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
|
}
|
14
library/HTMLPurifier/AttrTransform/SafeObject.php
Normal file
14
library/HTMLPurifier/AttrTransform/SafeObject.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes default type for all objects. Currently only supports flash.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_AttrTransform_SafeObject extends HTMLPurifier_AttrTransform
|
||||||
|
{
|
||||||
|
public $name = "SafeObject";
|
||||||
|
|
||||||
|
function transform($attr, $config, $context) {
|
||||||
|
if (!isset($attr['type'])) $attr['type'] = 'application/x-shockwave-flash';
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
|
}
|
48
library/HTMLPurifier/AttrTransform/SafeParam.php
Normal file
48
library/HTMLPurifier/AttrTransform/SafeParam.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates name/value pairs in param tags to be used in safe objects. This
|
||||||
|
* will only allow name values it recognizes, and pre-fill certain attributes
|
||||||
|
* with required values.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* This class only supports Flash. In the future, Quicktime support
|
||||||
|
* may be added.
|
||||||
|
*
|
||||||
|
* @warning
|
||||||
|
* This class expects an injector to add the necessary parameters tags.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform
|
||||||
|
{
|
||||||
|
public $name = "SafeParam";
|
||||||
|
private $uri;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded
|
||||||
|
}
|
||||||
|
|
||||||
|
public function transform($attr, $config, $context) {
|
||||||
|
// If we add support for other objects, we'll need to alter the
|
||||||
|
// transforms.
|
||||||
|
switch ($attr['name']) {
|
||||||
|
// application/x-shockwave-flash
|
||||||
|
// Keep this synchronized with Injector/SafeObject.php
|
||||||
|
case 'allowScriptAccess':
|
||||||
|
$attr['value'] = 'never';
|
||||||
|
break;
|
||||||
|
case 'allowNetworking':
|
||||||
|
$attr['value'] = 'internal';
|
||||||
|
break;
|
||||||
|
case 'wmode':
|
||||||
|
$attr['value'] = 'window';
|
||||||
|
break;
|
||||||
|
case 'movie':
|
||||||
|
$attr['value'] = $this->uri->validate($attr['value'], $config, $context);
|
||||||
|
break;
|
||||||
|
// add other cases to support other param name/value pairs
|
||||||
|
default:
|
||||||
|
$attr['name'] = $attr['value'] = null;
|
||||||
|
}
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
|
}
|
16
library/HTMLPurifier/AttrTransform/Textarea.php
Normal file
16
library/HTMLPurifier/AttrTransform/Textarea.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets height/width defaults for <textarea>
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_AttrTransform_Textarea extends HTMLPurifier_AttrTransform
|
||||||
|
{
|
||||||
|
|
||||||
|
public function transform($attr, $config, $context) {
|
||||||
|
// Calculated from Firefox
|
||||||
|
if (!isset($attr['cols'])) $attr['cols'] = '22';
|
||||||
|
if (!isset($attr['rows'])) $attr['rows'] = '3';
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -32,6 +32,9 @@ class HTMLPurifier_AttrTypes
|
|||||||
|
|
||||||
// unimplemented aliases
|
// unimplemented aliases
|
||||||
$this->info['ContentType'] = new HTMLPurifier_AttrDef_Text();
|
$this->info['ContentType'] = new HTMLPurifier_AttrDef_Text();
|
||||||
|
$this->info['ContentTypes'] = new HTMLPurifier_AttrDef_Text();
|
||||||
|
$this->info['Charsets'] = new HTMLPurifier_AttrDef_Text();
|
||||||
|
$this->info['Character'] = new HTMLPurifier_AttrDef_Text();
|
||||||
|
|
||||||
// number is really a positive integer (one or more digits)
|
// number is really a positive integer (one or more digits)
|
||||||
// FIXME: ^^ not always, see start and value of list items
|
// FIXME: ^^ not always, see start and value of list items
|
||||||
|
@@ -35,29 +35,33 @@ class HTMLPurifier_AttrValidator
|
|||||||
if (!$current_token) $context->register('CurrentToken', $token);
|
if (!$current_token) $context->register('CurrentToken', $token);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!$token instanceof HTMLPurifier_Token_Start &&
|
!$token instanceof HTMLPurifier_Token_Start &&
|
||||||
!$token instanceof HTMLPurifier_Token_Empty
|
!$token instanceof HTMLPurifier_Token_Empty
|
||||||
) return $token;
|
) return $token;
|
||||||
|
|
||||||
// create alias to global definition array, see also $defs
|
// create alias to global definition array, see also $defs
|
||||||
// DEFINITION CALL
|
// DEFINITION CALL
|
||||||
$d_defs = $definition->info_global_attr;
|
$d_defs = $definition->info_global_attr;
|
||||||
|
|
||||||
// reference attributes for easy manipulation
|
// don't update token until the very end, to ensure an atomic update
|
||||||
$attr =& $token->attr;
|
$attr = $token->attr;
|
||||||
|
|
||||||
// do global transformations (pre)
|
// do global transformations (pre)
|
||||||
// nothing currently utilizes this
|
// nothing currently utilizes this
|
||||||
foreach ($definition->info_attr_transform_pre as $transform) {
|
foreach ($definition->info_attr_transform_pre as $transform) {
|
||||||
$attr = $transform->transform($o = $attr, $config, $context);
|
$attr = $transform->transform($o = $attr, $config, $context);
|
||||||
if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
|
if ($e) {
|
||||||
|
if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do local transformations only applicable to this element (pre)
|
// do local transformations only applicable to this element (pre)
|
||||||
// ex. <p align="right"> to <p style="text-align:right;">
|
// ex. <p align="right"> to <p style="text-align:right;">
|
||||||
foreach ($definition->info[$token->name]->attr_transform_pre as $transform) {
|
foreach ($definition->info[$token->name]->attr_transform_pre as $transform) {
|
||||||
$attr = $transform->transform($o = $attr, $config, $context);
|
$attr = $transform->transform($o = $attr, $config, $context);
|
||||||
if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
|
if ($e) {
|
||||||
|
if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create alias to this element's attribute definition array, see
|
// create alias to this element's attribute definition array, see
|
||||||
@@ -114,6 +118,8 @@ class HTMLPurifier_AttrValidator
|
|||||||
|
|
||||||
// simple substitution
|
// simple substitution
|
||||||
$attr[$attr_key] = $result;
|
$attr[$attr_key] = $result;
|
||||||
|
} else {
|
||||||
|
// nothing happens
|
||||||
}
|
}
|
||||||
|
|
||||||
// we'd also want slightly more complicated substitution
|
// we'd also want slightly more complicated substitution
|
||||||
@@ -130,15 +136,21 @@ class HTMLPurifier_AttrValidator
|
|||||||
// global (error reporting untested)
|
// global (error reporting untested)
|
||||||
foreach ($definition->info_attr_transform_post as $transform) {
|
foreach ($definition->info_attr_transform_post as $transform) {
|
||||||
$attr = $transform->transform($o = $attr, $config, $context);
|
$attr = $transform->transform($o = $attr, $config, $context);
|
||||||
if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
|
if ($e) {
|
||||||
|
if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// local (error reporting untested)
|
// local (error reporting untested)
|
||||||
foreach ($definition->info[$token->name]->attr_transform_post as $transform) {
|
foreach ($definition->info[$token->name]->attr_transform_post as $transform) {
|
||||||
$attr = $transform->transform($o = $attr, $config, $context);
|
$attr = $transform->transform($o = $attr, $config, $context);
|
||||||
if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
|
if ($e) {
|
||||||
|
if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$token->attr = $attr;
|
||||||
|
|
||||||
// destroy CurrentToken if we made it ourselves
|
// destroy CurrentToken if we made it ourselves
|
||||||
if (!$current_token) $context->destroy('CurrentToken');
|
if (!$current_token) $context->destroy('CurrentToken');
|
||||||
|
|
||||||
|
@@ -90,7 +90,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
|||||||
$this->info['border-left-width'] =
|
$this->info['border-left-width'] =
|
||||||
$this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
$this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||||
new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')),
|
new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')),
|
||||||
new HTMLPurifier_AttrDef_CSS_Length(true) //disallow negative
|
new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width);
|
$this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width);
|
||||||
@@ -116,7 +116,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
|||||||
$this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
$this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||||
new HTMLPurifier_AttrDef_Enum(array('normal')),
|
new HTMLPurifier_AttrDef_Enum(array('normal')),
|
||||||
new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives
|
new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives
|
||||||
new HTMLPurifier_AttrDef_CSS_Length(true),
|
new HTMLPurifier_AttrDef_CSS_Length('0'),
|
||||||
new HTMLPurifier_AttrDef_CSS_Percentage(true)
|
new HTMLPurifier_AttrDef_CSS_Percentage(true)
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
|||||||
$this->info['padding-bottom'] =
|
$this->info['padding-bottom'] =
|
||||||
$this->info['padding-left'] =
|
$this->info['padding-left'] =
|
||||||
$this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
$this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||||
new HTMLPurifier_AttrDef_CSS_Length(true),
|
new HTMLPurifier_AttrDef_CSS_Length('0'),
|
||||||
new HTMLPurifier_AttrDef_CSS_Percentage(true)
|
new HTMLPurifier_AttrDef_CSS_Percentage(true)
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -149,14 +149,26 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
|||||||
new HTMLPurifier_AttrDef_CSS_Percentage()
|
new HTMLPurifier_AttrDef_CSS_Percentage()
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->info['width'] =
|
$trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||||
$this->info['height'] =
|
new HTMLPurifier_AttrDef_CSS_Length('0'),
|
||||||
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_CSS_Percentage(true),
|
||||||
new HTMLPurifier_AttrDef_Enum(array('auto'))
|
new HTMLPurifier_AttrDef_Enum(array('auto'))
|
||||||
)), 'img');
|
));
|
||||||
|
$max = $config->get('CSS', 'MaxImgLength');
|
||||||
|
|
||||||
|
$this->info['width'] =
|
||||||
|
$this->info['height'] =
|
||||||
|
$max === null ?
|
||||||
|
$trusted_wh :
|
||||||
|
new HTMLPurifier_AttrDef_Switch('img',
|
||||||
|
// For img tags:
|
||||||
|
new HTMLPurifier_AttrDef_CSS_Composite(array(
|
||||||
|
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
|
||||||
|
new HTMLPurifier_AttrDef_Enum(array('auto'))
|
||||||
|
)),
|
||||||
|
// For everyone else:
|
||||||
|
$trusted_wh
|
||||||
|
);
|
||||||
|
|
||||||
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
|
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
|
||||||
|
|
||||||
|
@@ -24,6 +24,14 @@ abstract class HTMLPurifier_ChildDef
|
|||||||
*/
|
*/
|
||||||
public $elements = array();
|
public $elements = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get lookup of tag names that should not close this element automatically.
|
||||||
|
* All other elements will do so.
|
||||||
|
*/
|
||||||
|
public function getNonAutoCloseElements($config) {
|
||||||
|
return $this->elements;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates nodes according to definition and returns modification.
|
* Validates nodes according to definition and returns modification.
|
||||||
*
|
*
|
||||||
|
@@ -5,8 +5,6 @@
|
|||||||
*
|
*
|
||||||
* @warning Currently this class is an all or nothing proposition, that is,
|
* @warning Currently this class is an all or nothing proposition, that is,
|
||||||
* it will only give a bool return value.
|
* it will only give a bool return value.
|
||||||
* @note This class is currently not used by any code, although it is unit
|
|
||||||
* tested.
|
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef
|
class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef
|
||||||
{
|
{
|
||||||
|
@@ -55,10 +55,7 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
|||||||
$escape_invalid_children = $config->get('Core', 'EscapeInvalidChildren');
|
$escape_invalid_children = $config->get('Core', 'EscapeInvalidChildren');
|
||||||
|
|
||||||
// generator
|
// generator
|
||||||
static $gen = null;
|
$gen = new HTMLPurifier_Generator($config, $context);
|
||||||
if ($gen === null) {
|
|
||||||
$gen = new HTMLPurifier_Generator();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($tokens_of_children as $token) {
|
foreach ($tokens_of_children as $token) {
|
||||||
if (!empty($token->is_whitespace)) {
|
if (!empty($token->is_whitespace)) {
|
||||||
@@ -83,7 +80,7 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
|||||||
$result[] = $token;
|
$result[] = $token;
|
||||||
} elseif ($pcdata_allowed && $escape_invalid_children) {
|
} elseif ($pcdata_allowed && $escape_invalid_children) {
|
||||||
$result[] = new HTMLPurifier_Token_Text(
|
$result[] = new HTMLPurifier_Token_Text(
|
||||||
$gen->generateFromToken($token, $config)
|
$gen->generateFromToken($token)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -94,7 +91,7 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
|||||||
} elseif ($pcdata_allowed && $escape_invalid_children) {
|
} elseif ($pcdata_allowed && $escape_invalid_children) {
|
||||||
$result[] =
|
$result[] =
|
||||||
new HTMLPurifier_Token_Text(
|
new HTMLPurifier_Token_Text(
|
||||||
$gen->generateFromToken( $token, $config )
|
$gen->generateFromToken($token)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// drop silently
|
// drop silently
|
||||||
|
@@ -10,16 +10,19 @@ class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Requi
|
|||||||
public $allow_empty = true;
|
public $allow_empty = true;
|
||||||
public $type = 'strictblockquote';
|
public $type = 'strictblockquote';
|
||||||
protected $init = false;
|
protected $init = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @note We don't want MakeWellFormed to auto-close inline elements since
|
||||||
|
* they might be allowed.
|
||||||
|
*/
|
||||||
|
public function getNonAutoCloseElements($config) {
|
||||||
|
$this->init($config);
|
||||||
|
return $this->fake_elements;
|
||||||
|
}
|
||||||
|
|
||||||
public function validateChildren($tokens_of_children, $config, $context) {
|
public function validateChildren($tokens_of_children, $config, $context) {
|
||||||
|
|
||||||
$def = $config->getHTMLDefinition();
|
$this->init($config);
|
||||||
if (!$this->init) {
|
|
||||||
// allow all inline elements
|
|
||||||
$this->real_elements = $this->elements;
|
|
||||||
$this->fake_elements = $def->info_content_sets['Flow'];
|
|
||||||
$this->fake_elements['#PCDATA'] = true;
|
|
||||||
$this->init = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trick the parent class into thinking it allows more
|
// trick the parent class into thinking it allows more
|
||||||
$this->elements = $this->fake_elements;
|
$this->elements = $this->fake_elements;
|
||||||
@@ -29,6 +32,7 @@ class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Requi
|
|||||||
if ($result === false) return array();
|
if ($result === false) return array();
|
||||||
if ($result === true) $result = $tokens_of_children;
|
if ($result === true) $result = $tokens_of_children;
|
||||||
|
|
||||||
|
$def = $config->getHTMLDefinition();
|
||||||
$block_wrap_start = new HTMLPurifier_Token_Start($def->info_block_wrapper);
|
$block_wrap_start = new HTMLPurifier_Token_Start($def->info_block_wrapper);
|
||||||
$block_wrap_end = new HTMLPurifier_Token_End( $def->info_block_wrapper);
|
$block_wrap_end = new HTMLPurifier_Token_End( $def->info_block_wrapper);
|
||||||
$is_inline = false;
|
$is_inline = false;
|
||||||
@@ -68,5 +72,16 @@ class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Requi
|
|||||||
if ($is_inline) $ret[] = $block_wrap_end;
|
if ($is_inline) $ret[] = $block_wrap_end;
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function init($config) {
|
||||||
|
if (!$this->init) {
|
||||||
|
$def = $config->getHTMLDefinition();
|
||||||
|
// allow all inline elements
|
||||||
|
$this->real_elements = $this->elements;
|
||||||
|
$this->fake_elements = $def->info_content_sets['Flow'];
|
||||||
|
$this->fake_elements['#PCDATA'] = true;
|
||||||
|
$this->init = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ class HTMLPurifier_Config
|
|||||||
/**
|
/**
|
||||||
* HTML Purifier's version
|
* HTML Purifier's version
|
||||||
*/
|
*/
|
||||||
public $version = '3.1.0';
|
public $version = '3.2.0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bool indicator whether or not to automatically finalize
|
* Bool indicator whether or not to automatically finalize
|
||||||
@@ -125,7 +125,7 @@ class HTMLPurifier_Config
|
|||||||
E_USER_WARNING);
|
E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($this->def->info[$namespace][$key]->class == 'alias') {
|
if (isset($this->def->info[$namespace][$key]->isAlias)) {
|
||||||
$d = $this->def->info[$namespace][$key];
|
$d = $this->def->info[$namespace][$key];
|
||||||
trigger_error('Cannot get value from aliased directive, use real name ' . $d->namespace . '.' . $d->name,
|
trigger_error('Cannot get value from aliased directive, use real name ' . $d->namespace . '.' . $d->name,
|
||||||
E_USER_ERROR);
|
E_USER_ERROR);
|
||||||
@@ -196,40 +196,48 @@ class HTMLPurifier_Config
|
|||||||
E_USER_WARNING);
|
E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($this->def->info[$namespace][$key]->class == 'alias') {
|
$def = $this->def->info[$namespace][$key];
|
||||||
|
|
||||||
|
if (isset($def->isAlias)) {
|
||||||
if ($from_alias) {
|
if ($from_alias) {
|
||||||
trigger_error('Double-aliases not allowed, please fix '.
|
trigger_error('Double-aliases not allowed, please fix '.
|
||||||
'ConfigSchema bug with' . "$namespace.$key", E_USER_ERROR);
|
'ConfigSchema bug with' . "$namespace.$key", E_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->set($new_ns = $this->def->info[$namespace][$key]->namespace,
|
$this->set($new_ns = $def->namespace,
|
||||||
$new_dir = $this->def->info[$namespace][$key]->name,
|
$new_dir = $def->name,
|
||||||
$value, true);
|
$value, true);
|
||||||
trigger_error("$namespace.$key is an alias, preferred directive name is $new_ns.$new_dir", E_USER_NOTICE);
|
trigger_error("$namespace.$key is an alias, preferred directive name is $new_ns.$new_dir", E_USER_NOTICE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Raw type might be negative when using the fully optimized form
|
||||||
|
// of stdclass, which indicates allow_null == true
|
||||||
|
$rtype = is_int($def) ? $def : $def->type;
|
||||||
|
if ($rtype < 0) {
|
||||||
|
$type = -$rtype;
|
||||||
|
$allow_null = true;
|
||||||
|
} else {
|
||||||
|
$type = $rtype;
|
||||||
|
$allow_null = isset($def->allow_null);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$value = $this->parser->parse(
|
$value = $this->parser->parse($value, $type, $allow_null);
|
||||||
$value,
|
|
||||||
$type = $this->def->info[$namespace][$key]->type,
|
|
||||||
$this->def->info[$namespace][$key]->allow_null
|
|
||||||
);
|
|
||||||
} catch (HTMLPurifier_VarParserException $e) {
|
} catch (HTMLPurifier_VarParserException $e) {
|
||||||
trigger_error('Value for ' . "$namespace.$key" . ' is of invalid type, should be ' . $type, E_USER_WARNING);
|
trigger_error('Value for ' . "$namespace.$key" . ' is of invalid type, should be ' . HTMLPurifier_VarParser::getTypeName($type), E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (is_string($value)) {
|
if (is_string($value) && is_object($def)) {
|
||||||
// resolve value alias if defined
|
// resolve value alias if defined
|
||||||
if (isset($this->def->info[$namespace][$key]->aliases[$value])) {
|
if (isset($def->aliases[$value])) {
|
||||||
$value = $this->def->info[$namespace][$key]->aliases[$value];
|
$value = $def->aliases[$value];
|
||||||
}
|
}
|
||||||
if ($this->def->info[$namespace][$key]->allowed !== true) {
|
// check to see if the value is allowed
|
||||||
// check to see if the value is allowed
|
if (isset($def->allowed) && !isset($def->allowed[$value])) {
|
||||||
if (!isset($this->def->info[$namespace][$key]->allowed[$value])) {
|
trigger_error('Value not supported, valid values are: ' .
|
||||||
trigger_error('Value not supported, valid values are: ' .
|
$this->_listify($def->allowed), E_USER_WARNING);
|
||||||
$this->_listify($this->def->info[$namespace][$key]->allowed), E_USER_WARNING);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->conf[$namespace][$key] = $value;
|
$this->conf[$namespace][$key] = $value;
|
||||||
@@ -386,7 +394,7 @@ class HTMLPurifier_Config
|
|||||||
if (isset($blacklisted_directives["$ns.$directive"])) continue;
|
if (isset($blacklisted_directives["$ns.$directive"])) continue;
|
||||||
if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue;
|
if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue;
|
||||||
}
|
}
|
||||||
if ($def->class == 'alias') continue;
|
if (isset($def->isAlias)) continue;
|
||||||
if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue;
|
if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue;
|
||||||
$ret[] = array($ns, $directive);
|
$ret[] = array($ns, $directive);
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for configuration entity
|
|
||||||
*/
|
|
||||||
abstract class HTMLPurifier_ConfigDef {
|
|
||||||
public $class = false;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Structure object containing definition of a directive.
|
|
||||||
* @note This structure does not contain default values
|
|
||||||
*/
|
|
||||||
class HTMLPurifier_ConfigDef_Directive extends HTMLPurifier_ConfigDef
|
|
||||||
{
|
|
||||||
|
|
||||||
public $class = 'directive';
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
$type = null,
|
|
||||||
$allow_null = null,
|
|
||||||
$allowed = null,
|
|
||||||
$aliases = null
|
|
||||||
) {
|
|
||||||
if ( $type !== null) $this->type = $type;
|
|
||||||
if ( $allow_null !== null) $this->allow_null = $allow_null;
|
|
||||||
if ( $allowed !== null) $this->allowed = $allowed;
|
|
||||||
if ( $aliases !== null) $this->aliases = $aliases;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allowed type of the directive. Values are:
|
|
||||||
* - string
|
|
||||||
* - istring (case insensitive string)
|
|
||||||
* - int
|
|
||||||
* - float
|
|
||||||
* - bool
|
|
||||||
* - lookup (array of value => true)
|
|
||||||
* - list (regular numbered index array)
|
|
||||||
* - hash (array of key => value)
|
|
||||||
* - mixed (anything goes)
|
|
||||||
*/
|
|
||||||
public $type = 'mixed';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is null allowed? Has no effect for mixed type.
|
|
||||||
* @bool
|
|
||||||
*/
|
|
||||||
public $allow_null = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lookup table of allowed values of the element, bool true if all allowed.
|
|
||||||
*/
|
|
||||||
public $allowed = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hash of value aliases, i.e. values that are equivalent.
|
|
||||||
*/
|
|
||||||
public $aliases = array();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@@ -1,24 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Structure object describing a directive alias
|
|
||||||
*/
|
|
||||||
class HTMLPurifier_ConfigDef_DirectiveAlias extends HTMLPurifier_ConfigDef
|
|
||||||
{
|
|
||||||
public $class = 'alias';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Namespace being aliased to
|
|
||||||
*/
|
|
||||||
public $namespace;
|
|
||||||
/**
|
|
||||||
* Directive being aliased to
|
|
||||||
*/
|
|
||||||
public $name;
|
|
||||||
|
|
||||||
public function __construct($namespace, $name) {
|
|
||||||
$this->namespace = $namespace;
|
|
||||||
$this->name = $name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Structure object describing of a namespace
|
|
||||||
*/
|
|
||||||
class HTMLPurifier_ConfigDef_Namespace extends HTMLPurifier_ConfigDef
|
|
||||||
{
|
|
||||||
public $class = 'namespace';
|
|
||||||
}
|
|
||||||
|
|
@@ -12,7 +12,33 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
public $defaults = array();
|
public $defaults = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of the directives.
|
* Definition of the directives. The structure of this is:
|
||||||
|
*
|
||||||
|
* array(
|
||||||
|
* 'Namespace' => array(
|
||||||
|
* 'Directive' => new stdclass(),
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* The stdclass may have the following properties:
|
||||||
|
*
|
||||||
|
* - If isAlias isn't set:
|
||||||
|
* - type: Integer type of directive, see HTMLPurifier_VarParser for definitions
|
||||||
|
* - allow_null: If set, this directive allows null values
|
||||||
|
* - aliases: If set, an associative array of value aliases to real values
|
||||||
|
* - allowed: If set, a lookup array of allowed (string) values
|
||||||
|
* - If isAlias is set:
|
||||||
|
* - namespace: Namespace this directive aliases to
|
||||||
|
* - name: Directive name this directive aliases to
|
||||||
|
*
|
||||||
|
* In certain degenerate cases, stdclass will actually be an integer. In
|
||||||
|
* that case, the value is equivalent to an stdclass with the type
|
||||||
|
* property set to the integer. If the integer is negative, type is
|
||||||
|
* equal to the absolute value of integer, and allow_null is true.
|
||||||
|
*
|
||||||
|
* This class is friendly with HTMLPurifier_Config. If you need introspection
|
||||||
|
* about the schema, you're better of using the ConfigSchema_Interchange,
|
||||||
|
* which uses more memory but has much richer information.
|
||||||
*/
|
*/
|
||||||
public $info = array();
|
public $info = array();
|
||||||
|
|
||||||
@@ -21,15 +47,6 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
*/
|
*/
|
||||||
static protected $singleton;
|
static protected $singleton;
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable parser.
|
|
||||||
*/
|
|
||||||
protected $parser;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->parser = new HTMLPurifier_VarParser_Flexible();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unserializes the default ConfigSchema.
|
* Unserializes the default ConfigSchema.
|
||||||
*/
|
*/
|
||||||
@@ -62,11 +79,11 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
* @param $allow_null Whether or not to allow null values
|
* @param $allow_null Whether or not to allow null values
|
||||||
*/
|
*/
|
||||||
public function add($namespace, $name, $default, $type, $allow_null) {
|
public function add($namespace, $name, $default, $type, $allow_null) {
|
||||||
$default = $this->parser->parse($default, $type, $allow_null);
|
$obj = new stdclass();
|
||||||
$this->info[$namespace][$name] = new HTMLPurifier_ConfigDef_Directive();
|
$obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type];
|
||||||
$this->info[$namespace][$name]->type = $type;
|
if ($allow_null) $obj->allow_null = true;
|
||||||
$this->info[$namespace][$name]->allow_null = $allow_null;
|
$this->info[$namespace][$name] = $obj;
|
||||||
$this->defaults[$namespace][$name] = $default;
|
$this->defaults[$namespace][$name] = $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,6 +107,9 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
* @param $aliases Hash of aliased values to the real alias
|
* @param $aliases Hash of aliased values to the real alias
|
||||||
*/
|
*/
|
||||||
public function addValueAliases($namespace, $name, $aliases) {
|
public function addValueAliases($namespace, $name, $aliases) {
|
||||||
|
if (!isset($this->info[$namespace][$name]->aliases)) {
|
||||||
|
$this->info[$namespace][$name]->aliases = array();
|
||||||
|
}
|
||||||
foreach ($aliases as $alias => $real) {
|
foreach ($aliases as $alias => $real) {
|
||||||
$this->info[$namespace][$name]->aliases[$alias] = $real;
|
$this->info[$namespace][$name]->aliases[$alias] = $real;
|
||||||
}
|
}
|
||||||
@@ -104,7 +124,6 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
* @param $allowed Lookup array of allowed values
|
* @param $allowed Lookup array of allowed values
|
||||||
*/
|
*/
|
||||||
public function addAllowedValues($namespace, $name, $allowed) {
|
public function addAllowedValues($namespace, $name, $allowed) {
|
||||||
$type = $this->info[$namespace][$name]->type;
|
|
||||||
$this->info[$namespace][$name]->allowed = $allowed;
|
$this->info[$namespace][$name]->allowed = $allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +135,26 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
* @param $new_name Directive that the alias will be to
|
* @param $new_name Directive that the alias will be to
|
||||||
*/
|
*/
|
||||||
public function addAlias($namespace, $name, $new_namespace, $new_name) {
|
public function addAlias($namespace, $name, $new_namespace, $new_name) {
|
||||||
$this->info[$namespace][$name] = new HTMLPurifier_ConfigDef_DirectiveAlias($new_namespace, $new_name);
|
$obj = new stdclass;
|
||||||
|
$obj->namespace = $new_namespace;
|
||||||
|
$obj->name = $new_name;
|
||||||
|
$obj->isAlias = true;
|
||||||
|
$this->info[$namespace][$name] = $obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces any stdclass that only has the type property with type integer.
|
||||||
|
*/
|
||||||
|
public function postProcess() {
|
||||||
|
foreach ($this->info as $namespace => $info) {
|
||||||
|
foreach ($info as $directive => $v) {
|
||||||
|
if (count((array) $v) == 1) {
|
||||||
|
$this->info[$namespace][$directive] = $v->type;
|
||||||
|
} elseif (count((array) $v) == 2 && isset($v->allow_null)) {
|
||||||
|
$this->info[$namespace][$directive] = -$v->type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEPRECATED METHODS
|
// DEPRECATED METHODS
|
||||||
@@ -124,7 +162,6 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
/** @see HTMLPurifier_ConfigSchema->set() */
|
/** @see HTMLPurifier_ConfigSchema->set() */
|
||||||
public static function define($namespace, $name, $default, $type, $description) {
|
public static function define($namespace, $name, $default, $type, $description) {
|
||||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||||
// process modifiers (OPTIMIZE!)
|
|
||||||
$type_values = explode('/', $type, 2);
|
$type_values = explode('/', $type, 2);
|
||||||
$type = $type_values[0];
|
$type = $type_values[0];
|
||||||
$modifier = isset($type_values[1]) ? $type_values[1] : false;
|
$modifier = isset($type_values[1]) ? $type_values[1] : false;
|
||||||
@@ -168,7 +205,8 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
/** @deprecated, use HTMLPurifier_VarParser->parse() */
|
/** @deprecated, use HTMLPurifier_VarParser->parse() */
|
||||||
public function validate($a, $b, $c = false) {
|
public function validate($a, $b, $c = false) {
|
||||||
trigger_error("HTMLPurifier_ConfigSchema->validate deprecated, use HTMLPurifier_VarParser->parse instead", E_USER_NOTICE);
|
trigger_error("HTMLPurifier_ConfigSchema->validate deprecated, use HTMLPurifier_VarParser->parse instead", E_USER_NOTICE);
|
||||||
return $this->parser->parse($a, $b, $c);
|
$parser = new HTMLPurifier_VarParser();
|
||||||
|
return $parser->parse($a, $b, $c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -43,6 +43,7 @@ class HTMLPurifier_ConfigSchema_Builder_ConfigSchema
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$schema->postProcess();
|
||||||
return $schema;
|
return $schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -111,7 +111,8 @@ class HTMLPurifier_ConfigSchema_Validator
|
|||||||
if (!is_null($d->allowed) || !empty($d->valueAliases)) {
|
if (!is_null($d->allowed) || !empty($d->valueAliases)) {
|
||||||
// allowed and valueAliases require that we be dealing with
|
// allowed and valueAliases require that we be dealing with
|
||||||
// strings, so check for that early.
|
// strings, so check for that early.
|
||||||
if (!isset(HTMLPurifier_VarParser::$stringTypes[$d->type])) {
|
$d_int = HTMLPurifier_VarParser::$types[$d->type];
|
||||||
|
if (!isset(HTMLPurifier_VarParser::$stringTypes[$d_int])) {
|
||||||
$this->error('type', 'must be a string type when used with allowed or value aliases');
|
$this->error('type', 'must be a string type when used with allowed or value aliases');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
|
|||||||
|
Attr.DefaultImageAlt
|
||||||
|
TYPE: string/null
|
||||||
|
DEFAULT: null
|
||||||
|
--DESCRIPTION--
|
||||||
|
This is the content of the alt tag of an image if the user had not
|
||||||
|
previously specified an alt attribute. This applies to all images without
|
||||||
|
a valid alt attribute, as opposed to %Attr.DefaultInvalidImageAlt, which
|
||||||
|
only applies to invalid images, and overrides in the case of an invalid image.
|
||||||
|
Default behavior with null is to use the basename of the src tag for the alt.
|
@@ -0,0 +1,10 @@
|
|||||||
|
AutoFormat.DisplayLinkURI
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 3.2.0
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
This directive turns on the in-text display of URIs in <a> tags, and disables
|
||||||
|
those links. For example, <a href="http://example.com">example</a> becomes
|
||||||
|
example (<a>http://example.com</a>).
|
||||||
|
</p>
|
@@ -0,0 +1,44 @@
|
|||||||
|
AutoFormat.RemoveEmpty
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 3.2.0
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
When enabled, HTML Purifier will attempt to remove empty elements that
|
||||||
|
contribute no semantic information to the document. The following types
|
||||||
|
of nodes will be removed:
|
||||||
|
</p>
|
||||||
|
<ul><li>
|
||||||
|
Tags with no attributes and no content, and that are not empty
|
||||||
|
elements (remove <code><a></a></code> but not
|
||||||
|
<code><br /></code>), and
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Tags with no content, except for:<ul>
|
||||||
|
<li>The <code>colgroup</code> element, or</li>
|
||||||
|
<li>
|
||||||
|
Elements with the <code>id</code> or <code>name</code> attribute,
|
||||||
|
when those attributes are permitted on those elements.
|
||||||
|
</li>
|
||||||
|
</ul></li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Please be very careful when using this functionality; while it may not
|
||||||
|
seem that empty elements contain useful information, they can alter the
|
||||||
|
layout of a document given appropriate styling. This directive is most
|
||||||
|
useful when you are processing machine-generated HTML, please avoid using
|
||||||
|
it on regular user HTML.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Elements that contain only whitespace will be treated as empty. Non-breaking
|
||||||
|
spaces, however, do not count as whitespace.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This algorithm is not perfect; you may still notice some empty tags,
|
||||||
|
particularly if a node had elements, but those elements were later removed
|
||||||
|
because they were not permitted in that context, or tags that, after
|
||||||
|
being auto-closed by another tag, where empty. This is for safety reasons
|
||||||
|
to prevent clever code from breaking validation. The general rule of thumb:
|
||||||
|
if a tag looked empty on the way end, it will get removed; if HTML Purifier
|
||||||
|
made it empty, it will stay.
|
||||||
|
</p>
|
@@ -0,0 +1,15 @@
|
|||||||
|
CSS.MaxImgLength
|
||||||
|
TYPE: string/null
|
||||||
|
DEFAULT: '1200px'
|
||||||
|
VERSION: 3.1.1
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
This parameter sets the maximum allowed length on <code>img</code> tags,
|
||||||
|
effectively the <code>width</code> and <code>height</code> properties.
|
||||||
|
Only absolute units of measurement (in, pt, pc, mm, cm) and pixels (px) are allowed. This is
|
||||||
|
in place to prevent imagecrash attacks, disable with null at your own risk.
|
||||||
|
This directive is similar to %HTML.MaxImgLength, and both should be
|
||||||
|
concurrently edited, although there are
|
||||||
|
subtle differences in the input format (the CSS max is a number with
|
||||||
|
a unit).
|
||||||
|
</p>
|
@@ -1,13 +1,17 @@
|
|||||||
Core.AggressivelyFixLt
|
Core.AggressivelyFixLt
|
||||||
TYPE: bool
|
TYPE: bool
|
||||||
VERSION: 2.1.0
|
VERSION: 2.1.0
|
||||||
DEFAULT: false
|
DEFAULT: true
|
||||||
--DESCRIPTION--
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
This directive enables aggressive pre-filter fixes HTML Purifier can
|
This directive enables aggressive pre-filter fixes HTML Purifier can
|
||||||
perform in order to ensure that open angled-brackets do not get killed
|
perform in order to ensure that open angled-brackets do not get killed
|
||||||
during parsing stage. Enabling this will result in two preg_replace_callback
|
during parsing stage. Enabling this will result in two preg_replace_callback
|
||||||
calls and one preg_replace call for every bit of HTML passed through here.
|
calls and at least two preg_replace calls for every HTML document parsed;
|
||||||
It is not necessary and will have no effect for PHP 4.
|
if your users make very well-formed HTML, you can set this directive false.
|
||||||
|
This has no effect when DirectLex is used.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Notice:</strong> This directive's default turned from false to true
|
||||||
|
in HTML Purifier 3.2.0.
|
||||||
|
</p>
|
@@ -14,13 +14,49 @@ EXTERNAL: CSSTidy
|
|||||||
<p>
|
<p>
|
||||||
Sample usage:
|
Sample usage:
|
||||||
</p>
|
</p>
|
||||||
<pre><![CDATA[$config = HTMLPurifier_Config::createDefault();
|
<pre><![CDATA[
|
||||||
$config->set('Filter', 'ExtractStyleBlocks', true);
|
<?php
|
||||||
$purifier = new HTMLPurifier($config);
|
header('Content-type: text/html; charset=utf-8');
|
||||||
$styles = $purifier->context->get('StyleBlocks');
|
echo '<?xml version="1.0" encoding="UTF-8"?>';
|
||||||
foreach ($styles as $style) {
|
?>
|
||||||
echo '<style type="text/css">' . $style . "</style>\n";
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
}]]></pre>
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Filter.ExtractStyleBlocks</title>
|
||||||
|
<?php
|
||||||
|
require_once '/path/to/library/HTMLPurifier.auto.php';
|
||||||
|
require_once '/path/to/csstidy.class.php';
|
||||||
|
|
||||||
|
$dirty = '<style>body {color:#F00;}</style> Some text';
|
||||||
|
|
||||||
|
$config = HTMLPurifier_Config::createDefault();
|
||||||
|
$config->set('Filter', 'ExtractStyleBlocks', true);
|
||||||
|
$purifier = new HTMLPurifier($config);
|
||||||
|
|
||||||
|
$html = $purifier->purify($dirty);
|
||||||
|
|
||||||
|
// This implementation writes the stylesheets to the styles/ directory.
|
||||||
|
// You can also echo the styles inside the document, but it's a bit
|
||||||
|
// more difficult to make sure they get interpreted properly by
|
||||||
|
// browsers; try the usual CSS armoring techniques.
|
||||||
|
$styles = $purifier->context->get('StyleBlocks');
|
||||||
|
$dir = 'styles/';
|
||||||
|
if (!is_dir($dir)) mkdir($dir);
|
||||||
|
$hash = sha1($_GET['html']);
|
||||||
|
foreach ($styles as $i => $style) {
|
||||||
|
file_put_contents($name = $dir . $hash . "_$i");
|
||||||
|
echo '<link rel="stylesheet" type="text/css" href="'.$name.'" />';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<?php echo $html; ?>
|
||||||
|
</div>
|
||||||
|
</b]]><![CDATA[ody>
|
||||||
|
</html>
|
||||||
|
]]></pre>
|
||||||
<p>
|
<p>
|
||||||
<strong>Warning:</strong> It is possible for a user to mount an
|
<strong>Warning:</strong> It is possible for a user to mount an
|
||||||
imagecrash attack using this CSS. Counter-measures are difficult;
|
imagecrash attack using this CSS. Counter-measures are difficult;
|
||||||
|
@@ -0,0 +1,13 @@
|
|||||||
|
HTML.MaxImgLength
|
||||||
|
TYPE: int/null
|
||||||
|
DEFAULT: 1200
|
||||||
|
VERSION: 3.1.1
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
This directive controls the maximum number of pixels in the width and
|
||||||
|
height attributes in <code>img</code> tags. This is
|
||||||
|
in place to prevent imagecrash attacks, disable with null at your own risk.
|
||||||
|
This directive is similar to %CSS.MaxImgLength, and both should be
|
||||||
|
concurrently edited, although there are
|
||||||
|
subtle differences in the input format (the HTML max is an integer).
|
||||||
|
</p>
|
13
library/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt
Normal file
13
library/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
HTML.SafeEmbed
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 3.1.1
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
Whether or not to permit embed tags in documents, with a number of extra
|
||||||
|
security features added to prevent script execution. This is similar to
|
||||||
|
what websites like MySpace do to embed tags. Embed is a proprietary
|
||||||
|
element and will cause your website to stop validating. You probably want
|
||||||
|
to enable this with %HTML.SafeObject.
|
||||||
|
<strong>Highly experimental.</strong>
|
||||||
|
</p>
|
13
library/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt
Normal file
13
library/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
HTML.SafeObject
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 3.1.1
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
Whether or not to permit object tags in documents, with a number of extra
|
||||||
|
security features added to prevent script execution. This is similar to
|
||||||
|
what websites like MySpace do to object tags. You may also want to
|
||||||
|
enable %HTML.SafeEmbed for maximum interoperability with Internet Explorer,
|
||||||
|
although embed tags will cause your website to stop validating.
|
||||||
|
<strong>Highly experimental.</strong>
|
||||||
|
</p>
|
13
library/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt
Normal file
13
library/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Output.SortAttr
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 3.2.0
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
If true, HTML Purifier will sort attributes by name before writing them back
|
||||||
|
to the document, converting a tag like: <code><el b="" a="" c="" /></code>
|
||||||
|
to <code><el a="" b="" c="" /></code>. This is a workaround for
|
||||||
|
a bug in FCKeditor which causes it to swap attributes order, adding noise
|
||||||
|
to text diffs. If you're not seeing this bug, chances are, you don't need
|
||||||
|
this directive.
|
||||||
|
</p>
|
@@ -6,7 +6,7 @@ DEFAULT: NULL
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
Munges all browsable (usually http, https and ftp)
|
Munges all browsable (usually http, https and ftp)
|
||||||
absolute URI's into another URI, usually a URI redirection service.
|
absolute URIs into another URI, usually a URI redirection service.
|
||||||
This directive accepts a URI, formatted with a <code>%s</code> where
|
This directive accepts a URI, formatted with a <code>%s</code> where
|
||||||
the url-encoded original URI should be inserted (sample:
|
the url-encoded original URI should be inserted (sample:
|
||||||
<code>http://www.google.com/url?q=%s</code>).
|
<code>http://www.google.com/url?q=%s</code>).
|
||||||
@@ -19,13 +19,64 @@ DEFAULT: NULL
|
|||||||
Prevent PageRank leaks, while being fairly transparent
|
Prevent PageRank leaks, while being fairly transparent
|
||||||
to users (you may also want to add some client side JavaScript to
|
to users (you may also want to add some client side JavaScript to
|
||||||
override the text in the statusbar). <strong>Notice</strong>:
|
override the text in the statusbar). <strong>Notice</strong>:
|
||||||
Many security experts believe that this form of protection does
|
Many security experts believe that this form of protection does not deter spam-bots.
|
||||||
not deter spam-bots.
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Redirect users to a splash page telling them they are leaving your
|
Redirect users to a splash page telling them they are leaving your
|
||||||
website. While this is poor usability practice, it is often
|
website. While this is poor usability practice, it is often mandated
|
||||||
mandated
|
|
||||||
in corporate environments.
|
in corporate environments.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<p>
|
||||||
|
Prior to HTML Purifier 3.1.1, this directive also enabled the munging
|
||||||
|
of browsable external resources, which could break things if your redirection
|
||||||
|
script was a splash page or used <code>meta</code> tags. To revert to
|
||||||
|
previous behavior, please use %URI.MungeResources.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You may want to also use %URI.MungeSecretKey along with this directive
|
||||||
|
in order to enforce what URIs your redirector script allows. Open
|
||||||
|
redirector scripts can be a security risk and negatively affect the
|
||||||
|
reputation of your domain name.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Starting with HTML Purifier 3.1.1, there is also these substitutions:
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Example <code><a href=""></code></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>%r</td>
|
||||||
|
<td>1 - The URI embeds a resource<br />(blank) - The URI is merely a link</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>%n</td>
|
||||||
|
<td>The name of the tag this URI came from</td>
|
||||||
|
<td>a</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>%m</td>
|
||||||
|
<td>The name of the attribute this URI came from</td>
|
||||||
|
<td>href</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>%p</td>
|
||||||
|
<td>The name of the CSS property this URI came from, or blank if irrelevant</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
Admittedly, these letters are somewhat arbitrary; the only stipulation
|
||||||
|
was that they couldn't be a through f. r is for resource (I would have preferred
|
||||||
|
e, but you take what you can get), n is for name, m
|
||||||
|
was picked because it came after n (and I couldn't use a), p is for
|
||||||
|
property.
|
||||||
|
</p>
|
||||||
|
@@ -0,0 +1,16 @@
|
|||||||
|
URI.MungeResources
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 3.1.1
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
If true, any URI munging directives like %URI.Munge
|
||||||
|
will also apply to embedded resources, such as <code><img src=""></code>.
|
||||||
|
Be careful enabling this directive if you have a redirector script
|
||||||
|
that does not use the <code>Location</code> HTTP header; all of your images
|
||||||
|
and other embedded resources will break.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Warning:</strong> It is strongly advised you use this in conjunction
|
||||||
|
%URI.MungeSecretKey to mitigate the security risk of an open redirector.
|
||||||
|
</p>
|
@@ -0,0 +1,29 @@
|
|||||||
|
URI.MungeSecretKey
|
||||||
|
TYPE: string/null
|
||||||
|
VERSION: 3.1.1
|
||||||
|
DEFAULT: NULL
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
This directive enables secure checksum generation along with %URI.Munge.
|
||||||
|
It should be set to a secure key that is not shared with anyone else.
|
||||||
|
The checksum can be placed in the URI using %t. Use of this checksum
|
||||||
|
affords an additional level of protection by allowing a redirector
|
||||||
|
to check if a URI has passed through HTML Purifier with this line:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>$checksum === sha1($secret_key . ':' . $url)</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If the output is TRUE, the redirector script should accept the URI.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please note that it would still be possible for an attacker to procure
|
||||||
|
secure hashes en-mass by abusing your website's Preview feature or the
|
||||||
|
like, but this service affords an additional level of protection
|
||||||
|
that should be combined with website blacklisting.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Remember this has no effect if %URI.Munge is not on.
|
||||||
|
</p>
|
@@ -37,33 +37,35 @@ class HTMLPurifier_ContentSets
|
|||||||
// sorry, no way of overloading
|
// sorry, no way of overloading
|
||||||
foreach ($modules as $module_i => $module) {
|
foreach ($modules as $module_i => $module) {
|
||||||
foreach ($module->content_sets as $key => $value) {
|
foreach ($module->content_sets as $key => $value) {
|
||||||
if (isset($this->info[$key])) {
|
$temp = $this->convertToLookup($value);
|
||||||
|
if (isset($this->lookup[$key])) {
|
||||||
// add it into the existing content set
|
// add it into the existing content set
|
||||||
$this->info[$key] = $this->info[$key] . ' | ' . $value;
|
$this->lookup[$key] = array_merge($this->lookup[$key], $temp);
|
||||||
} else {
|
} else {
|
||||||
$this->info[$key] = $value;
|
$this->lookup[$key] = $temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// perform content_set expansions
|
$old_lookup = false;
|
||||||
$this->keys = array_keys($this->info);
|
while ($old_lookup !== $this->lookup) {
|
||||||
foreach ($this->info as $i => $set) {
|
$old_lookup = $this->lookup;
|
||||||
// only performed once, so infinite recursion is not
|
foreach ($this->lookup as $i => $set) {
|
||||||
// a problem
|
$add = array();
|
||||||
$this->info[$i] =
|
foreach ($set as $element => $x) {
|
||||||
str_replace(
|
if (isset($this->lookup[$element])) {
|
||||||
$this->keys,
|
$add += $this->lookup[$element];
|
||||||
// must be recalculated each time due to
|
unset($this->lookup[$i][$element]);
|
||||||
// changing substitutions
|
}
|
||||||
array_values($this->info),
|
}
|
||||||
$set);
|
$this->lookup[$i] += $add;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->values = array_values($this->info);
|
|
||||||
|
|
||||||
// generate lookup tables
|
foreach ($this->lookup as $key => $lookup) {
|
||||||
foreach ($this->info as $name => $set) {
|
$this->info[$key] = implode(' | ', array_keys($lookup));
|
||||||
$this->lookup[$name] = $this->convertToLookup($set);
|
|
||||||
}
|
}
|
||||||
|
$this->keys = array_keys($this->info);
|
||||||
|
$this->values = array_values($this->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,12 +77,22 @@ class HTMLPurifier_ContentSets
|
|||||||
if (!empty($def->child)) return; // already done!
|
if (!empty($def->child)) return; // already done!
|
||||||
$content_model = $def->content_model;
|
$content_model = $def->content_model;
|
||||||
if (is_string($content_model)) {
|
if (is_string($content_model)) {
|
||||||
$def->content_model = str_replace(
|
// Assume that $this->keys is alphanumeric
|
||||||
$this->keys, $this->values, $content_model);
|
$def->content_model = preg_replace_callback(
|
||||||
|
'/\b(' . implode('|', $this->keys) . ')\b/',
|
||||||
|
array($this, 'generateChildDefCallback'),
|
||||||
|
$content_model
|
||||||
|
);
|
||||||
|
//$def->content_model = str_replace(
|
||||||
|
// $this->keys, $this->values, $content_model);
|
||||||
}
|
}
|
||||||
$def->child = $this->getChildDef($def, $module);
|
$def->child = $this->getChildDef($def, $module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function generateChildDefCallback($matches) {
|
||||||
|
return $this->info[$matches[0]];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a ChildDef based on content_model and content_model_type
|
* Instantiates a ChildDef based on content_model and content_model_type
|
||||||
* member variables in HTMLPurifier_ElementDef
|
* member variables in HTMLPurifier_ElementDef
|
||||||
|
1
library/HTMLPurifier/DefinitionCache/Serializer/README
Normal file
1
library/HTMLPurifier/DefinitionCache/Serializer/README
Normal file
@@ -0,0 +1 @@
|
|||||||
|
This is a dummy file to prevent Git from ignoring this empty directory.
|
@@ -46,35 +46,13 @@ class HTMLPurifier_Encoder
|
|||||||
*/
|
*/
|
||||||
public static function cleanUTF8($str, $force_php = false) {
|
public static function cleanUTF8($str, $force_php = false) {
|
||||||
|
|
||||||
static $non_sgml_chars = array();
|
|
||||||
if (empty($non_sgml_chars)) {
|
|
||||||
for ($i = 0; $i <= 31; $i++) {
|
|
||||||
// non-SGML ASCII chars
|
|
||||||
// save \r, \t and \n
|
|
||||||
if ($i == 9 || $i == 13 || $i == 10) continue;
|
|
||||||
$non_sgml_chars[chr($i)] = '';
|
|
||||||
}
|
|
||||||
for ($i = 127; $i <= 159; $i++) {
|
|
||||||
$non_sgml_chars[HTMLPurifier_Encoder::unichr($i)] = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static $iconv = null;
|
|
||||||
if ($iconv === null) $iconv = function_exists('iconv');
|
|
||||||
|
|
||||||
// UTF-8 validity is checked since PHP 4.3.5
|
// UTF-8 validity is checked since PHP 4.3.5
|
||||||
// This is an optimization: if the string is already valid UTF-8, no
|
// 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.
|
// need to do PHP stuff. 99% of the time, this will be the case.
|
||||||
if (preg_match('/^.{1}/us', $str)) {
|
// The regexp matches the XML char production, as well as well as excluding
|
||||||
return strtr($str, $non_sgml_chars);
|
// non-SGML codepoints U+007F to U+009F
|
||||||
}
|
if (preg_match('/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du', $str)) {
|
||||||
|
return $str;
|
||||||
if ($iconv && !$force_php) {
|
|
||||||
// do the shortcut way
|
|
||||||
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
|
||||||
$str = iconv('UTF-8', 'UTF-8//IGNORE', $str);
|
|
||||||
restore_error_handler();
|
|
||||||
return strtr($str, $non_sgml_chars);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$mState = 0; // cached expected number of octets after the current octet
|
$mState = 0; // cached expected number of octets after the current octet
|
||||||
@@ -185,7 +163,17 @@ class HTMLPurifier_Encoder
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
} elseif (0xFEFF != $mUcs4 && // omit BOM
|
} elseif (0xFEFF != $mUcs4 && // omit BOM
|
||||||
!($mUcs4 >= 128 && $mUcs4 <= 159) // omit non-SGML
|
// check for valid Char unicode codepoints
|
||||||
|
(
|
||||||
|
0x9 == $mUcs4 ||
|
||||||
|
0xA == $mUcs4 ||
|
||||||
|
0xD == $mUcs4 ||
|
||||||
|
(0x20 <= $mUcs4 && 0x7E >= $mUcs4) ||
|
||||||
|
// 7F-9F is not strictly prohibited by XML,
|
||||||
|
// but it is non-SGML, and thus we don't allow it
|
||||||
|
(0xA0 <= $mUcs4 && 0xD7FF >= $mUcs4) ||
|
||||||
|
(0x10000 <= $mUcs4 && 0x10FFFF >= $mUcs4)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
$out .= $char;
|
$out .= $char;
|
||||||
}
|
}
|
||||||
@@ -276,22 +264,31 @@ class HTMLPurifier_Encoder
|
|||||||
* Converts a string to UTF-8 based on configuration.
|
* Converts a string to UTF-8 based on configuration.
|
||||||
*/
|
*/
|
||||||
public static function convertToUTF8($str, $config, $context) {
|
public static function convertToUTF8($str, $config, $context) {
|
||||||
static $iconv = null;
|
|
||||||
if ($iconv === null) $iconv = function_exists('iconv');
|
|
||||||
$encoding = $config->get('Core', 'Encoding');
|
$encoding = $config->get('Core', 'Encoding');
|
||||||
if ($encoding === 'utf-8') return $str;
|
if ($encoding === 'utf-8') return $str;
|
||||||
|
static $iconv = null;
|
||||||
|
if ($iconv === null) $iconv = function_exists('iconv');
|
||||||
|
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
||||||
if ($iconv && !$config->get('Test', 'ForceNoIconv')) {
|
if ($iconv && !$config->get('Test', 'ForceNoIconv')) {
|
||||||
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
|
||||||
$str = iconv($encoding, 'utf-8//IGNORE', $str);
|
$str = iconv($encoding, 'utf-8//IGNORE', $str);
|
||||||
|
if ($str === false) {
|
||||||
|
// $encoding is not a valid encoding
|
||||||
|
restore_error_handler();
|
||||||
|
trigger_error('Invalid encoding ' . $encoding, E_USER_ERROR);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
// If the string is bjorked by Shift_JIS or a similar encoding
|
||||||
|
// that doesn't support all of ASCII, convert the naughty
|
||||||
|
// characters to their true byte-wise ASCII/UTF-8 equivalents.
|
||||||
|
$str = strtr($str, HTMLPurifier_Encoder::testEncodingSupportsASCII($encoding));
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
return $str;
|
return $str;
|
||||||
} elseif ($encoding === 'iso-8859-1') {
|
} elseif ($encoding === 'iso-8859-1') {
|
||||||
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
|
||||||
$str = utf8_encode($str);
|
$str = utf8_encode($str);
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
trigger_error('Encoding not supported', E_USER_ERROR);
|
trigger_error('Encoding not supported, please install iconv', E_USER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -300,20 +297,28 @@ class HTMLPurifier_Encoder
|
|||||||
* characters being omitted.
|
* characters being omitted.
|
||||||
*/
|
*/
|
||||||
public static function convertFromUTF8($str, $config, $context) {
|
public static function convertFromUTF8($str, $config, $context) {
|
||||||
static $iconv = null;
|
|
||||||
if ($iconv === null) $iconv = function_exists('iconv');
|
|
||||||
$encoding = $config->get('Core', 'Encoding');
|
$encoding = $config->get('Core', 'Encoding');
|
||||||
if ($encoding === 'utf-8') return $str;
|
if ($encoding === 'utf-8') return $str;
|
||||||
if ($config->get('Core', 'EscapeNonASCIICharacters')) {
|
static $iconv = null;
|
||||||
|
if ($iconv === null) $iconv = function_exists('iconv');
|
||||||
|
if ($escape = $config->get('Core', 'EscapeNonASCIICharacters')) {
|
||||||
$str = HTMLPurifier_Encoder::convertToASCIIDumbLossless($str);
|
$str = HTMLPurifier_Encoder::convertToASCIIDumbLossless($str);
|
||||||
}
|
}
|
||||||
|
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
||||||
if ($iconv && !$config->get('Test', 'ForceNoIconv')) {
|
if ($iconv && !$config->get('Test', 'ForceNoIconv')) {
|
||||||
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
// Undo our previous fix in convertToUTF8, otherwise iconv will barf
|
||||||
|
$ascii_fix = HTMLPurifier_Encoder::testEncodingSupportsASCII($encoding);
|
||||||
|
if (!$escape && !empty($ascii_fix)) {
|
||||||
|
$clear_fix = array();
|
||||||
|
foreach ($ascii_fix as $utf8 => $native) $clear_fix[$utf8] = '';
|
||||||
|
$str = strtr($str, $clear_fix);
|
||||||
|
}
|
||||||
|
$str = strtr($str, array_flip($ascii_fix));
|
||||||
|
// Normal stuff
|
||||||
$str = iconv('utf-8', $encoding . '//IGNORE', $str);
|
$str = iconv('utf-8', $encoding . '//IGNORE', $str);
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
return $str;
|
return $str;
|
||||||
} elseif ($encoding === 'iso-8859-1') {
|
} elseif ($encoding === 'iso-8859-1') {
|
||||||
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
|
||||||
$str = utf8_decode($str);
|
$str = utf8_decode($str);
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
return $str;
|
return $str;
|
||||||
@@ -368,6 +373,47 @@ class HTMLPurifier_Encoder
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This expensive function tests whether or not a given character
|
||||||
|
* encoding supports ASCII. 7/8-bit encodings like Shift_JIS will
|
||||||
|
* fail this test, and require special processing. Variable width
|
||||||
|
* encodings shouldn't ever fail.
|
||||||
|
*
|
||||||
|
* @param string $encoding Encoding name to test, as per iconv format
|
||||||
|
* @param bool $bypass Whether or not to bypass the precompiled arrays.
|
||||||
|
* @return Array of UTF-8 characters to their corresponding ASCII,
|
||||||
|
* which can be used to "undo" any overzealous iconv action.
|
||||||
|
*/
|
||||||
|
public static function testEncodingSupportsASCII($encoding, $bypass = false) {
|
||||||
|
static $encodings = array();
|
||||||
|
if (!$bypass) {
|
||||||
|
if (isset($encodings[$encoding])) return $encodings[$encoding];
|
||||||
|
$lenc = strtolower($encoding);
|
||||||
|
switch ($lenc) {
|
||||||
|
case 'shift_jis':
|
||||||
|
return array("\xC2\xA5" => '\\', "\xE2\x80\xBE" => '~');
|
||||||
|
case 'johab':
|
||||||
|
return array("\xE2\x82\xA9" => '\\');
|
||||||
|
}
|
||||||
|
if (strpos($lenc, 'iso-8859-') === 0) return array();
|
||||||
|
}
|
||||||
|
$ret = array();
|
||||||
|
set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler'));
|
||||||
|
if (iconv('UTF-8', $encoding, 'a') === false) return false;
|
||||||
|
for ($i = 0x20; $i <= 0x7E; $i++) { // all printable ASCII chars
|
||||||
|
$c = chr($i);
|
||||||
|
if (iconv('UTF-8', "$encoding//IGNORE", $c) === '') {
|
||||||
|
// Reverse engineer: what's the UTF-8 equiv of this byte
|
||||||
|
// sequence? This assumes that there's no variable width
|
||||||
|
// encoding that doesn't support ASCII.
|
||||||
|
$ret[iconv($encoding, 'UTF-8//IGNORE', $c)] = $c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
restore_error_handler();
|
||||||
|
$encodings[$encoding] = $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,22 +7,37 @@
|
|||||||
class HTMLPurifier_ErrorCollector
|
class HTMLPurifier_ErrorCollector
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $errors = array();
|
/**
|
||||||
|
* Identifiers for the returned error array. These are purposely numeric
|
||||||
|
* so list() can be used.
|
||||||
|
*/
|
||||||
|
const LINENO = 0;
|
||||||
|
const SEVERITY = 1;
|
||||||
|
const MESSAGE = 2;
|
||||||
|
const CHILDREN = 3;
|
||||||
|
|
||||||
|
protected $errors;
|
||||||
|
protected $_current;
|
||||||
|
protected $_stacks = array(array());
|
||||||
protected $locale;
|
protected $locale;
|
||||||
protected $generator;
|
protected $generator;
|
||||||
protected $context;
|
protected $context;
|
||||||
|
|
||||||
|
protected $lines = array();
|
||||||
|
|
||||||
public function __construct($context) {
|
public function __construct($context) {
|
||||||
$this->locale =& $context->get('Locale');
|
$this->locale =& $context->get('Locale');
|
||||||
$this->generator =& $context->get('Generator');
|
|
||||||
$this->context = $context;
|
$this->context = $context;
|
||||||
|
$this->_current =& $this->_stacks[0];
|
||||||
|
$this->errors =& $this->_stacks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an error message to the collector for later use
|
* Sends an error message to the collector for later use
|
||||||
* @param $line Integer line number, or HTMLPurifier_Token that caused error
|
|
||||||
* @param $severity int Error severity, PHP error style (don't use E_USER_)
|
* @param $severity int Error severity, PHP error style (don't use E_USER_)
|
||||||
* @param $msg string Error message text
|
* @param $msg string Error message text
|
||||||
|
* @param $subst1 string First substitution for $msg
|
||||||
|
* @param $subst2 string ...
|
||||||
*/
|
*/
|
||||||
public function send($severity, $msg) {
|
public function send($severity, $msg) {
|
||||||
|
|
||||||
@@ -35,6 +50,7 @@ class HTMLPurifier_ErrorCollector
|
|||||||
|
|
||||||
$token = $this->context->get('CurrentToken', true);
|
$token = $this->context->get('CurrentToken', true);
|
||||||
$line = $token ? $token->line : $this->context->get('CurrentLine', true);
|
$line = $token ? $token->line : $this->context->get('CurrentLine', true);
|
||||||
|
$col = $token ? $token->col : $this->context->get('CurrentCol', true);
|
||||||
$attr = $this->context->get('CurrentAttr', true);
|
$attr = $this->context->get('CurrentAttr', true);
|
||||||
|
|
||||||
// perform special substitutions, also add custom parameters
|
// perform special substitutions, also add custom parameters
|
||||||
@@ -55,13 +71,66 @@ class HTMLPurifier_ErrorCollector
|
|||||||
|
|
||||||
if (!empty($subst)) $msg = strtr($msg, $subst);
|
if (!empty($subst)) $msg = strtr($msg, $subst);
|
||||||
|
|
||||||
$this->errors[] = array($line, $severity, $msg);
|
// (numerically indexed)
|
||||||
|
$error = array(
|
||||||
|
self::LINENO => $line,
|
||||||
|
self::SEVERITY => $severity,
|
||||||
|
self::MESSAGE => $msg,
|
||||||
|
self::CHILDREN => array()
|
||||||
|
);
|
||||||
|
$this->_current[] = $error;
|
||||||
|
|
||||||
|
|
||||||
|
// NEW CODE BELOW ...
|
||||||
|
|
||||||
|
$struct = null;
|
||||||
|
// Top-level errors are either:
|
||||||
|
// TOKEN type, if $value is set appropriately, or
|
||||||
|
// "syntax" type, if $value is null
|
||||||
|
$new_struct = new HTMLPurifier_ErrorStruct();
|
||||||
|
$new_struct->type = HTMLPurifier_ErrorStruct::TOKEN;
|
||||||
|
if ($token) $new_struct->value = clone $token;
|
||||||
|
if (is_int($line) && is_int($col)) {
|
||||||
|
if (isset($this->lines[$line][$col])) {
|
||||||
|
$struct = $this->lines[$line][$col];
|
||||||
|
} else {
|
||||||
|
$struct = $this->lines[$line][$col] = $new_struct;
|
||||||
|
}
|
||||||
|
// These ksorts may present a performance problem
|
||||||
|
ksort($this->lines[$line], SORT_NUMERIC);
|
||||||
|
} else {
|
||||||
|
if (isset($this->lines[-1])) {
|
||||||
|
$struct = $this->lines[-1];
|
||||||
|
} else {
|
||||||
|
$struct = $this->lines[-1] = $new_struct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ksort($this->lines, SORT_NUMERIC);
|
||||||
|
|
||||||
|
// Now, check if we need to operate on a lower structure
|
||||||
|
if (!empty($attr)) {
|
||||||
|
$struct = $struct->getChild(HTMLPurifier_ErrorStruct::ATTR, $attr);
|
||||||
|
if (!$struct->value) {
|
||||||
|
$struct->value = array($attr, 'PUT VALUE HERE');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($cssprop)) {
|
||||||
|
$struct = $struct->getChild(HTMLPurifier_ErrorStruct::CSSPROP, $cssprop);
|
||||||
|
if (!$struct->value) {
|
||||||
|
// if we tokenize CSS this might be a little more difficult to do
|
||||||
|
$struct->value = array($cssprop, 'PUT VALUE HERE');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok, structs are all setup, now time to register the error
|
||||||
|
$struct->addError($severity, $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves raw error data for custom formatter to use
|
* Retrieves raw error data for custom formatter to use
|
||||||
* @param List of arrays in format of array(Error message text,
|
* @param List of arrays in format of array(line of error,
|
||||||
* token that caused error, tokens surrounding token)
|
* error severity, error message,
|
||||||
|
* recursive sub-errors array)
|
||||||
*/
|
*/
|
||||||
public function getRaw() {
|
public function getRaw() {
|
||||||
return $this->errors;
|
return $this->errors;
|
||||||
@@ -70,38 +139,25 @@ class HTMLPurifier_ErrorCollector
|
|||||||
/**
|
/**
|
||||||
* Default HTML formatting implementation for error messages
|
* Default HTML formatting implementation for error messages
|
||||||
* @param $config Configuration array, vital for HTML output nature
|
* @param $config Configuration array, vital for HTML output nature
|
||||||
|
* @param $errors Errors array to display; used for recursion.
|
||||||
*/
|
*/
|
||||||
public function getHTMLFormatted($config) {
|
public function getHTMLFormatted($config, $errors = null) {
|
||||||
$ret = array();
|
$ret = array();
|
||||||
|
|
||||||
$errors = $this->errors;
|
$this->generator = new HTMLPurifier_Generator($config, $this->context);
|
||||||
|
if ($errors === null) $errors = $this->errors;
|
||||||
|
|
||||||
// sort error array by line
|
// 'At line' message needs to be removed
|
||||||
// line numbers are enabled if they aren't explicitly disabled
|
|
||||||
if ($config->get('Core', 'MaintainLineNumbers') !== false) {
|
// generation code for new structure goes here. It needs to be recursive.
|
||||||
$has_line = array();
|
foreach ($this->lines as $line => $col_array) {
|
||||||
$lines = array();
|
if ($line == -1) continue;
|
||||||
$original_order = array();
|
foreach ($col_array as $col => $struct) {
|
||||||
foreach ($errors as $i => $error) {
|
$this->_renderStruct($ret, $struct, $line, $col);
|
||||||
$has_line[] = (int) (bool) $error[0];
|
|
||||||
$lines[] = $error[0];
|
|
||||||
$original_order[] = $i;
|
|
||||||
}
|
}
|
||||||
array_multisort($has_line, SORT_DESC, $lines, SORT_ASC, $original_order, SORT_ASC, $errors);
|
|
||||||
}
|
}
|
||||||
|
if (isset($this->lines[-1])) {
|
||||||
foreach ($errors as $error) {
|
$this->_renderStruct($ret, $this->lines[-1]);
|
||||||
list($line, $severity, $msg) = $error;
|
|
||||||
$string = '';
|
|
||||||
$string .= '<strong>' . $this->locale->getErrorName($severity) . '</strong>: ';
|
|
||||||
$string .= $this->generator->escape($msg);
|
|
||||||
if ($line) {
|
|
||||||
// have javascript link generation that causes
|
|
||||||
// textarea to skip to the specified line
|
|
||||||
$string .= $this->locale->formatMessage(
|
|
||||||
'ErrorCollector: At line', array('line' => $line));
|
|
||||||
}
|
|
||||||
$ret[] = $string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($errors)) {
|
if (empty($errors)) {
|
||||||
@@ -112,5 +168,41 @@ class HTMLPurifier_ErrorCollector
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function _renderStruct(&$ret, $struct, $line = null, $col = null) {
|
||||||
|
$stack = array($struct);
|
||||||
|
$context_stack = array(array());
|
||||||
|
while ($current = array_pop($stack)) {
|
||||||
|
$context = array_pop($context_stack);
|
||||||
|
foreach ($current->errors as $error) {
|
||||||
|
list($severity, $msg) = $error;
|
||||||
|
$string = '';
|
||||||
|
$string .= '<div>';
|
||||||
|
// W3C uses an icon to indicate the severity of the error.
|
||||||
|
$error = $this->locale->getErrorName($severity);
|
||||||
|
$string .= "<span class=\"error e$severity\"><strong>$error</strong></span> ";
|
||||||
|
if (!is_null($line) && !is_null($col)) {
|
||||||
|
$string .= "<em class=\"location\">Line $line, Column $col: </em> ";
|
||||||
|
} else {
|
||||||
|
$string .= '<em class="location">End of Document: </em> ';
|
||||||
|
}
|
||||||
|
$string .= '<strong class="description">' . $this->generator->escape($msg) . '</strong> ';
|
||||||
|
$string .= '</div>';
|
||||||
|
// Here, have a marker for the character on the column appropriate.
|
||||||
|
// Be sure to clip extremely long lines.
|
||||||
|
//$string .= '<pre>';
|
||||||
|
//$string .= '';
|
||||||
|
//$string .= '</pre>';
|
||||||
|
$ret[] = $string;
|
||||||
|
}
|
||||||
|
foreach ($current->children as $type => $array) {
|
||||||
|
$context[] = $current;
|
||||||
|
$stack = array_merge($stack, array_reverse($array, true));
|
||||||
|
for ($i = count($array); $i > 0; $i--) {
|
||||||
|
$context_stack[] = $context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
58
library/HTMLPurifier/ErrorStruct.php
Normal file
58
library/HTMLPurifier/ErrorStruct.php
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records errors for particular segments of an HTML document such as tokens,
|
||||||
|
* attributes or CSS properties. They can contain error structs (which apply
|
||||||
|
* to components of what they represent), but their main purpose is to hold
|
||||||
|
* errors applying to whatever struct is being used.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_ErrorStruct
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible values for $children first-key. Note that top-level structures
|
||||||
|
* are automatically token-level.
|
||||||
|
*/
|
||||||
|
const TOKEN = 0;
|
||||||
|
const ATTR = 1;
|
||||||
|
const CSSPROP = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of this struct.
|
||||||
|
*/
|
||||||
|
public $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value of the struct we are recording errors for. There are various
|
||||||
|
* values for this:
|
||||||
|
* - TOKEN: Instance of HTMLPurifier_Token
|
||||||
|
* - ATTR: array('attr-name', 'value')
|
||||||
|
* - CSSPROP: array('prop-name', 'value')
|
||||||
|
*/
|
||||||
|
public $value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Errors registered for this structure.
|
||||||
|
*/
|
||||||
|
public $errors = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child ErrorStructs that are from this structure. For example, a TOKEN
|
||||||
|
* ErrorStruct would contain ATTR ErrorStructs. This is a multi-dimensional
|
||||||
|
* array in structure: [TYPE]['identifier']
|
||||||
|
*/
|
||||||
|
public $children = array();
|
||||||
|
|
||||||
|
public function getChild($type, $id) {
|
||||||
|
if (!isset($this->children[$type][$id])) {
|
||||||
|
$this->children[$type][$id] = new HTMLPurifier_ErrorStruct();
|
||||||
|
$this->children[$type][$id]->type = $type;
|
||||||
|
}
|
||||||
|
return $this->children[$type][$id];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addError($severity, $message) {
|
||||||
|
$this->errors[] = array($severity, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -26,6 +26,11 @@ class HTMLPurifier_Generator
|
|||||||
*/
|
*/
|
||||||
private $_def;
|
private $_def;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache of %Output.SortAttr
|
||||||
|
*/
|
||||||
|
private $_sortAttr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the generator
|
* Configuration for the generator
|
||||||
*/
|
*/
|
||||||
@@ -35,10 +40,10 @@ class HTMLPurifier_Generator
|
|||||||
* @param $config Instance of HTMLPurifier_Config
|
* @param $config Instance of HTMLPurifier_Config
|
||||||
* @param $context Instance of HTMLPurifier_Context
|
* @param $context Instance of HTMLPurifier_Context
|
||||||
*/
|
*/
|
||||||
public function __construct($config = null, $context = null) {
|
public function __construct($config, $context) {
|
||||||
if (!$config) $config = HTMLPurifier_Config::createDefault();
|
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->_scriptFix = $config->get('Output', 'CommentScriptContents');
|
$this->_scriptFix = $config->get('Output', 'CommentScriptContents');
|
||||||
|
$this->_sortAttr = $config->get('Output', 'SortAttr');
|
||||||
$this->_def = $config->getHTMLDefinition();
|
$this->_def = $config->getHTMLDefinition();
|
||||||
$this->_xhtml = $this->_def->doctype->xml;
|
$this->_xhtml = $this->_def->doctype->xml;
|
||||||
}
|
}
|
||||||
@@ -143,6 +148,7 @@ class HTMLPurifier_Generator
|
|||||||
*/
|
*/
|
||||||
public function generateAttributes($assoc_array_of_attributes, $element = false) {
|
public function generateAttributes($assoc_array_of_attributes, $element = false) {
|
||||||
$html = '';
|
$html = '';
|
||||||
|
if ($this->_sortAttr) ksort($assoc_array_of_attributes);
|
||||||
foreach ($assoc_array_of_attributes as $key => $value) {
|
foreach ($assoc_array_of_attributes as $key => $value) {
|
||||||
if (!$this->_xhtml) {
|
if (!$this->_xhtml) {
|
||||||
// Remove namespaced attributes
|
// Remove namespaced attributes
|
||||||
|
@@ -76,6 +76,11 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
|||||||
*/
|
*/
|
||||||
public $info_content_sets = array();
|
public $info_content_sets = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indexed list of HTMLPurifier_Injector to be used.
|
||||||
|
*/
|
||||||
|
public $info_injector = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doctype object
|
* Doctype object
|
||||||
*/
|
*/
|
||||||
@@ -186,18 +191,22 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
|||||||
$this->doctype = $this->manager->doctype;
|
$this->doctype = $this->manager->doctype;
|
||||||
|
|
||||||
foreach ($this->manager->modules as $module) {
|
foreach ($this->manager->modules as $module) {
|
||||||
foreach($module->info_tag_transform as $k => $v) {
|
foreach($module->info_tag_transform as $k => $v) {
|
||||||
if ($v === false) unset($this->info_tag_transform[$k]);
|
if ($v === false) unset($this->info_tag_transform[$k]);
|
||||||
else $this->info_tag_transform[$k] = $v;
|
else $this->info_tag_transform[$k] = $v;
|
||||||
}
|
}
|
||||||
foreach($module->info_attr_transform_pre as $k => $v) {
|
foreach($module->info_attr_transform_pre as $k => $v) {
|
||||||
if ($v === false) unset($this->info_attr_transform_pre[$k]);
|
if ($v === false) unset($this->info_attr_transform_pre[$k]);
|
||||||
else $this->info_attr_transform_pre[$k] = $v;
|
else $this->info_attr_transform_pre[$k] = $v;
|
||||||
}
|
}
|
||||||
foreach($module->info_attr_transform_post as $k => $v) {
|
foreach($module->info_attr_transform_post as $k => $v) {
|
||||||
if ($v === false) unset($this->info_attr_transform_post[$k]);
|
if ($v === false) unset($this->info_attr_transform_post[$k]);
|
||||||
else $this->info_attr_transform_post[$k] = $v;
|
else $this->info_attr_transform_post[$k] = $v;
|
||||||
}
|
}
|
||||||
|
foreach ($module->info_injector as $k => $v) {
|
||||||
|
if ($v === false) unset($this->info_injector[$k]);
|
||||||
|
else $this->info_injector[$k] = $v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->info = $this->manager->getElements();
|
$this->info = $this->manager->getElements();
|
||||||
@@ -356,6 +365,14 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup injectors -----------------------------------------------------
|
||||||
|
foreach ($this->info_injector as $i => $injector) {
|
||||||
|
if ($injector->checkNeeded($config) !== false) {
|
||||||
|
// remove injector that does not have it's required
|
||||||
|
// elements/attributes present, and is thus not needed.
|
||||||
|
unset($this->info_injector[$i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -71,6 +71,14 @@ class HTMLPurifier_HTMLModule
|
|||||||
*/
|
*/
|
||||||
public $info_attr_transform_post = array();
|
public $info_attr_transform_post = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of HTMLPurifier_Injector to be performed during well-formedness fixing.
|
||||||
|
* An injector will only be invoked if all of it's pre-requisites are met;
|
||||||
|
* if an injector fails setup, there will be no error; it will simply be
|
||||||
|
* silently disabled.
|
||||||
|
*/
|
||||||
|
public $info_injector = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Boolean flag that indicates whether or not getChildDef is implemented.
|
* Boolean flag that indicates whether or not getChildDef is implemented.
|
||||||
* For optimization reasons: may save a call to a function. Be sure
|
* For optimization reasons: may save a call to a function. Be sure
|
||||||
@@ -222,5 +230,14 @@ class HTMLPurifier_HTMLModule
|
|||||||
}
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazy load construction of the module after determining whether
|
||||||
|
* or not it's needed, and also when a finalized configuration object
|
||||||
|
* is available.
|
||||||
|
* @param $config Instance of HTMLPurifier_Config
|
||||||
|
*/
|
||||||
|
public function setup($config) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule
|
|||||||
'I18N' => array('dir' => false)
|
'I18N' => array('dir' => false)
|
||||||
);
|
);
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
$bdo = $this->addElement(
|
$bdo = $this->addElement(
|
||||||
'bdo', 'Inline', 'Inline', array('Core', 'Lang'),
|
'bdo', 'Inline', 'Inline', array('Core', 'Lang'),
|
||||||
array(
|
array(
|
||||||
|
@@ -9,7 +9,7 @@ class HTMLPurifier_HTMLModule_Edit extends HTMLPurifier_HTMLModule
|
|||||||
|
|
||||||
public $name = 'Edit';
|
public $name = 'Edit';
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
$contents = 'Chameleon: #PCDATA | Inline ! #PCDATA | Flow';
|
$contents = 'Chameleon: #PCDATA | Inline ! #PCDATA | Flow';
|
||||||
$attr = array(
|
$attr = array(
|
||||||
'cite' => 'URI',
|
'cite' => 'URI',
|
||||||
|
117
library/HTMLPurifier/HTMLModule/Forms.php
Normal file
117
library/HTMLPurifier/HTMLModule/Forms.php
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XHTML 1.1 Forms module, defines all form-related elements found in HTML 4.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_HTMLModule_Forms extends HTMLPurifier_HTMLModule
|
||||||
|
{
|
||||||
|
public $name = 'Forms';
|
||||||
|
public $safe = false;
|
||||||
|
|
||||||
|
public $content_sets = array(
|
||||||
|
'Block' => 'Form',
|
||||||
|
'Inline' => 'Formctrl',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function setup($config) {
|
||||||
|
$form = $this->addElement('form', 'Form',
|
||||||
|
'Required: Heading | List | Block | fieldset', 'Common', array(
|
||||||
|
'accept' => 'ContentTypes',
|
||||||
|
'accept-charset' => 'Charsets',
|
||||||
|
'action*' => 'URI',
|
||||||
|
'method' => 'Enum#get,post',
|
||||||
|
// really ContentType, but these two are the only ones used today
|
||||||
|
'enctype' => 'Enum#application/x-www-form-urlencoded,multipart/form-data',
|
||||||
|
));
|
||||||
|
$form->excludes = array('form' => true);
|
||||||
|
|
||||||
|
$input = $this->addElement('input', 'Formctrl', 'Empty', 'Common', array(
|
||||||
|
'accept' => 'ContentTypes',
|
||||||
|
'accesskey' => 'Character',
|
||||||
|
'alt' => 'Text',
|
||||||
|
'checked' => 'Bool#checked',
|
||||||
|
'disabled' => 'Bool#disabled',
|
||||||
|
'maxlength' => 'Number',
|
||||||
|
'name' => 'CDATA',
|
||||||
|
'readonly' => 'Bool#readonly',
|
||||||
|
'size' => 'Number',
|
||||||
|
'src' => 'URI#embeds',
|
||||||
|
'tabindex' => 'Number',
|
||||||
|
'type' => 'Enum#text,password,checkbox,button,radio,submit,reset,file,hidden,image',
|
||||||
|
'value' => 'CDATA',
|
||||||
|
));
|
||||||
|
$input->attr_transform_post[] = new HTMLPurifier_AttrTransform_Input();
|
||||||
|
|
||||||
|
$this->addElement('select', 'Formctrl', 'Required: optgroup | option', 'Common', array(
|
||||||
|
'disabled' => 'Bool#disabled',
|
||||||
|
'multiple' => 'Bool#multiple',
|
||||||
|
'name' => 'CDATA',
|
||||||
|
'size' => 'Number',
|
||||||
|
'tabindex' => 'Number',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->addElement('option', false, 'Optional: #PCDATA', 'Common', array(
|
||||||
|
'disabled' => 'Bool#disabled',
|
||||||
|
'label' => 'Text',
|
||||||
|
'selected' => 'Bool#selected',
|
||||||
|
'value' => 'CDATA',
|
||||||
|
));
|
||||||
|
// It's illegal for there to be more than one selected, but not
|
||||||
|
// be multiple. Also, no selected means undefined behavior. This might
|
||||||
|
// be difficult to implement; perhaps an injector, or a context variable.
|
||||||
|
|
||||||
|
$textarea = $this->addElement('textarea', 'Formctrl', 'Optional: #PCDATA', 'Common', array(
|
||||||
|
'accesskey' => 'Character',
|
||||||
|
'cols*' => 'Number',
|
||||||
|
'disabled' => 'Bool#disabled',
|
||||||
|
'name' => 'CDATA',
|
||||||
|
'readonly' => 'Bool#readonly',
|
||||||
|
'rows*' => 'Number',
|
||||||
|
'tabindex' => 'Number',
|
||||||
|
));
|
||||||
|
$textarea->attr_transform_pre[] = new HTMLPurifier_AttrTransform_Textarea();
|
||||||
|
|
||||||
|
$button = $this->addElement('button', 'Formctrl', 'Optional: #PCDATA | Heading | List | Block | Inline', 'Common', array(
|
||||||
|
'accesskey' => 'Character',
|
||||||
|
'disabled' => 'Bool#disabled',
|
||||||
|
'name' => 'CDATA',
|
||||||
|
'tabindex' => 'Number',
|
||||||
|
'type' => 'Enum#button,submit,reset',
|
||||||
|
'value' => 'CDATA',
|
||||||
|
));
|
||||||
|
|
||||||
|
// For exclusions, ideally we'd specify content sets, not literal elements
|
||||||
|
$button->excludes = $this->makeLookup(
|
||||||
|
'form', 'fieldset', // Form
|
||||||
|
'input', 'select', 'textarea', 'label', 'button', // Formctrl
|
||||||
|
'a' // as per HTML 4.01 spec, this is omitted by modularization
|
||||||
|
);
|
||||||
|
|
||||||
|
// Extra exclusion: img usemap="" is not permitted within this element.
|
||||||
|
// We'll omit this for now, since we don't have any good way of
|
||||||
|
// indicating it yet.
|
||||||
|
|
||||||
|
// This is HIGHLY user-unfriendly; we need a custom child-def for this
|
||||||
|
$this->addElement('fieldset', 'Form', 'Custom: (#WS?,legend,(Flow|#PCDATA)*)', 'Common');
|
||||||
|
|
||||||
|
$label = $this->addElement('label', 'Formctrl', 'Optional: #PCDATA | Inline', 'Common', array(
|
||||||
|
'accesskey' => 'Character',
|
||||||
|
// 'for' => 'IDREF', // IDREF not implemented, cannot allow
|
||||||
|
));
|
||||||
|
$label->excludes = array('label' => true);
|
||||||
|
|
||||||
|
$this->addElement('legend', false, 'Optional: #PCDATA | Inline', 'Common', array(
|
||||||
|
'accesskey' => 'Character',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->addElement('optgroup', false, 'Required: option', 'Common', array(
|
||||||
|
'disabled' => 'Bool#disabled',
|
||||||
|
'label*' => 'Text',
|
||||||
|
));
|
||||||
|
|
||||||
|
// Don't forget an injector for <isindex>. This one's a little complex
|
||||||
|
// because it maps to multiple elements.
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -8,7 +8,7 @@ class HTMLPurifier_HTMLModule_Hypertext extends HTMLPurifier_HTMLModule
|
|||||||
|
|
||||||
public $name = 'Hypertext';
|
public $name = 'Hypertext';
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
$a = $this->addElement(
|
$a = $this->addElement(
|
||||||
'a', 'Inline', 'Inline', 'Common',
|
'a', 'Inline', 'Inline', 'Common',
|
||||||
array(
|
array(
|
||||||
|
@@ -10,17 +10,25 @@ class HTMLPurifier_HTMLModule_Image extends HTMLPurifier_HTMLModule
|
|||||||
|
|
||||||
public $name = 'Image';
|
public $name = 'Image';
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
|
$max = $config->get('HTML', 'MaxImgLength');
|
||||||
$img = $this->addElement(
|
$img = $this->addElement(
|
||||||
'img', 'Inline', 'Empty', 'Common',
|
'img', 'Inline', 'Empty', 'Common',
|
||||||
array(
|
array(
|
||||||
'alt*' => 'Text',
|
'alt*' => 'Text',
|
||||||
'height' => 'Length',
|
// According to the spec, it's Length, but percents can
|
||||||
|
// be abused, so we allow only Pixels.
|
||||||
|
'height' => 'Pixels#' . $max,
|
||||||
|
'width' => 'Pixels#' . $max,
|
||||||
'longdesc' => 'URI',
|
'longdesc' => 'URI',
|
||||||
'src*' => new HTMLPurifier_AttrDef_URI(true), // embedded
|
'src*' => new HTMLPurifier_AttrDef_URI(true), // embedded
|
||||||
'width' => 'Length'
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
if ($max === null || $config->get('HTML', 'Trusted')) {
|
||||||
|
$img->attr['height'] =
|
||||||
|
$img->attr['width'] = 'Length';
|
||||||
|
}
|
||||||
|
|
||||||
// kind of strange, but splitting things up would be inefficient
|
// kind of strange, but splitting things up would be inefficient
|
||||||
$img->attr_transform_pre[] =
|
$img->attr_transform_pre[] =
|
||||||
$img->attr_transform_post[] =
|
$img->attr_transform_post[] =
|
||||||
|
@@ -21,7 +21,7 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule
|
|||||||
|
|
||||||
public $name = 'Legacy';
|
public $name = 'Legacy';
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
|
|
||||||
$this->addElement('basefont', 'Inline', 'Empty', false, array(
|
$this->addElement('basefont', 'Inline', 'Empty', false, array(
|
||||||
'color' => 'Color',
|
'color' => 'Color',
|
||||||
|
@@ -19,7 +19,7 @@ class HTMLPurifier_HTMLModule_List extends HTMLPurifier_HTMLModule
|
|||||||
|
|
||||||
public $content_sets = array('Flow' => 'List');
|
public $content_sets = array('Flow' => 'List');
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
$this->addElement('ol', 'List', 'Required: li', 'Common');
|
$this->addElement('ol', 'List', 'Required: li', 'Common');
|
||||||
$this->addElement('ul', 'List', 'Required: li', 'Common');
|
$this->addElement('ul', 'List', 'Required: li', 'Common');
|
||||||
$this->addElement('dl', 'List', 'Required: dt | dd', 'Common');
|
$this->addElement('dl', 'List', 'Required: dt | dd', 'Common');
|
||||||
|
16
library/HTMLPurifier/HTMLModule/Name.php
Normal file
16
library/HTMLPurifier/HTMLModule/Name.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class HTMLPurifier_HTMLModule_Name extends HTMLPurifier_HTMLModule
|
||||||
|
{
|
||||||
|
|
||||||
|
public $name = 'Name';
|
||||||
|
|
||||||
|
public function setup($config) {
|
||||||
|
$elements = array('a', 'applet', 'form', 'frame', 'iframe', 'img', 'map');
|
||||||
|
foreach ($elements as $name) {
|
||||||
|
$element = $this->addBlankElement($name);
|
||||||
|
$element->attr['name'] = 'ID';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -11,7 +11,7 @@ class HTMLPurifier_HTMLModule_Object extends HTMLPurifier_HTMLModule
|
|||||||
public $name = 'Object';
|
public $name = 'Object';
|
||||||
public $safe = false;
|
public $safe = false;
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
|
|
||||||
$this->addElement('object', 'Inline', 'Optional: #PCDATA | Flow | param', 'Common',
|
$this->addElement('object', 'Inline', 'Optional: #PCDATA | Flow | param', 'Common',
|
||||||
array(
|
array(
|
||||||
|
@@ -15,7 +15,7 @@ class HTMLPurifier_HTMLModule_Presentation extends HTMLPurifier_HTMLModule
|
|||||||
|
|
||||||
public $name = 'Presentation';
|
public $name = 'Presentation';
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
$this->addElement('b', 'Inline', 'Inline', 'Common');
|
$this->addElement('b', 'Inline', 'Inline', 'Common');
|
||||||
$this->addElement('big', 'Inline', 'Inline', 'Common');
|
$this->addElement('big', 'Inline', 'Inline', 'Common');
|
||||||
$this->addElement('hr', 'Block', 'Empty', 'Common');
|
$this->addElement('hr', 'Block', 'Empty', 'Common');
|
||||||
|
@@ -9,7 +9,7 @@ class HTMLPurifier_HTMLModule_Proprietary extends HTMLPurifier_HTMLModule
|
|||||||
|
|
||||||
public $name = 'Proprietary';
|
public $name = 'Proprietary';
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
|
|
||||||
$this->addElement('marquee', 'Inline', 'Flow', 'Common',
|
$this->addElement('marquee', 'Inline', 'Flow', 'Common',
|
||||||
array(
|
array(
|
||||||
|
@@ -9,7 +9,7 @@ class HTMLPurifier_HTMLModule_Ruby extends HTMLPurifier_HTMLModule
|
|||||||
|
|
||||||
public $name = 'Ruby';
|
public $name = 'Ruby';
|
||||||
|
|
||||||
public function __construct() {
|
public function setup($config) {
|
||||||
$this->addElement('ruby', 'Inline',
|
$this->addElement('ruby', 'Inline',
|
||||||
'Custom: ((rb, (rt | (rp, rt, rp))) | (rbc, rtc, rtc?))',
|
'Custom: ((rb, (rt | (rp, rt, rp))) | (rbc, rtc, rtc?))',
|
||||||
'Common');
|
'Common');
|
||||||
|
31
library/HTMLPurifier/HTMLModule/SafeEmbed.php
Normal file
31
library/HTMLPurifier/HTMLModule/SafeEmbed.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A "safe" embed module. See SafeObject. This is a proprietary element.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_HTMLModule_SafeEmbed extends HTMLPurifier_HTMLModule
|
||||||
|
{
|
||||||
|
|
||||||
|
public $name = 'SafeEmbed';
|
||||||
|
|
||||||
|
public function setup($config) {
|
||||||
|
|
||||||
|
$max = $config->get('HTML', 'MaxImgLength');
|
||||||
|
$embed = $this->addElement(
|
||||||
|
'embed', 'Inline', 'Empty', 'Common',
|
||||||
|
array(
|
||||||
|
'src*' => 'URI#embedded',
|
||||||
|
'type' => 'Enum#application/x-shockwave-flash',
|
||||||
|
'width' => 'Pixels#' . $max,
|
||||||
|
'height' => 'Pixels#' . $max,
|
||||||
|
'allowscriptaccess' => 'Enum#never',
|
||||||
|
'allownetworking' => 'Enum#internal',
|
||||||
|
'wmode' => 'Enum#window',
|
||||||
|
'name' => 'ID',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$embed->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeEmbed();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
48
library/HTMLPurifier/HTMLModule/SafeObject.php
Normal file
48
library/HTMLPurifier/HTMLModule/SafeObject.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A "safe" object module. In theory, objects permitted by this module will
|
||||||
|
* be safe, and untrusted users can be allowed to embed arbitrary flash objects
|
||||||
|
* (maybe other types too, but only Flash is supported as of right now).
|
||||||
|
* Highly experimental.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_HTMLModule_SafeObject extends HTMLPurifier_HTMLModule
|
||||||
|
{
|
||||||
|
|
||||||
|
public $name = 'SafeObject';
|
||||||
|
|
||||||
|
public function setup($config) {
|
||||||
|
|
||||||
|
// These definitions are not intrinsically safe: the attribute transforms
|
||||||
|
// are a vital part of ensuring safety.
|
||||||
|
|
||||||
|
$max = $config->get('HTML', 'MaxImgLength');
|
||||||
|
$object = $this->addElement(
|
||||||
|
'object',
|
||||||
|
'Inline',
|
||||||
|
'Optional: param | Flow | #PCDATA',
|
||||||
|
'Common',
|
||||||
|
array(
|
||||||
|
// While technically not required by the spec, we're forcing
|
||||||
|
// it to this value.
|
||||||
|
'type' => 'Enum#application/x-shockwave-flash',
|
||||||
|
'width' => 'Pixels#' . $max,
|
||||||
|
'height' => 'Pixels#' . $max,
|
||||||
|
'data' => 'URI#embedded'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$object->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeObject();
|
||||||
|
|
||||||
|
$param = $this->addElement('param', false, 'Empty', false,
|
||||||
|
array(
|
||||||
|
'id' => 'ID',
|
||||||
|
'name*' => 'Text',
|
||||||
|
'value' => 'Text'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$param->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeParam();
|
||||||
|
$this->info_injector[] = 'SafeObject';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user