mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-08-04 13:18:00 +02:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
5b46727358 |
12
.gitattributes
vendored
12
.gitattributes
vendored
@@ -1,12 +0,0 @@
|
||||
/.gitattributes export-ignore
|
||||
/.gitignore export-ignore
|
||||
/Doxyfile export-ignore
|
||||
/art/ export-ignore
|
||||
/benchmarks/ export-ignore
|
||||
/configdoc/ export-ignore
|
||||
/configdoc/usage.xml -crlf
|
||||
/docs/ export-ignore
|
||||
/phpdoc.ini
|
||||
/smoketests/ export-ignore
|
||||
/tests/* export-ignore
|
||||
/tests/path2class.func.php -export-ignore
|
28
.gitignore
vendored
28
.gitignore
vendored
@@ -1,28 +0,0 @@
|
||||
tags
|
||||
conf/
|
||||
test-settings.php
|
||||
config-schema.php
|
||||
library/HTMLPurifier/DefinitionCache/Serializer/*/
|
||||
library/standalone/
|
||||
library/HTMLPurifier.standalone.php
|
||||
library/HTMLPurifier*.tgz
|
||||
library/package*.xml
|
||||
smoketests/test-schema.html
|
||||
configdoc/*.html
|
||||
configdoc/configdoc.xml
|
||||
docs/doxygen*
|
||||
*.phpt.diff
|
||||
*.phpt.exp
|
||||
*.phpt.log
|
||||
*.phpt.out
|
||||
*.phpt.php
|
||||
*.phpt.skip.php
|
||||
*.htmlt.ini
|
||||
*.patch
|
||||
/*.php
|
||||
vendor
|
||||
composer.lock
|
||||
*.rej
|
||||
*.orig
|
||||
*.bak
|
||||
core
|
2
CREDITS
2
CREDITS
@@ -5,5 +5,3 @@ Almost everything written by Edward Z. Yang (Ambush Commander). Lots of thanks
|
||||
to the DevNetwork Community for their help (see docs/ref-devnetwork.html for
|
||||
more details), Feyd especially (namely IPv6 and optimization). Thanks to RSnake
|
||||
for letting me package his fantastic XSS cheatsheet for a smoketest.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
4
Doxyfile
4
Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 4.8.0
|
||||
PROJECT_NUMBER = 3.1.0
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
@@ -1313,5 +1313,3 @@ DOT_CLEANUP = YES
|
||||
# used. If set to NO the values of all tags below this one will be ignored.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
|
||||
# vim: et sw=4 sts=4
|
||||
|
54
INSTALL
54
INSTALL
@@ -15,22 +15,17 @@ with these contents.
|
||||
---------------------------------------------------------------------------
|
||||
1. Compatibility
|
||||
|
||||
HTML Purifier is PHP 5 and PHP 7, and is actively tested from PHP 5.0.5
|
||||
and up. It has no core dependencies with other libraries.
|
||||
HTML Purifier is PHP 5 only, and is actively tested from PHP 5.0.5 and
|
||||
up. It has no core dependencies with other libraries. PHP
|
||||
4 support was deprecated on December 31, 2007 with HTML Purifier 3.0.0.
|
||||
Essential security fixes will be issued for the 2.1.x branch until
|
||||
August 8, 2008.
|
||||
|
||||
These optional extensions can enhance the capabilities of HTML Purifier:
|
||||
|
||||
* iconv : Converts text to and from non-UTF-8 encodings
|
||||
* bcmath : Used for unit conversion and imagecrash protection
|
||||
* tidy : Used for pretty-printing HTML
|
||||
|
||||
These optional libraries can enhance the capabilities of HTML Purifier:
|
||||
|
||||
* CSSTidy : Clean CSS stylesheets using %Core.ExtractStyleBlocks
|
||||
Note: You should use the modernized fork of CSSTidy available
|
||||
at https://github.com/Cerdic/CSSTidy
|
||||
* Net_IDNA2 (PEAR) : IRI support using %Core.EnableIDNA
|
||||
Note: This is not necessary for PHP 5.3 or later
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
2. Reconnaissance
|
||||
@@ -237,12 +232,12 @@ HTML Purifier uses iconv to support other character encodings, as such,
|
||||
any encoding that iconv supports <http://www.gnu.org/software/libiconv/>
|
||||
HTML Purifier supports with this code:
|
||||
|
||||
$config->set('Core.Encoding', /* put your encoding here */);
|
||||
$config->set('Core', 'Encoding', /* put your encoding here */);
|
||||
|
||||
An example usage for Latin-1 websites (the most common encoding for English
|
||||
websites):
|
||||
|
||||
$config->set('Core.Encoding', 'ISO-8859-1');
|
||||
$config->set('Core', 'Encoding', 'ISO-8859-1');
|
||||
|
||||
Note that HTML Purifier's support for non-Unicode encodings is crippled by the
|
||||
fact that any character not supported by that encoding will be silently
|
||||
@@ -257,7 +252,7 @@ reason, I do not include the solution in this document).
|
||||
For those of you using HTML 4.01 Transitional, you can disable
|
||||
XHTML output like this:
|
||||
|
||||
$config->set('HTML.Doctype', 'HTML 4.01 Transitional');
|
||||
$config->set('HTML', 'Doctype', 'HTML 4.01 Transitional');
|
||||
|
||||
Other supported doctypes include:
|
||||
|
||||
@@ -283,14 +278,14 @@ are, respectively, %HTML.Allowed, %URI.MakeAbsolute and %URI.Base, and
|
||||
%AutoFormat.AutoParagraph. The %Namespace.Directive naming convention
|
||||
translates to:
|
||||
|
||||
$config->set('Namespace.Directive', $value);
|
||||
$config->set('Namespace', 'Directive', $value);
|
||||
|
||||
E.g.
|
||||
|
||||
$config->set('HTML.Allowed', 'p,b,a[href],i');
|
||||
$config->set('URI.Base', 'http://www.example.com');
|
||||
$config->set('URI.MakeAbsolute', true);
|
||||
$config->set('AutoFormat.AutoParagraph', true);
|
||||
$config->set('HTML', 'Allowed', 'p,b,a[href],i');
|
||||
$config->set('URI', 'Base', 'http://www.example.com');
|
||||
$config->set('URI', 'MakeAbsolute', true);
|
||||
$config->set('AutoFormat', 'AutoParagraph', true);
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -306,9 +301,11 @@ appropriate permissions using:
|
||||
chmod -R 0755 HTMLPurifier/DefinitionCache/Serializer
|
||||
|
||||
If the above command doesn't work, you may need to assign write permissions
|
||||
to group:
|
||||
to all. This may be necessary if your webserver runs as nobody, but is
|
||||
not recommended since it means any other user can write files in the
|
||||
directory. Use:
|
||||
|
||||
chmod -R 0775 HTMLPurifier/DefinitionCache/Serializer
|
||||
chmod -R 0777 HTMLPurifier/DefinitionCache/Serializer
|
||||
|
||||
You can also chmod files via your FTP client; this option
|
||||
is usually accessible by right clicking the corresponding directory and
|
||||
@@ -322,11 +319,11 @@ If you are unable or unwilling to give write permissions to the cache
|
||||
directory, you can either disable the cache (and suffer a performance
|
||||
hit):
|
||||
|
||||
$config->set('Core.DefinitionCache', null);
|
||||
$config->set('Core', 'DefinitionCache', null);
|
||||
|
||||
Or move the cache directory somewhere else (no trailing slash):
|
||||
|
||||
$config->set('Cache.SerializerPath', '/home/user/absolute/path');
|
||||
$config->set('Cache', 'SerializerPath', '/home/user/absolute/path');
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -334,6 +331,11 @@ Or move the cache directory somewhere else (no trailing slash):
|
||||
|
||||
The interface is mind-numbingly simple:
|
||||
|
||||
$purifier = new HTMLPurifier();
|
||||
$clean_html = $purifier->purify( $dirty_html );
|
||||
|
||||
...or, if you're using the configuration object:
|
||||
|
||||
$purifier = new HTMLPurifier($config);
|
||||
$clean_html = $purifier->purify( $dirty_html );
|
||||
|
||||
@@ -352,8 +354,7 @@ If your website is in UTF-8 and XHTML Transitional, use this code:
|
||||
<?php
|
||||
require_once '/path/to/htmlpurifier/library/HTMLPurifier.auto.php';
|
||||
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$purifier = new HTMLPurifier($config);
|
||||
$purifier = new HTMLPurifier();
|
||||
$clean_html = $purifier->purify($dirty_html);
|
||||
?>
|
||||
|
||||
@@ -363,11 +364,10 @@ If your website is in a different encoding or doctype, use this code:
|
||||
require_once '/path/to/htmlpurifier/library/HTMLPurifier.auto.php';
|
||||
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('Core.Encoding', 'ISO-8859-1'); // replace with your encoding
|
||||
$config->set('HTML.Doctype', 'HTML 4.01 Transitional'); // replace with your doctype
|
||||
$config->set('Core', 'Encoding', 'ISO-8859-1'); // replace with your encoding
|
||||
$config->set('HTML', 'Doctype', 'HTML 4.01 Transitional'); // replace with your doctype
|
||||
$purifier = new HTMLPurifier($config);
|
||||
|
||||
$clean_html = $purifier->purify($dirty_html);
|
||||
?>
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -1,60 +1,67 @@
|
||||
|
||||
|
||||
Installation
|
||||
Comment installer HTML Purifier
|
||||
|
||||
Attention : Ce document est encodé en UTF-8, si les lettres avec des accents
|
||||
ne s'affichent pas, prenez un meilleur éditeur de texte.
|
||||
Attention: Ce document a encode en UTF-8. Si les lettres avec les accents
|
||||
est essoreuse, prenez un mieux editeur de texte.
|
||||
|
||||
À L'Aide: Je ne suis pas un diseur natif de français. Si vous trouvez une
|
||||
erreur dans ce document, racontez-moi! Merci.
|
||||
|
||||
|
||||
L'installation de HTML Purifier est trés simple, parce qu'il ne doit pas
|
||||
la configuration. Dans le pied de de document, les utilisateurs
|
||||
impatient peuvent trouver le code, mais je recommande que vous lisez
|
||||
ce document pour quelques choses.
|
||||
|
||||
L'installation de HTML Purifier est très simple, parce qu'il n'a pas besoin
|
||||
de configuration. Pour les utilisateurs impatients, le code se trouve dans le
|
||||
pied de page, mais je recommande de lire le document.
|
||||
|
||||
1. Compatibilité
|
||||
|
||||
HTML Purifier fonctionne avec PHP 5. PHP 5.0.5 est la dernière version testée.
|
||||
Il ne dépend pas d'autres librairies.
|
||||
HTML Purifier fonctionne dans PHP 5. PHP 5.0.5 est le dernier
|
||||
version que je le testais. Il ne dépend de les autre librairies.
|
||||
|
||||
Les extensions optionnelles sont iconv (généralement déjà installée) et tidy
|
||||
(répendue aussi). Si vous utilisez UTF-8 et que vous ne voulez pas l'indentation,
|
||||
vous pouvez utiliser HTML Purifier sans ces extensions.
|
||||
Les extensions optionnel est iconv (en général déjà installer) et
|
||||
tidy (répandu aussi). Si vous utilisez UTF-8 et ne voulez pas
|
||||
l'indentation, vous pouvez utiliser HTML Purifier sans ces extensions.
|
||||
|
||||
|
||||
2. Inclure la librairie
|
||||
2. Inclure la librarie
|
||||
|
||||
Quand vous devez l'utilisez, incluez le :
|
||||
Utilisez:
|
||||
|
||||
require_once('/path/to/library/HTMLPurifier.auto.php');
|
||||
require_once '/path/to/library/HTMLPurifier.auto.php';
|
||||
|
||||
Ne pas l'inclure si ce n'est pas nécessaire, car HTML Purifier est lourd.
|
||||
...quand vous devez utiliser HTML Purifier (ne inclure pas quand vous
|
||||
ne devez pas, parce que HTML Purifier est trés grand.)
|
||||
|
||||
HTML Purifier utilise "autoload". Si vous avez défini la fonction __autoload,
|
||||
vous devez ajouter cette fonction :
|
||||
HTML Purifier utilise 'autoload'. Si vous avez définu la fonction
|
||||
__autoload, vous doivez ajoute cet programme:
|
||||
|
||||
spl_autoload_register('__autoload')
|
||||
|
||||
Plus d'informations dans le document "INSTALL".
|
||||
Plus d'information est dans le document 'INSTALL'.
|
||||
|
||||
3. Installation rapide
|
||||
|
||||
Si votre site Web est en UTF-8 et XHTML Transitional, utilisez :
|
||||
3. Installation vite
|
||||
|
||||
Si votre site web est en UTF-8 et XHTML Transitional, utilisez:
|
||||
|
||||
<?php
|
||||
require_once('/path/to/htmlpurifier/library/HTMLPurifier.auto.php');
|
||||
require_once '/path/to/htmlpurifier/library/HTMLPurifier.auto.php';
|
||||
|
||||
$purificateur = new HTMLPurifier();
|
||||
$html_propre = $purificateur->purify($html_a_purifier);
|
||||
$html_propre = $purificateur->purify($html_salle);
|
||||
?>
|
||||
|
||||
Sinon, utilisez :
|
||||
Sinon, utilisez:
|
||||
|
||||
<?php
|
||||
require_once('/path/to/html/purifier/library/HTMLPurifier.auto.load');
|
||||
$config = $HTMLPurifier_Config::createDefault();
|
||||
$config->set('Core', 'Encoding', 'ISO-8859-1'); //Remplacez par votre
|
||||
encodage
|
||||
$config->set('Core', 'XHTML', true); //Remplacer par false si HTML 4.01
|
||||
require_once '/path/to/htmlpurifier/library/HTMLPurifier.auto.php';
|
||||
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('Core', 'Encoding', 'ISO-8859-1'); //remplacez avec votre encoding
|
||||
$config->set('Core', 'XHTML', true); //remplacez avec false si HTML 4.01
|
||||
$purificateur = new HTMLPurifier($config);
|
||||
$html_propre = $purificateur->purify($html_a_purifier);
|
||||
|
||||
$html_propre = $purificateur->purify($html_salle);
|
||||
?>
|
||||
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
2
LICENSE
2
LICENSE
@@ -501,4 +501,4 @@ necessary. Here is a sample; alter the names:
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
||||
|
456
NEWS
456
NEWS
@@ -9,457 +9,6 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
. Internal change
|
||||
==========================
|
||||
|
||||
4.8.0, released 2016-07-16
|
||||
# By default, when a link has a target attribute associated
|
||||
with it, we now also add rel="noreferrer" in order to
|
||||
prevent the new window from being able to overwrite
|
||||
the original frame. To disable this protection,
|
||||
set %HTML.TargetNoreferrer to FALSE.
|
||||
! Full PHP 7 compatibility, the test suite is ALL GO.
|
||||
! %CSS.AllowDuplicates permits duplicate CSS properties.
|
||||
! Support for 'tel' URIs.
|
||||
! Partial support for 'border-radius' properties when %CSS.AllowProprietary is true.
|
||||
The slash syntax, i.e., 'border-radius: 2em 1em 4em / 0.5em 3em' is not
|
||||
yet supported.
|
||||
! %Attr.ID.HTML5 turns on HTML5-style ID handling.
|
||||
- alt truncation could result in malformed UTF-8 sequence. Don't
|
||||
truncate. Thanks Brandon Farber for reporting.
|
||||
- Linkify regex is smarter, based off of Gruber's regex.
|
||||
- IDNA supported natively on PHP 5.3 and later.
|
||||
- Non all-numeric top-level names (e.g., foo.1f, 1f) are now
|
||||
allowed.
|
||||
- Minor bounds error fix to squash a PHP 7 notice.
|
||||
- Support non-/tmp temporary directories for data:// validation
|
||||
- Give a better error message when a user attempts to allow
|
||||
ul/ol without allowing li.
|
||||
- On some versions of PHP, the Serializer DefinitionCache could
|
||||
infinite loop when the directory exists but is not listable. (#49)
|
||||
- Don't match for <body> inside comments with
|
||||
%Core.ConvertDocumentToFragment. (#67)
|
||||
- SafeObject is now less case sensitive. (#57)
|
||||
- AutoFormat.RemoveEmpty.Predicate now correctly renders in
|
||||
web form. (#85)
|
||||
|
||||
4.7.0, released 2015-08-04
|
||||
# opacity is now considered a "tricky" CSS property rather than a
|
||||
proprietary one.
|
||||
! %AutoFormat.RemoveEmpty.Predicate for specifying exactly when
|
||||
an element should be considered "empty" (maybe preserve if it
|
||||
has attributes), and modify iframe support so that the iframe
|
||||
is removed if it is missing a src attribute. Thanks meeva for
|
||||
reporting.
|
||||
- Don't truncate upon encountering </div> when using DOMLex. Thanks
|
||||
Myrto Christina for finally convincing me to fix this.
|
||||
- Update YouTube filter for new code.
|
||||
- Fix parsing of rgb() values with spaces in them for 'border'
|
||||
attribute.
|
||||
- Don't remove foo="" attributes if foo is a boolean attribute. Thanks
|
||||
valME for reporting.
|
||||
|
||||
4.6.0, released 2013-11-30
|
||||
# Secure URI munge hashing algorithm has changed to hash_hmac("sha256", $url, $secret).
|
||||
Please update any verification scripts you may have.
|
||||
# URI parsing algorithm was made more strict, so only prefixes which
|
||||
looks like schemes will actually be schemes. Thanks
|
||||
Michael Gusev <mgusev@sugarcrm.com> for fixing.
|
||||
# %Core.EscapeInvalidChildren is no longer supported, and no longer does
|
||||
anything.
|
||||
! New directive %Core.AllowHostnameUnderscore which allows underscores
|
||||
in hostnames.
|
||||
- Eliminate quadratic behavior in DOMLex by using a proper queue.
|
||||
Thanks Ole Laursen for noticing this.
|
||||
- Rewritten MakeWellFormed/FixNesting implementation eliminates quadratic
|
||||
behavior in the rest of the purificaiton pipeline. Thanks Chedburn
|
||||
Networks for sponsoring this work.
|
||||
- Made Linkify URL parser a bit less permissive, so that non-breaking
|
||||
spaces and commas are not included as part of URL. Thanks nAS for fixing.
|
||||
- Fix some bad interactions with %HTML.Allowed and injectors. Thanks
|
||||
David Hirtz for reporting.
|
||||
- Fix infinite loop in DirectLex. Thanks Ashar Javed (@soaj1664ashar)
|
||||
for reporting.
|
||||
|
||||
4.5.0, released 2013-02-17
|
||||
# Fix bug where stacked attribute transforms clobber each other;
|
||||
this also means it's no longer possible to override attribute
|
||||
transforms in later modules. No internal code was using this
|
||||
but this may break some clients.
|
||||
# We now use SHA-1 to identify cached definitions, instead of MD5.
|
||||
! Support display:inline-block
|
||||
! Support for more white-space CSS values.
|
||||
! Permit underscores in font families
|
||||
! Support for page-break-* CSS3 properties when proprietary properties
|
||||
are enabled.
|
||||
! New directive %Core.DisableExcludes; can be set to 'true' to turn off
|
||||
SGML excludes checking. If HTML Purifier is removing too much text
|
||||
and you don't care about full standards compliance, try setting this to
|
||||
'true'.
|
||||
- Use prepend for SPL autoloading on PHP 5.3 and later.
|
||||
- Fix bug with nofollow transform when pre-existing rel exists.
|
||||
- Fix bug where background:url() always gets lower-cased
|
||||
(but not background-image:url())
|
||||
- Fix bug with non lower-case color names in HTML
|
||||
- Fix bug where data URI validation doesn't remove temporary files.
|
||||
Thanks Javier Marín Ros <javiermarinros@gmail.com> for reporting.
|
||||
- Don't remove certain empty tags on RemoveEmpty.
|
||||
|
||||
4.4.0, released 2012-01-18
|
||||
# Removed PEARSax3 handler.
|
||||
# URI.Munge now munges URIs inside the same host that go from https
|
||||
to http. Reported by Neike Taika-Tessaro.
|
||||
# Core.EscapeNonASCIICharacters now always transforms entities to
|
||||
entities, even if target encoding is UTF-8.
|
||||
# Tighten up selector validation in ExtractStyleBlocks.
|
||||
Non-syntactically valid selectors are now rejected, along with
|
||||
some of the more obscure ones such as attribute selectors, the
|
||||
:lang pseudoselector, and anything not in CSS2.1. Furthermore,
|
||||
ID and class selectors now work properly with the relevant
|
||||
configuration attributes. Also, mute errors when parsing CSS
|
||||
with CSS Tidy. Reported by Mario Heiderich and Norman Hippert.
|
||||
! Added support for 'scope' attribute on tables.
|
||||
! Added %HTML.TargetBlank, which adds target="blank" to all outgoing links.
|
||||
! Properly handle sub-lists directly nested inside of lists in
|
||||
a standards compliant way, by moving them into the preceding <li>
|
||||
! Added %HTML.AllowedComments and %HTML.AllowedCommentsRegexp for
|
||||
limited allowed comments in untrusted situations.
|
||||
! Implement iframes, and allow them to be used in untrusted mode with
|
||||
%HTML.SafeIframe and %URI.SafeIframeRegexp. Thanks Bradley M. Froehle
|
||||
<brad.froehle@gmail.com> for submitting an initial version of the patch.
|
||||
! The Forms module now works properly for transitional doctypes.
|
||||
! Added support for internationalized domain names. You need the PEAR
|
||||
Net_IDNA2 module to be in your path; if it is installed, ensure the
|
||||
class can be loaded and then set %Core.EnableIDNA to true.
|
||||
- Color keywords are now case insensitive. Thanks Yzmir Ramirez
|
||||
<yramirez-htmlpurifier@adicio.com> for reporting.
|
||||
- Explicitly initialize anonModule variable to null.
|
||||
- Do not duplicate nofollow if already present. Thanks 178
|
||||
for reporting.
|
||||
- Do not add nofollow if hostname matches our current host. Thanks 178
|
||||
for reporting, and Neike Taika-Tessaro for helping diagnose.
|
||||
- Do not unset parser variable; this fixes intermittent serialization
|
||||
problems. Thanks Neike Taika-Tessaro for reporting, bill
|
||||
<10010tiger@gmail.com> for diagnosing.
|
||||
- Fix iconv truncation bug, where non-UTF-8 target encodings see
|
||||
output truncated after around 8000 characters. Thanks Jörg Ludwig
|
||||
<joerg.ludwig@iserv.eu> for reporting.
|
||||
- Fix broken table content model for XHTML1.1 (and also earlier
|
||||
versions, although the W3C validator doesn't catch those violations).
|
||||
Thanks GlitchMr <glitch.mr@gmail.com> for reporting.
|
||||
|
||||
4.3.0, released 2011-03-27
|
||||
# Fixed broken caching of customized raw definitions, but requires an
|
||||
API change. The old API still works but will emit a warning,
|
||||
see http://htmlpurifier.org/docs/enduser-customize.html#optimized
|
||||
for how to upgrade your code.
|
||||
# Protect against Internet Explorer innerHTML behavior by specially
|
||||
treating attributes with backticks but no angled brackets, quotes or
|
||||
spaces. This constitutes a slight semantic change, which can be
|
||||
reverted using %Output.FixInnerHTML. Reported by Neike Taika-Tessaro
|
||||
and Mario Heiderich.
|
||||
# Protect against cssText/innerHTML by restricting allowed characters
|
||||
used in fonts further than mandated by the specification and encoding
|
||||
some extra special characters in URLs. Reported by Neike
|
||||
Taika-Tessaro and Mario Heiderich.
|
||||
! Added %HTML.Nofollow to add rel="nofollow" to external links.
|
||||
! More types of SPL autoloaders allowed on later versions of PHP.
|
||||
! Implementations for position, top, left, right, bottom, z-index
|
||||
when %CSS.Trusted is on.
|
||||
! Add %Cache.SerializerPermissions option for custom serializer
|
||||
directory/file permissions
|
||||
! Fix longstanding bug in Flash support for non-IE browsers, and
|
||||
allow more wmode attributes.
|
||||
! Add %CSS.AllowedFonts to restrict permissible font names.
|
||||
- Switch to an iterative traversal of the DOM, which prevents us
|
||||
from running out of stack space for deeply nested documents.
|
||||
Thanks Maxim Krizhanovsky for contributing a patch.
|
||||
- Make removal of conditional IE comments ungreedy; thanks Bernd
|
||||
for reporting.
|
||||
- Escape CDATA before removing Internet Explorer comments.
|
||||
- Fix removal of id attributes under certain conditions by ensuring
|
||||
armor attributes are preserved when recreating tags.
|
||||
- Check if schema.ser was corrupted.
|
||||
- Check if zend.ze1_compatibility_mode is on, and error out if it is.
|
||||
This safety check is only done for HTMLPurifier.auto.php; if you
|
||||
are using standalone or the specialized includes files, you're
|
||||
expected to know what you're doing.
|
||||
- Stop repeatedly writing the cache file after I'm done customizing a
|
||||
raw definition. Reported by ajh.
|
||||
- Switch to using require_once in the Bootstrap to work around bad
|
||||
interaction with Zend Debugger and APC. Reported by Antonio Parraga.
|
||||
- Fix URI handling when hostname is missing but scheme is present.
|
||||
Reported by Neike Taika-Tessaro.
|
||||
- Fix missing numeric entities on DirectLex; thanks Neike Taika-Tessaro
|
||||
for reporting.
|
||||
- Fix harmless notice from indexing into empty string. Thanks Matthijs
|
||||
Kooijman <matthijs@stdin.nl> for reporting.
|
||||
- Don't autoclose no parent elements are able to support the element
|
||||
that triggered the autoclose. In particular fixes strange behavior
|
||||
of stray <li> tags. Thanks pkuliga@gmail.com for reporting and
|
||||
Neike Taika-Tessaro <pinkgothic@gmail.com> for debugging assistance.
|
||||
|
||||
4.2.0, released 2010-09-15
|
||||
! Added %Core.RemoveProcessingInstructions, which lets you remove
|
||||
<? ... ?> statements.
|
||||
! Added %URI.DisableResources functionality; the directive originally
|
||||
did nothing. Thanks David Rothstein for reporting.
|
||||
! Add documentation about configuration directive types.
|
||||
! Add %CSS.ForbiddenProperties configuration directive.
|
||||
! Add %HTML.FlashAllowFullScreen to permit embedded Flash objects
|
||||
to utilize full-screen mode.
|
||||
! Add optional support for the <code>file</code> URI scheme, enable
|
||||
by explicitly setting %URI.AllowedSchemes.
|
||||
! Add %Core.NormalizeNewlines options to allow turning off newline
|
||||
normalization.
|
||||
- Fix improper handling of Internet Explorer conditional comments
|
||||
by parser. Thanks zmonteca for reporting.
|
||||
- Fix missing attributes bug when running on Mac Snow Leopard and APC.
|
||||
Thanks sidepodcast for the fix.
|
||||
- Warn if an element is allowed, but an attribute it requires is
|
||||
not allowed.
|
||||
|
||||
4.1.1, released 2010-05-31
|
||||
- Fix undefined index warnings in maintenance scripts.
|
||||
- Fix bug in DirectLex for parsing elements with a single attribute
|
||||
with entities.
|
||||
- Rewrite CSS output logic for font-family and url(). Thanks Mario
|
||||
Heiderich <mario.heiderich@googlemail.com> for reporting and Takeshi
|
||||
Terada <t-terada@violet.plala.or.jp> for suggesting the fix.
|
||||
- Emit an error for CollectErrors if a body is extracted
|
||||
- Fix bug where in background-position for center keyword handling.
|
||||
- Fix infinite loop when a wrapper element is inserted in a context
|
||||
where it's not allowed. Thanks Lars <lars@renoz.dk> for reporting.
|
||||
- Remove +x bit and shebang from index.php; only supported mode is to
|
||||
explicitly call it with php.
|
||||
- Make test script less chatty when log_errors is on.
|
||||
|
||||
4.1.0, released 2010-04-26
|
||||
! Support proprietary height attribute on table element
|
||||
! Support YouTube slideshows that contain /cp/ in their URL.
|
||||
! Support for data: URI scheme; not enabled by default, add it using
|
||||
%URI.AllowedSchemes
|
||||
! Support flashvars when using %HTML.SafeObject and %HTML.SafeEmbed.
|
||||
! Support for Internet Explorer compatibility with %HTML.SafeObject
|
||||
using %Output.FlashCompat.
|
||||
! Handle <ol><ol> properly, by inserting the necessary <li> tag.
|
||||
- Always quote the insides of url(...) in CSS.
|
||||
|
||||
4.0.0, released 2009-07-07
|
||||
# APIs for ConfigSchema subsystem have substantially changed. See
|
||||
docs/dev-config-bcbreaks.txt for details; in essence, anything that
|
||||
had both namespace and directive now have a single unified key.
|
||||
# Some configuration directives were renamed, specifically:
|
||||
%AutoFormatParam.PurifierLinkifyDocURL -> %AutoFormat.PurifierLinkify.DocURL
|
||||
%FilterParam.ExtractStyleBlocksEscaping -> %Filter.ExtractStyleBlocks.Escaping
|
||||
%FilterParam.ExtractStyleBlocksScope -> %Filter.ExtractStyleBlocks.Scope
|
||||
%FilterParam.ExtractStyleBlocksTidyImpl -> %Filter.ExtractStyleBlocks.TidyImpl
|
||||
As usual, the old directive names will still work, but will throw E_NOTICE
|
||||
errors.
|
||||
# The allowed values for class have been relaxed to allow all of CDATA for
|
||||
doctypes that are not XHTML 1.1 or XHTML 2.0. For old behavior, set
|
||||
%Attr.ClassUseCDATA to false.
|
||||
# Instead of appending the content model to an old content model, a blank
|
||||
element will replace the old content model. You can use #SUPER to get
|
||||
the old content model.
|
||||
! More robust support for name="" and id=""
|
||||
! HTMLPurifier_Config::inherit($config) allows you to inherit one
|
||||
configuration, and have changes to that configuration be propagated
|
||||
to all of its children.
|
||||
! Implement %HTML.Attr.Name.UseCDATA, which relaxes validation rules on
|
||||
the name attribute when set. Use with care. Thanks Ian Cook for
|
||||
sponsoring.
|
||||
! Implement %AutoFormat.RemoveEmpty.RemoveNbsp, which removes empty
|
||||
tags that contain non-breaking spaces as well other whitespace. You
|
||||
can also modify which tags should have maintained with
|
||||
%AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.
|
||||
! Implement %Attr.AllowedClasses, which allows administrators to restrict
|
||||
classes users can use to a specified finite set of classes, and
|
||||
%Attr.ForbiddenClasses, which is the logical inverse.
|
||||
! You can now maintain your own configuration schema directories by
|
||||
creating a config-schema.php file or passing an extra argument. Check
|
||||
docs/dev-config-schema.html for more details.
|
||||
! Added HTMLPurifier_Config->serialize() method, which lets you save away
|
||||
your configuration in a compact serial file, which you can unserialize
|
||||
and use directly without having to go through the overhead of setup.
|
||||
- Fix bug where URIDefinition would not get cleared if it's directives got
|
||||
changed.
|
||||
- Fix fatal error in HTMLPurifier_Encoder on certain platforms (probably NetBSD 5.0)
|
||||
- Fix bug in Linkify autoformatter involving <a><span>http://foo</span></a>
|
||||
- Make %URI.Munge not apply to links that have the same host as your host.
|
||||
- Prevent stray </body> tag from truncating output, if a second </body>
|
||||
is present.
|
||||
. Created script maintenance/rename-config.php for renaming a configuration
|
||||
directive while maintaining its alias. This script does not change source code.
|
||||
. Implement namespace locking for definition construction, to prevent
|
||||
bugs where a directive is used for definition construction but is not
|
||||
used to construct the cache hash.
|
||||
|
||||
3.3.0, released 2009-02-16
|
||||
! Implement CSS property 'overflow' when %CSS.AllowTricky is true.
|
||||
! Implement generic property list classess
|
||||
- Fix bug with testEncodingSupportsASCII() algorithm when iconv() implementation
|
||||
does not do the "right thing" with characters not supported in the output
|
||||
set.
|
||||
- Spellcheck UTF-8: The Secret To Character Encoding
|
||||
- Fix improper removal of the contents of elements with only whitespace. Thanks
|
||||
Eric Wald for reporting.
|
||||
- Fix broken test suite in versions of PHP without spl_autoload_register()
|
||||
- Fix degenerate case with YouTube filter involving double hyphens.
|
||||
Thanks Pierre Attar for reporting.
|
||||
- Fix YouTube rendering problem on certain versions of Firefox.
|
||||
- Fix CSSDefinition Printer problems with decorators
|
||||
- Add text parameter to unit tests, forces text output
|
||||
. Add verbose mode to command line test runner, use (--verbose)
|
||||
. Turn on unit tests for UnitConverter
|
||||
. Fix missing version number in configuration %Attr.DefaultImageAlt (added 3.2.0)
|
||||
. Fix newline errors that caused spurious failures when CRLF HTML Purifier was
|
||||
tested on Linux.
|
||||
. Removed trailing whitespace from all text files, see
|
||||
remote-trailing-whitespace.php maintenance script.
|
||||
. Convert configuration to use property list backend.
|
||||
|
||||
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
|
||||
# Unnecessary references to objects (vestiges of PHP4) removed from method
|
||||
signatures. The following methods do not need references when assigning from
|
||||
@@ -484,8 +33,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
and allows for version numbers like "3.1.0-dev".
|
||||
! %HTML.Allowed deals gracefully with whitespace anywhere, anytime!
|
||||
! HTML Purifier's URI handling is a lot more robust, with much stricter
|
||||
validation checks and better percent encoding handling. Thanks Gareth Heyes
|
||||
for indicating security vulnerabilities from lax percent encoding.
|
||||
validation checks and better percent encoding handling.
|
||||
! Bootstrap autoloader deals more robustly with classes that don't exist,
|
||||
preventing class_exists($class, true) from barfing.
|
||||
- InterchangeBuilder now alphabetizes its lists
|
||||
@@ -1121,5 +669,3 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
+ Shorthand CSS properties
|
||||
+ Table CSS properties
|
||||
+ Deprecated attribute transformations
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -1,5 +1,6 @@
|
||||
HTML Purifier
|
||||
=============
|
||||
|
||||
README
|
||||
All about HTML Purifier
|
||||
|
||||
HTML Purifier is an HTML filtering solution that uses a unique combination
|
||||
of robust whitelists and agressive parsing to ensure that not only are
|
||||
@@ -18,12 +19,4 @@ Places to go:
|
||||
an in-depth installation guide.
|
||||
* See WYSIWYG for information on editors like TinyMCE and FCKeditor
|
||||
|
||||
HTML Purifier can be found on the web at: [http://htmlpurifier.org/](http://htmlpurifier.org/)
|
||||
|
||||
## Installation
|
||||
|
||||
Package available on [Composer](https://packagist.org/packages/ezyang/htmlpurifier).
|
||||
|
||||
If you're using Composer to manage dependencies, you can use
|
||||
|
||||
$ composer require "ezyang/htmlpurifier": "dev-master"
|
||||
HTML Purifier can be found on the web at: http://htmlpurifier.org/
|
110
TODO
110
TODO
@@ -11,68 +11,52 @@ If no interest is expressed for a feature that may require a considerable
|
||||
amount of effort to implement, it may get endlessly delayed. Do not be
|
||||
afraid to cast your vote for the next feature to be implemented!
|
||||
|
||||
Things to do as soon as possible:
|
||||
|
||||
- http://htmlpurifier.org/phorum/read.php?3,5560,6307#msg-6307
|
||||
- Think about allowing explicit order of operations hooks for transforms
|
||||
- Fix "<.<" bug (trailing < is removed if not EOD)
|
||||
- Build in better internal state dumps and debugging tools for remote
|
||||
debugging
|
||||
- Allowed/Allowed* have strange interactions when both set
|
||||
? Transform lone embeds into object tags
|
||||
- Deprecated config options that emit warnings when you set them (with'
|
||||
a way of muting the warning if you really want to)
|
||||
- Make HTML.Trusted work with Output.FlashCompat
|
||||
- HTML.Trusted and HTML.SafeObject have funny interaction; general
|
||||
problem is what to do when a module "supersedes" another
|
||||
(see also tables and basic tables.) This is a little dicier
|
||||
because HTML.SafeObject has some extra functionality that
|
||||
trusted might find useful. See http://htmlpurifier.org/phorum/read.php?3,5762,6100
|
||||
- Implement validation for query and for fragment
|
||||
|
||||
FUTURE VERSIONS
|
||||
---------------
|
||||
|
||||
4.9 release [OMG CONFIG PONIES]
|
||||
! Fix Printer. It's from the old days when we didn't have decent XML classes
|
||||
! Factor demo.php into a set of Printer classes, and then create a stub
|
||||
file for users here (inside the actual HTML Purifier library)
|
||||
- Fix error handling with form construction
|
||||
- Do encoding validation in Printers, or at least, where user data comes in
|
||||
- Config: Add examples to everything (make built-in which also automatically
|
||||
gives output)
|
||||
- Add "register" field to config schemas to eliminate dependence on
|
||||
naming conventions (try to remember why we ultimately decided on tihs)
|
||||
|
||||
5.0 release [HTML 5]
|
||||
# Swap out code to use html5lib tokenizer and tree-builder
|
||||
! Allow turning off of FixNesting and required attribute insertion
|
||||
|
||||
5.1 release [It's All About Trust] (floating)
|
||||
3.2 release [It's All About Trust] (floating)
|
||||
# Implement untrusted, dangerous elements/attributes
|
||||
- Objects and Forms are especially wanted
|
||||
# Implement IDREF support (harder than it seems, since you cannot have
|
||||
IDREFs to non-existent IDs)
|
||||
- Implement <area> (client and server side image maps are blocking
|
||||
on IDREF support)
|
||||
# Frameset XHTML 1.0 and HTML 4.01 doctypes
|
||||
- Figure out how to simultaneously set %CSS.Trusted and %HTML.Trusted (?)
|
||||
- Research and implement a "safe" version of the Object module
|
||||
|
||||
5.2 release [Error'ed]
|
||||
3.3 release [Error'ed]
|
||||
# Error logging for filtering/cleanup procedures
|
||||
- XSS-attempt detection--certain errors are flagged XSS-like
|
||||
|
||||
3.4 release [Do What I Mean, Not What I Say]
|
||||
# Additional support for poorly written HTML
|
||||
- Microsoft Word HTML cleaning (i.e. MsoNormal, but research essential!)
|
||||
- Friendly strict handling of <address> (block -> <br>)
|
||||
- XSS-attempt detection--certain errors are flagged XSS-like
|
||||
? Remove redundant tags, ex. <u><u>Underlined</u></u>. Implementation notes:
|
||||
1. Analyzing which tags to remove duplicants
|
||||
2. Ensure attributes are merged into the parent tag
|
||||
3. Extend the tag exclusion system to specify whether or not the
|
||||
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.)
|
||||
- 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
|
||||
dupe detector would also need to detect the suffix as well)
|
||||
- Externalize inline CSS to promote clean HTML, proposed by Sander Tekelenburg
|
||||
|
||||
6.0 release [Beyond HTML]
|
||||
4.0 release [Beyond HTML]
|
||||
# Legit token based CSS parsing (will require revamping almost every
|
||||
AttrDef class). Probably will use CSSTidy
|
||||
AttrDef class). Probably will use CSSTidy class?
|
||||
# More control over allowed CSS properties using a modularization
|
||||
# IRI support (this includes IDN)
|
||||
# HTML 5 support
|
||||
# IRI support
|
||||
- Standardize token armor for all areas of processing
|
||||
- Convert RTL/LTR override characters to <bdo> tags, or vice versa on demand.
|
||||
Also, enable disabling of directionality
|
||||
|
||||
7.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)
|
||||
- Hooks for adding custom processors to custom namespaced tags and
|
||||
attributes, offer default implementation
|
||||
@@ -83,14 +67,27 @@ Ongoing
|
||||
- Refactor unit tests into lots of test methods
|
||||
- Plugins for major CMSes (COMPLEX)
|
||||
- phpBB
|
||||
- Also, a FAQ for extension writers with HTML Purifier
|
||||
- Drupal needs loving!
|
||||
- Phorum need loving!
|
||||
- more! (look for ones that use WYSIWYGs)
|
||||
- Also, maybe a FAQ for extension writers with HTML Purifier
|
||||
|
||||
AutoFormat
|
||||
- Smileys
|
||||
- Syntax highlighting (with GeSHi) with <pre> and possibly <?php
|
||||
- Look at http://drupal.org/project/Modules/category/63 for ideas
|
||||
|
||||
Optimizations
|
||||
- Reduce size of internal data-structures (esp. HTMLDefinition)
|
||||
- Research memory usage of objects versus arrays
|
||||
- Combine multiple strategies into a single, single-pass strategy
|
||||
- Get PH5P working with the latest versions of DOM, which have much more
|
||||
stringent error checking procedures. Maybe convert straight to tokens.
|
||||
- Get rid of set_include_path(). Save this for another major release.
|
||||
|
||||
Neat feature related
|
||||
! Factor demo.php into a set of Printer classes, and then create a stub
|
||||
file for users here (inside the actual HTML Purifier library)
|
||||
! Support exporting configuration, so users can easily tweak settings
|
||||
in the demo, and then copy-paste into their own setup
|
||||
- Advanced URI filtering schemes (see docs/proposal-new-directives.txt)
|
||||
@@ -107,32 +104,13 @@ Neat feature related
|
||||
- Full set of color keywords. Also, a way to add onto them without
|
||||
finalizing the configuration object.
|
||||
- Write a var_export and memcached DefinitionCache - Denis
|
||||
- Built-in support for target="_blank" on all external links
|
||||
- Convert RTL/LTR override characters to <bdo> tags, or vice versa on demand.
|
||||
Also, enable disabling of directionality
|
||||
? Externalize inline CSS to promote clean HTML, proposed by Sander Tekelenburg
|
||||
? Remove redundant tags, ex. <u><u>Underlined</u></u>. Implementation notes:
|
||||
1. Analyzing which tags to remove duplicants
|
||||
2. Ensure attributes are merged into the parent tag
|
||||
3. Extend the tag exclusion system to specify whether or not the
|
||||
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.)
|
||||
? Make AutoParagraph also support paragraph-izing double <br> tags, and not
|
||||
just double newlines. This is kind of tough to do in the current framework,
|
||||
though, and might be reasonably approximated by search replacing double <br>s
|
||||
with newlines before running it through HTML Purifier.
|
||||
|
||||
Maintenance related (slightly boring)
|
||||
# CHMOD install script for PEAR installs
|
||||
! Factor out command line parser into its own class, and unit test it
|
||||
- Reduce size of internal data-structures (esp. HTMLDefinition)
|
||||
- Allow merging configurations. Thus,
|
||||
a -> b -> default
|
||||
c -> d -> default
|
||||
becomes
|
||||
a -> b -> c -> d -> default
|
||||
Maybe allow more fine-grained tuning of this behavior. Alternatively,
|
||||
encourage people to use short plist depths before building them up.
|
||||
! Nested configuration namespaces
|
||||
- Distinguish between default settings and explicitly set settings, so
|
||||
configurations can be merged
|
||||
- Time PHPT tests
|
||||
|
||||
ChildDef related (very boring)
|
||||
@@ -146,5 +124,3 @@ Wontfix
|
||||
- Pretty-printing HTML: users can use Tidy on the output on entire page
|
||||
- Native content compression, whitespace stripping: use gzip if this is
|
||||
really important
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
19
WHATSNEW
19
WHATSNEW
@@ -1,9 +1,10 @@
|
||||
HTML Purifier 4.8.0 is a bugfix release, collecting a year
|
||||
of accumulated bug fixes. In particular, we fixed some minor
|
||||
bugs and now declare full PHP 7 compatibility. The primary
|
||||
backwards-incompatible change is that HTML Purifier will now
|
||||
add rel="noreferrer" to all links with target attributes
|
||||
(you can disable this with %HTML.TargetNoReferrer.) Other
|
||||
changes: new configuration options %CSS.AllowDuplicates and
|
||||
%Attr.ID.HTML5; border-radius is partially supported when
|
||||
%CSS.AllowProprietary, and tel URIs are supported by default.
|
||||
HTML Purifier 3.1.0 is the second release series for HTML Purifier on PHP 5
|
||||
as well as a security update related to URIs. It shifts over to using
|
||||
autoload, and also includes support for the !important CSS modifier,
|
||||
display and visibility CSS properties with %CSS.AllowTricky, marquee with
|
||||
%HTML.Proprietary (had you scared for a moment, hmm?), a kses() wrapper,
|
||||
%CSS.AllowedProperties, %HTML.ForbiddenAttributes and
|
||||
%HTML.ForbiddenElements and a totally revamped ConfigDoc system. Since the
|
||||
release candidate, there have also been a number of stability fixes such as
|
||||
improved URI escaping, a change in serializer ID format, and a relaxed
|
||||
format for %HTML.Allowed. And as always, numerous bugfixes.
|
||||
|
2
WYSIWYG
2
WYSIWYG
@@ -16,5 +16,3 @@ trouble. Therein lies the solution:
|
||||
HTML Purifier is perfect for filtering pure-HTML input from WYSIWYG editors.
|
||||
|
||||
Enough said.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -1,16 +0,0 @@
|
||||
<?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;
|
||||
|
||||
// vim: et sw=4 sts=4
|
@@ -23,16 +23,15 @@ if (version_compare(PHP_VERSION, '5', '>=')) {
|
||||
class RowTimer extends Benchmark_Timer
|
||||
{
|
||||
|
||||
public $name;
|
||||
var $name;
|
||||
|
||||
public function __construct($name, $auto = false)
|
||||
{
|
||||
function RowTimer($name, $auto = false) {
|
||||
$this->name = htmlentities($name);
|
||||
$this->Benchmark_Timer($auto);
|
||||
}
|
||||
|
||||
public function getOutput()
|
||||
{
|
||||
function getOutput() {
|
||||
|
||||
$total = $this->TimeElapsed();
|
||||
$result = $this->getProfiling();
|
||||
$dashes = '';
|
||||
@@ -69,8 +68,7 @@ class RowTimer extends Benchmark_Timer
|
||||
}
|
||||
}
|
||||
|
||||
function print_lexers()
|
||||
{
|
||||
function print_lexers() {
|
||||
global $LEXERS;
|
||||
$first = true;
|
||||
foreach ($LEXERS as $key => $value) {
|
||||
@@ -80,8 +78,7 @@ function print_lexers()
|
||||
}
|
||||
}
|
||||
|
||||
function do_benchmark($name, $document)
|
||||
{
|
||||
function do_benchmark($name, $document) {
|
||||
global $LEXERS, $RUNS;
|
||||
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
@@ -156,6 +153,3 @@ echo '<div>Random input was: ' .
|
||||
|
||||
|
||||
</body></html>
|
||||
<?php
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -17,5 +17,3 @@ $data = $purifier->purify(file_get_contents('samples/Lexer/4.html'));
|
||||
xdebug_stop_trace();
|
||||
|
||||
echo "Trace finished.";
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -51,6 +51,3 @@
|
||||
<div style="text-align:center;">Click on photo to see HR version</div></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -15,6 +15,3 @@ function rwt(el,ct,cd,sg){var e = window.encodeURIComponent ? encodeURIComponent
|
||||
function qs(el) {if (window.RegExp && window.encodeURIComponent) {var ue=el.href;var qe=encodeURIComponent(document.f.q.value);if(ue.indexOf("q=")!=-1){el.href=ue.replace(new RegExp("q=[^&$]*"),"q="+qe);}else{el.href=ue+"&q="+qe;}}return 1;}
|
||||
// -->
|
||||
</script><table border=0 cellspacing=0 cellpadding=4><tr><td nowrap><font size=-1><b>Web</b> <a id=1a class=q href="/imghp?hl=en&tab=wi" onClick="return qs(this);">Images</a> <a id=2a class=q href="http://groups.google.com/grphp?hl=en&tab=wg" onClick="return qs(this);">Groups</a> <a id=4a class=q href="http://news.google.com/nwshp?hl=en&tab=wn" onClick="return qs(this);">News</a> <a id=5a class=q href="http://froogle.google.com/frghp?hl=en&tab=wf" onClick="return qs(this);">Froogle</a> <a id=8a class=q href="/lochp?hl=en&tab=wl" onClick="return qs(this);">Local</a> <b><a href="/intl/en/options/" class=q>more »</a></b></font></td></tr></table><table cellspacing=0 cellpadding=0><tr><td width=25%> </td><td align=center><input type=hidden name=hl value=en><input maxlength=2048 size=55 name=q value="" title="Google Search"><br><input type=submit value="Google Search" name=btnG><input type=submit value="I'm Feeling Lucky" name=btnI></td><td valign=top nowrap width=25%><font size=-2> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><br><font size=-1><a href="/ads/">Advertising Programs</a> - <a href=/services/>Business Solutions</a> - <a href=/about.html>About Google</a></font><p><font size=-2>©2006 Google</font></p></center></body></html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -126,6 +126,3 @@ if (objAdMgr.isSlotAvailable("leaderboard")) {
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -538,6 +538,3 @@ Retrieved from "<a href="http://en.wikipedia.org/wiki/Tai_Chi_Chuan">http://en.w
|
||||
|
||||
<!-- Served by srv25 in 0.089 secs. -->
|
||||
</body></html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -3,5 +3,3 @@ Disclaimer:
|
||||
The HTML used in these samples are taken from random websites. I claim
|
||||
no copyright over these and assert that I may use them like this under
|
||||
fair use.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "ezyang/htmlpurifier",
|
||||
"description": "Standards compliant HTML filter written in PHP",
|
||||
"type": "library",
|
||||
"keywords": ["html"],
|
||||
"homepage": "http://htmlpurifier.org/",
|
||||
"license": "LGPL",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Edward Z. Yang",
|
||||
"email": "admin@htmlpurifier.org",
|
||||
"homepage": "http://ezyang.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "HTMLPurifier": "library/" },
|
||||
"files": ["library/HTMLPurifier.composer.php"]
|
||||
}
|
||||
}
|
@@ -18,24 +18,22 @@ TODO:
|
||||
if (version_compare(PHP_VERSION, '5.2', '<')) exit('PHP 5.2+ required.');
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
chdir(dirname(__FILE__));
|
||||
|
||||
// load dual-libraries
|
||||
require_once dirname(__FILE__) . '/../extras/HTMLPurifierExtras.auto.php';
|
||||
require_once dirname(__FILE__) . '/../library/HTMLPurifier.auto.php';
|
||||
require_once '../extras/HTMLPurifierExtras.auto.php';
|
||||
require_once '../library/HTMLPurifier.auto.php';
|
||||
|
||||
// setup HTML Purifier singleton
|
||||
HTMLPurifier::getInstance(array(
|
||||
'AutoFormat.PurifierLinkify' => true
|
||||
));
|
||||
|
||||
$builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder();
|
||||
$interchange = new HTMLPurifier_ConfigSchema_Interchange();
|
||||
$builder->buildDir($interchange);
|
||||
$loader = dirname(__FILE__) . '/../config-schema.php';
|
||||
if (file_exists($loader)) include $loader;
|
||||
$interchange = HTMLPurifier_ConfigSchema_InterchangeBuilder::buildFromDirectory();
|
||||
$interchange->validate();
|
||||
|
||||
$style = 'plain'; // use $_GET in the future, careful to validate!
|
||||
$configdoc_xml = dirname(__FILE__) . '/configdoc.xml';
|
||||
$configdoc_xml = 'configdoc.xml';
|
||||
|
||||
$xml_builder = new HTMLPurifier_ConfigSchema_Builder_Xml();
|
||||
$xml_builder->openURI($configdoc_xml);
|
||||
@@ -52,13 +50,12 @@ if (!$output) {
|
||||
}
|
||||
|
||||
// write out
|
||||
file_put_contents(dirname(__FILE__) . "/$style.html", $output);
|
||||
file_put_contents("$style.html", $output);
|
||||
|
||||
if (php_sapi_name() != 'cli') {
|
||||
// output (instant feedback if it's a browser)
|
||||
echo $output;
|
||||
} else {
|
||||
echo "Files generated successfully.\n";
|
||||
echo 'Files generated successfully.';
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -40,5 +40,3 @@ h4 {font-family:sans-serif; font-size:0.9em; font-weight:bold; }
|
||||
.deprecated {color: #CCC;}
|
||||
.deprecated table.constraints th {background:#FFF;}
|
||||
.deprecated-notice {color: #000; text-align:center; margin-bottom: 1em;}
|
||||
|
||||
/* vim: et sw=4 sts=4 */
|
||||
|
@@ -19,7 +19,7 @@
|
||||
<xsl:variable name="usageLookup" select="document('../usage.xml')/usage" />
|
||||
|
||||
<!-- Twiddle this variable to get the columns as even as possible -->
|
||||
<xsl:variable name="maxNumberAdjust" select="2" />
|
||||
<xsl:variable name="maxNumberAdjust" select="1" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<html lang="en" xml:lang="en">
|
||||
@@ -40,26 +40,12 @@
|
||||
</xsl:apply-templates>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="typesContainer">
|
||||
<h2>Types</h2>
|
||||
<xsl:apply-templates select="$typeLookup" mode="types" />
|
||||
</div>
|
||||
<xsl:apply-templates />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="type" mode="types">
|
||||
<div class="type-block">
|
||||
<xsl:attribute name="id">type-<xsl:value-of select="@id" /></xsl:attribute>
|
||||
<h3><code><xsl:value-of select="@id" /></code>: <xsl:value-of select="@name" /></h3>
|
||||
<div class="type-description">
|
||||
<xsl:copy-of xmlns:xhtml="http://www.w3.org/1999/xhtml" select="xhtml:div/node()" />
|
||||
</div>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="title" mode="toc" />
|
||||
<xsl:template match="namespace" mode="toc">
|
||||
<xsl:param name="overflowNumber" />
|
||||
@@ -206,13 +192,10 @@
|
||||
<td>
|
||||
<xsl:variable name="type" select="text()" />
|
||||
<xsl:attribute name="class">type type-<xsl:value-of select="$type" /></xsl:attribute>
|
||||
<a>
|
||||
<xsl:attribute name="href">#type-<xsl:value-of select="$type" /></xsl:attribute>
|
||||
<xsl:value-of select="$typeLookup/type[@id=$type]/@name" />
|
||||
<xsl:value-of select="$typeLookup/type[@id=$type]/text()" />
|
||||
<xsl:if test="@allow-null='yes'">
|
||||
(or null)
|
||||
</xsl:if>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
@@ -248,6 +231,3 @@
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -1,69 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<types>
|
||||
<type id="string" name="String"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
A <a
|
||||
href="http://docs.php.net/manual/en/language.types.string.php">sequence
|
||||
of characters</a>.
|
||||
</div></type>
|
||||
<type id="istring" name="Case-insensitive string"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
A series of case-insensitive characters. Internally, upper-case
|
||||
ASCII characters will be converted to lower-case.
|
||||
</div></type>
|
||||
<type id="text" name="Text"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
A series of characters that may contain newlines. Text tends to
|
||||
indicate human-oriented text, as opposed to a machine format.
|
||||
</div></type>
|
||||
<type id="itext" name="Case-insensitive text"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
A series of case-insensitive characters that may contain newlines.
|
||||
</div></type>
|
||||
<type id="int" name="Integer"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
An <a
|
||||
href="http://docs.php.net/manual/en/language.types.integer.php">
|
||||
integer</a>. You are alternatively permitted to pass a string of
|
||||
digits instead, which will be cast to an integer using
|
||||
<code>(int)</code>.
|
||||
</div></type>
|
||||
<type id="float" name="Float"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
A <a href="http://docs.php.net/manual/en/language.types.float.php">
|
||||
floating point number</a>. You are alternatively permitted to
|
||||
pass a numeric string (as defined by <code>is_numeric()</code>),
|
||||
which will be cast to a float using <code>(float)</code>.
|
||||
</div></type>
|
||||
<type id="bool" name="Boolean"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
A <a
|
||||
href="http://docs.php.net/manual/en/language.types.boolean.php">boolean</a>.
|
||||
You are alternatively permitted to pass an integer <code>0</code> or
|
||||
<code>1</code> (other integers are not permitted) or a string
|
||||
<code>"on"</code>, <code>"true"</code> or <code>"1"</code> for
|
||||
<code>true</code>, and <code>"off"</code>, <code>"false"</code> or
|
||||
<code>"0"</code> for <code>false</code>.
|
||||
</div></type>
|
||||
<type id="lookup" name="Lookup array"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
An array whose values are <code>true</code>, e.g. <code>array('key'
|
||||
=> true, 'key2' => true)</code>. You are alternatively permitted
|
||||
to pass an array list of the keys <code>array('key', 'key2')</code>
|
||||
or a comma-separated string of keys <code>"key, key2"</code>. If
|
||||
you pass an array list of values, ensure that your values are
|
||||
strictly numerically indexed: <code>array('key1', 2 =>
|
||||
'key2')</code> will not do what you expect and emits a warning.
|
||||
</div></type>
|
||||
<type id="list" name="Array list"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
An array which has consecutive integer indexes, e.g.
|
||||
<code>array('val1', 'val2')</code>. You are alternatively permitted
|
||||
to pass a comma-separated string of keys <code>"val1, val2"</code>.
|
||||
If your array is not in this form, <code>array_values</code> is run
|
||||
on the array and a warning is emitted.
|
||||
</div></type>
|
||||
<type id="hash" name="Associative array"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
An array which is a mapping of keys to values, e.g.
|
||||
<code>array('key1' => 'val1', 'key2' => 'val2')</code>. You are
|
||||
alternatively permitted to pass a comma-separated string of
|
||||
key-colon-value strings, e.g. <code>"key1: val1, key2: val2"</code>.
|
||||
</div></type>
|
||||
<type id="mixed" name="Mixed"><div xmlns="http://www.w3.org/1999/xhtml">
|
||||
An arbitrary PHP value of any type.
|
||||
</div></type>
|
||||
<type id="string">String</type>
|
||||
<type id="istring">Case-insensitive string</type>
|
||||
<type id="text">Text</type>
|
||||
<type id="itext">Case-insensitive text</type>
|
||||
<type id="int">Integer</type>
|
||||
<type id="float">Float</type>
|
||||
<type id="bool">Boolean</type>
|
||||
<type id="lookup">Lookup array</type>
|
||||
<type id="list">Array list</type>
|
||||
<type id="hash">Associative array</type>
|
||||
<type id="mixed">Mixed</type>
|
||||
</types>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -2,566 +2,360 @@
|
||||
<usage>
|
||||
<directive id="Core.CollectErrors">
|
||||
<file name="HTMLPurifier.php">
|
||||
<line>162</line>
|
||||
<line>131</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>85</line>
|
||||
<line>315</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||
<line>67</line>
|
||||
<line>87</line>
|
||||
<line>385</line>
|
||||
<line>50</line>
|
||||
<line>62</line>
|
||||
<line>327</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||
<line>57</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.MaxImgLength">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>226</line>
|
||||
<line>44</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.Proprietary">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>319</line>
|
||||
<line>202</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowTricky">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>323</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.Trusted">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>327</line>
|
||||
<line>206</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowImportant">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>331</line>
|
||||
<line>210</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowedProperties">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>460</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.ForbiddenProperties">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>476</line>
|
||||
<line>262</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Cache.DefinitionImpl">
|
||||
<file name="HTMLPurifier/DefinitionCacheFactory.php">
|
||||
<line>66</line>
|
||||
<line>49</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Doctype">
|
||||
<file name="HTMLPurifier/DoctypeRegistry.php">
|
||||
<line>119</line>
|
||||
<line>83</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.CustomDoctype">
|
||||
<file name="HTMLPurifier/DoctypeRegistry.php">
|
||||
<line>123</line>
|
||||
<line>85</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.XHTML">
|
||||
<file name="HTMLPurifier/DoctypeRegistry.php">
|
||||
<line>128</line>
|
||||
<line>88</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Strict">
|
||||
<file name="HTMLPurifier/DoctypeRegistry.php">
|
||||
<line>133</line>
|
||||
<line>93</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.Encoding">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>374</line>
|
||||
<line>422</line>
|
||||
<line>281</line>
|
||||
<line>305</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Test.ForceNoIconv">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>382</line>
|
||||
<line>433</line>
|
||||
<line>283</line>
|
||||
<line>310</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.EscapeNonASCIICharacters">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>423</line>
|
||||
<line>307</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>
|
||||
</directive>
|
||||
<directive id="Output.CommentScriptContents">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>70</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.FixInnerHTML">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>71</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.SortAttr">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>72</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.FlashCompat">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>73</line>
|
||||
<line>41</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.TidyFormat">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>104</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.NormalizeNewlines">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>122</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>297</line>
|
||||
<line>70</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.Newline">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>123</line>
|
||||
<line>84</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.BlockWrapper">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>263</line>
|
||||
<line>213</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Parent">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>273</line>
|
||||
<line>221</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.AllowedElements">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>291</line>
|
||||
<line>238</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.AllowedAttributes">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>292</line>
|
||||
<line>239</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Allowed">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>295</line>
|
||||
<line>242</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.ForbiddenElements">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>399</line>
|
||||
<line>328</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.ForbiddenAttributes">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>400</line>
|
||||
<line>329</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Trusted">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>234</line>
|
||||
<line>198</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>302</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/HTMLModule/Image.php">
|
||||
<line>37</line>
|
||||
<line>238</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||
<line>47</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||
<line>30</line>
|
||||
<line>34</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.AllowedModules">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>241</line>
|
||||
<line>205</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.CoreModules">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>242</line>
|
||||
<line>206</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Proprietary">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>256</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.SafeObject">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>259</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.SafeEmbed">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>262</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.SafeScripting">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>265</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/HTMLModule/SafeScripting.php">
|
||||
<line>22</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Nofollow">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>268</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.TargetBlank">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>271</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.TargetNoreferrer">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>276</line>
|
||||
<line>220</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.IDBlacklist">
|
||||
<file name="HTMLPurifier/IDAccumulator.php">
|
||||
<line>27</line>
|
||||
<line>26</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.Language">
|
||||
<file name="HTMLPurifier/LanguageFactory.php">
|
||||
<line>93</line>
|
||||
<line>88</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.LexerImpl">
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>80</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.MaintainLineNumbers">
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>84</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||
<line>62</line>
|
||||
<line>70</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.ConvertDocumentToFragment">
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>313</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.RemoveProcessingInstructions">
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>334</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.">
|
||||
<file name="HTMLPurifier/URIDefinition.php">
|
||||
<line>65</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/URIFilter/Munge.php">
|
||||
<line>46</line>
|
||||
<line>230</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.Host">
|
||||
<file name="HTMLPurifier/URIDefinition.php">
|
||||
<line>76</line>
|
||||
<line>57</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/URIScheme.php">
|
||||
<line>89</line>
|
||||
<file name="HTMLPurifier/URIFilter/DisableExternal.php">
|
||||
<line>8</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.Base">
|
||||
<file name="HTMLPurifier/URIDefinition.php">
|
||||
<line>77</line>
|
||||
<line>58</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.DefaultScheme">
|
||||
<file name="HTMLPurifier/URIDefinition.php">
|
||||
<line>84</line>
|
||||
<line>65</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.AllowedSchemes">
|
||||
<file name="HTMLPurifier/URISchemeRegistry.php">
|
||||
<line>48</line>
|
||||
<line>42</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.OverrideAllowedSchemes">
|
||||
<file name="HTMLPurifier/URISchemeRegistry.php">
|
||||
<line>49</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowDuplicates">
|
||||
<file name="HTMLPurifier/AttrDef/CSS.php">
|
||||
<line>28</line>
|
||||
<line>43</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.Disable">
|
||||
<file name="HTMLPurifier/AttrDef/URI.php">
|
||||
<line>47</line>
|
||||
<line>23</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.Munge">
|
||||
<file name="HTMLPurifier/AttrDef/URI.php">
|
||||
<line>68</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.ColorKeywords">
|
||||
<file name="HTMLPurifier/AttrDef/CSS/Color.php">
|
||||
<line>19</line>
|
||||
<line>12</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/AttrDef/HTML/Color.php">
|
||||
<line>19</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowedFonts">
|
||||
<file name="HTMLPurifier/AttrDef/CSS/FontFamily.php">
|
||||
<line>64</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.AllowedClasses">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/Class.php">
|
||||
<line>33</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.ForbiddenClasses">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/Class.php">
|
||||
<line>34</line>
|
||||
<line>12</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.AllowedFrameTargets">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/FrameTarget.php">
|
||||
<line>32</line>
|
||||
<line>15</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.EnableID">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
||||
<line>41</line>
|
||||
<line>20</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.IDPrefix">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
||||
<line>51</line>
|
||||
<line>26</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.IDPrefixLocal">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
||||
<line>53</line>
|
||||
<line>58</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.ID.HTML5">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
||||
<line>75</line>
|
||||
<line>28</line>
|
||||
<line>31</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.IDBlacklistRegexp">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
||||
<line>97</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.">
|
||||
<file name="HTMLPurifier/AttrDef/HTML/LinkTypes.php">
|
||||
<line>46</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.AllowHostnameUnderscore">
|
||||
<file name="HTMLPurifier/AttrDef/URI/Host.php">
|
||||
<line>77</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.EnableIDNA">
|
||||
<file name="HTMLPurifier/AttrDef/URI/Host.php">
|
||||
<line>105</line>
|
||||
<line>54</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.DefaultTextDir">
|
||||
<file name="HTMLPurifier/AttrTransform/BdoDir.php">
|
||||
<line>22</line>
|
||||
<line>13</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.RemoveInvalidImg">
|
||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
||||
<line>24</line>
|
||||
<line>18</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||
<line>27</line>
|
||||
<line>20</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.DefaultInvalidImage">
|
||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
||||
<line>27</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.DefaultImageAlt">
|
||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
||||
<line>33</line>
|
||||
<line>19</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.DefaultInvalidImageAlt">
|
||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
||||
<line>40</line>
|
||||
<line>27</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Attr.Name.UseCDATA">
|
||||
<file name="HTMLPurifier/AttrTransform/Name.php">
|
||||
<line>18</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/HTMLModule/Name.php">
|
||||
<line>19</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.FlashAllowFullScreen">
|
||||
<file name="HTMLPurifier/AttrTransform/SafeParam.php">
|
||||
<line>53</line>
|
||||
<directive id="Core.EscapeInvalidChildren">
|
||||
<file name="HTMLPurifier/ChildDef/Required.php">
|
||||
<line>55</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Cache.SerializerPath">
|
||||
<file name="HTMLPurifier/DefinitionCache/Serializer.php">
|
||||
<line>183</line>
|
||||
<line>91</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Cache.SerializerPermissions">
|
||||
<file name="HTMLPurifier/DefinitionCache/Serializer.php">
|
||||
<line>200</line>
|
||||
<line>219</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Filter.ExtractStyleBlocks.TidyImpl">
|
||||
<directive id="FilterParam.ExtractStyleBlocksTidyImpl">
|
||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
||||
<line>94</line>
|
||||
<line>41</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Filter.ExtractStyleBlocks.Scope">
|
||||
<directive id="FilterParam.ExtractStyleBlocksScope">
|
||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
||||
<line>122</line>
|
||||
<line>65</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Filter.ExtractStyleBlocks.Escaping">
|
||||
<directive id="FilterParam.ExtractStyleBlocksEscaping">
|
||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
||||
<line>327</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.SafeIframe">
|
||||
<file name="HTMLPurifier/HTMLModule/Iframe.php">
|
||||
<line>28</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/URIFilter/SafeIframe.php">
|
||||
<line>48</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.MaxImgLength">
|
||||
<file name="HTMLPurifier/HTMLModule/Image.php">
|
||||
<line>21</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/HTMLModule/SafeEmbed.php">
|
||||
<line>18</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/HTMLModule/SafeObject.php">
|
||||
<line>24</line>
|
||||
<line>123</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.TidyLevel">
|
||||
<file name="HTMLPurifier/HTMLModule/Tidy.php">
|
||||
<line>50</line>
|
||||
<line>45</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.TidyAdd">
|
||||
<file name="HTMLPurifier/HTMLModule/Tidy.php">
|
||||
<line>54</line>
|
||||
<line>49</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.TidyRemove">
|
||||
<file name="HTMLPurifier/HTMLModule/Tidy.php">
|
||||
<line>55</line>
|
||||
<line>50</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="AutoFormat.PurifierLinkify.DocURL">
|
||||
<directive id="AutoFormatParam.PurifierLinkifyDocURL">
|
||||
<file name="HTMLPurifier/Injector/PurifierLinkify.php">
|
||||
<line>31</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="AutoFormat.RemoveEmpty.RemoveNbsp">
|
||||
<file name="HTMLPurifier/Injector/RemoveEmpty.php">
|
||||
<line>46</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions">
|
||||
<file name="HTMLPurifier/Injector/RemoveEmpty.php">
|
||||
<line>47</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="AutoFormat.RemoveEmpty.Predicate">
|
||||
<file name="HTMLPurifier/Injector/RemoveEmpty.php">
|
||||
<line>48</line>
|
||||
<line>15</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.AggressivelyFixLt">
|
||||
<file name="HTMLPurifier/Lexer/DOMLex.php">
|
||||
<line>54</line>
|
||||
<line>44</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.DirectLexLineNumberSyncInterval">
|
||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||
<line>84</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.DisableExcludes">
|
||||
<file name="HTMLPurifier/Strategy/FixNesting.php">
|
||||
<line>54</line>
|
||||
<line>59</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.EscapeInvalidTags">
|
||||
<file name="HTMLPurifier/Strategy/MakeWellFormed.php">
|
||||
<line>72</line>
|
||||
<line>22</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||
<line>26</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.AllowedComments">
|
||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||
<line>31</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.AllowedCommentsRegexp">
|
||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||
<line>32</line>
|
||||
<line>19</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.RemoveScriptContents">
|
||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||
<line>35</line>
|
||||
<line>22</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.HiddenElements">
|
||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
||||
<line>36</line>
|
||||
<line>23</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.HostBlacklist">
|
||||
<file name="HTMLPurifier/URIFilter/HostBlacklist.php">
|
||||
<line>25</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.MungeResources">
|
||||
<file name="HTMLPurifier/URIFilter/Munge.php">
|
||||
<line>48</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.MungeSecretKey">
|
||||
<file name="HTMLPurifier/URIFilter/Munge.php">
|
||||
<line>49</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.SafeIframeRegexp">
|
||||
<file name="HTMLPurifier/URIFilter/SafeIframe.php">
|
||||
<line>35</line>
|
||||
<line>8</line>
|
||||
</file>
|
||||
</directive>
|
||||
</usage>
|
||||
|
@@ -17,10 +17,202 @@
|
||||
<div id="home"><a href="http://htmlpurifier.org/">HTML Purifier</a> End-User Documentation</div>
|
||||
|
||||
<p>
|
||||
Please see <a href="enduser-customize.html">Customize!</a>
|
||||
<strong>Warning:</strong> This document may be out-of-date. When in doubt,
|
||||
consult the source code documentation.
|
||||
</p>
|
||||
|
||||
</body></html>
|
||||
<p>HTML Purifier currently natively supports only a subset of HTML's
|
||||
allowed elements, attributes, and behavior; specifically, this subset
|
||||
is the set of elements that are safe for untrusted users to use.
|
||||
However, HTML Purifier is often utilized to ensure standards-compliance
|
||||
from input that is trusted (making it a sort of Tidy substitute),
|
||||
and often users need to define new elements or attributes. The
|
||||
advanced API is oriented specifically for these use-cases.</p>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
<p>Our goals are to let the user:</p>
|
||||
|
||||
<dl>
|
||||
<dt>Select</dt>
|
||||
<dd><ul>
|
||||
<li>Doctype</li>
|
||||
<!-- <li>Filterset</li> -->
|
||||
<li>Elements / Attributes / Modules</li>
|
||||
<li>Tidy</li>
|
||||
</ul></dd>
|
||||
<dt>Customize</dt>
|
||||
<dd><ul>
|
||||
<li>Attributes</li>
|
||||
<li>Elements</li>
|
||||
<!--<li>Doctypes</li>-->
|
||||
</ul></dd>
|
||||
</dl>
|
||||
|
||||
<h2>Select</h2>
|
||||
|
||||
<p>For basic use, the user will have to specify some basic parameters. This
|
||||
is not strictly necessary, as HTML Purifier's default setting will always
|
||||
output safe code, but is required for standards-compliant output.</p>
|
||||
|
||||
<h3>Selecting a Doctype</h3>
|
||||
|
||||
<p>The first thing to select is the <strong>doctype</strong>. This
|
||||
is essential for standards-compliant output.</p>
|
||||
|
||||
<p class="technical">This identifier is based
|
||||
on the name the W3C has given to the document type and <em>not</em>
|
||||
the DTD identifier.</p>
|
||||
|
||||
<p>This parameter is set via the configuration object:</p>
|
||||
|
||||
<pre>$config->set('HTML', 'Doctype', 'XHTML 1.0 Transitional');</pre>
|
||||
|
||||
<p>Due to historical reasons, the default doctype is XHTML 1.0
|
||||
Transitional, however, we really shouldn't be guessing what the user's
|
||||
doctype is. Fortunantely, people who can't be bothered to set this won't
|
||||
be bothered when their pages stop validating.</p>
|
||||
|
||||
<h3>Selecting Elements / Attributes / Modules</h3>
|
||||
|
||||
<p>HTML Purifier will, by default, allow as many elements and attributes
|
||||
as possible. However, a user may decide to roll their own filterset by
|
||||
selecting modules, elements and attributes to allow for their own
|
||||
specific use-case. This can be done using %HTML.Allowed:</p>
|
||||
|
||||
<pre>$config->set('HTML', 'Allowed', 'a[href|title],em,p,blockquote');</pre>
|
||||
|
||||
<p class="technical">The directive %HTML.Allowed is a convenience feature
|
||||
that may be fully expressed with the legacy interface.</p>
|
||||
|
||||
<p>We currently support another interface from older versions:</p>
|
||||
|
||||
<pre>$config->set('HTML', 'AllowedElements', 'a,em,p,blockquote');
|
||||
$config->set('HTML', 'AllowedAttributes', 'a.href,a.title');</pre>
|
||||
|
||||
<p>A user may also choose to allow modules using a specialized
|
||||
directive:</p>
|
||||
|
||||
<pre>$config->set('HTML', 'AllowedModules', 'Hypertext,Text,Lists');</pre>
|
||||
|
||||
<p>But it is not expected that this feature will be widely used.</p>
|
||||
|
||||
<p class="technical">Module selection will work slightly differently
|
||||
from the other AllowedElements and AllowedAttributes directives by
|
||||
directly modifying the doctype you are operating in, in the spirit of
|
||||
XHTML 1.1's modularization. We stop users from shooting themselves in the
|
||||
foot by mandating the modules in %HTML.CoreModules be used.</p>
|
||||
|
||||
<p class="technical">Modules are distinguished from regular elements by the
|
||||
case of their first letter. While XML distinguishes between and allows
|
||||
lower and uppercase letters in element names, XHTML uses only lower-case
|
||||
element names for sake of consistency.</p>
|
||||
|
||||
<h3>Selecting Tidy</h3>
|
||||
|
||||
<p>The name of this segment of functionality is inspired off of Dave
|
||||
Ragget's program HTML Tidy, which purported to help clean up HTML. In
|
||||
HTML Purifier, Tidy functionality involves turning unsupported and
|
||||
deprecated elements into standards-compliant ones, maintaining
|
||||
backwards compatibility, and enforcing best practices.</p>
|
||||
|
||||
<p>This is a complicated feature, and is explained more in depth at
|
||||
<a href="enduser-tidy.html">the Tidy documentation page</a>.</p>
|
||||
|
||||
<!--
|
||||
<h3>Unified selector</h3>
|
||||
|
||||
<p>Because selecting each and every one of these configuration options
|
||||
is a chore, we may wish to offer a specialized configuration method
|
||||
for selecting a filterset. Possibility:</p>
|
||||
|
||||
<pre>function selectFilter($doctype, $filterset, $tidy)</pre>
|
||||
|
||||
<p>...which is simply a light wrapper over the individual configuration
|
||||
calls. A custom config file format or text format could also be adopted.</p>
|
||||
-->
|
||||
|
||||
<h2>Customize</h2>
|
||||
|
||||
<p>By reviewing topic posts in the support forum, we determined that
|
||||
there were two primarily demanded customization features people wanted:
|
||||
to add an attribute to an existing element, and to add an element.
|
||||
Thus, we'll want to create convenience functions for these common
|
||||
use-cases.</p>
|
||||
|
||||
<p>Note that the functions described here are only available if
|
||||
a raw copy of <code>HTMLPurifier_HTMLDefinition</code> was retrieved.
|
||||
Furthermore, caching may prevent your changes from immediately
|
||||
being seen: consult <a href="enduser-customize.html">enduser-customize.html</a> on how
|
||||
to work around this.</p>
|
||||
|
||||
<h3>Attributes</h3>
|
||||
|
||||
<p>An attribute is bound to an element by a name and has a specific
|
||||
<code>AttrDef</code> that validates it. The interface is therefore:</p>
|
||||
|
||||
<pre>function addAttribute($element, $attribute, $attribute_def);</pre>
|
||||
|
||||
<p>Example of the functionality in action:</p>
|
||||
|
||||
<pre>$def->addAttribute('a', 'rel', 'Enum#nofollow');</pre>
|
||||
|
||||
<p>The <code>$attribute_def</code> value is flexible,
|
||||
to make things simpler. It can be a literal object or:</p>
|
||||
|
||||
<ul>
|
||||
<!--<li>Class name: We'll instantiate it for you</li>
|
||||
<li>Function name: We'll create an <code>HTMLPurifier_AttrDef_Anonymous</code>
|
||||
class with that function registered as a callback.</li>-->
|
||||
<li>String attribute type: We'll use <code>HTMLPurifier_AttrTypes</code>
|
||||
to resolve it for you. Any data that follows a hash mark (#) will
|
||||
be used to customize the attribute type: in the example above,
|
||||
we specify which values for Enum to allow.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Elements</h3>
|
||||
|
||||
<p>An element requires certain information as specified by
|
||||
<code>HTMLPurifier_ElementDef</code>. However, not all of it is necessary,
|
||||
the usual things required are:</p>
|
||||
|
||||
<ul>
|
||||
<li>Attributes</li>
|
||||
<li>Content model/type</li>
|
||||
<li>Registration in a content set</li>
|
||||
</ul>
|
||||
|
||||
<p>This suggests an API like this:</p>
|
||||
|
||||
<pre>function addElement($element, $type, $contents,
|
||||
$attr_collections = array(); $attributes = array());</pre>
|
||||
|
||||
<p>Each parameter explained in depth:</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>$element</code></dt>
|
||||
<dd>Element name, ex. 'label'</dd>
|
||||
<dt><code>$type</code></dt>
|
||||
<dd>Content set to register in, ex. 'Inline' or 'Flow'</dd>
|
||||
<dt><code>$contents</code></dt>
|
||||
<dd>Description of allowed children. This is a merged form of
|
||||
<code>HTMLPurifier_ElementDef</code>'s member variables
|
||||
<code>$content_model</code> and <code>$content_model_type</code>,
|
||||
where the form is <q>Type: Model</q>, ex. 'Optional: Inline'.
|
||||
There are also a number of predefined templates one may use.</dd>
|
||||
<dt><code>$attr_collections</code></dt>
|
||||
<dd>Array (or string if only one) of attribute collection(s) to
|
||||
merge into the attributes array.</dd>
|
||||
<dt><code>$attributes</code></dt>
|
||||
<dd>Array of attribute names to attribute definitions, much like
|
||||
the above-described attribute customization.</dd>
|
||||
</dl>
|
||||
|
||||
<p>A possible usage:</p>
|
||||
|
||||
<pre>$def->addElement('font', 'Inline', 'Optional: Inline', 'Common',
|
||||
array('color' => 'Color'));</pre>
|
||||
|
||||
<p>See <code>HTMLPurifier/HTMLModule.php</code> for details.</p>
|
||||
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
</body></html>
|
||||
|
@@ -25,6 +25,3 @@ URIScheme - needs to have callable generic checks
|
||||
mailto - doesn't validate emails, doesn't validate querystring
|
||||
news - doesn't validate opaque path
|
||||
nntp - doesn't constrain path
|
||||
tel - doesn't validate phone numbers, only allows characters '+', '1-9', and 'x'
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -1,79 +0,0 @@
|
||||
|
||||
Configuration Backwards-Compatibility Breaks
|
||||
|
||||
In version 4.0.0, the configuration subsystem (composed of the outwards
|
||||
facing Config class, as well as the ConfigSchema and ConfigSchema_Interchange
|
||||
subsystems), was significantly revamped to make use of property lists.
|
||||
While most of the changes are internal, some internal APIs were changed for the
|
||||
sake of clarity. HTMLPurifier_Config was kept completely backwards compatible,
|
||||
although some of the functions were retrofitted with an unambiguous alternate
|
||||
syntax. Both of these changes are discussed in this document.
|
||||
|
||||
|
||||
|
||||
1. Outwards Facing Changes
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The HTMLPurifier_Config class now takes an alternate syntax. The general rule
|
||||
is:
|
||||
|
||||
If you passed $namespace, $directive, pass "$namespace.$directive"
|
||||
instead.
|
||||
|
||||
An example:
|
||||
|
||||
$config->set('HTML', 'Allowed', 'p');
|
||||
|
||||
becomes:
|
||||
|
||||
$config->set('HTML.Allowed', 'p');
|
||||
|
||||
New configuration options may have more than one namespace, they might
|
||||
look something like %Filter.YouTube.Blacklist. While you could technically
|
||||
set it with ('HTML', 'YouTube.Blacklist'), the logical extension
|
||||
('HTML', 'YouTube', 'Blacklist') does not work.
|
||||
|
||||
The old API will still work, but will emit E_USER_NOTICEs.
|
||||
|
||||
|
||||
|
||||
2. Internal API Changes
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Some overarching notes: we've completely eliminated the notion of namespace;
|
||||
it's now an informal construct for organizing related configuration directives.
|
||||
|
||||
Also, the validation routines for keys (formerly "$namespace.$directive")
|
||||
have been completely relaxed. I don't think it really should be necessary.
|
||||
|
||||
2.1 HTMLPurifier_ConfigSchema
|
||||
|
||||
First off, if you're interfacing with this class, you really shouldn't.
|
||||
HTMLPurifier_ConfigSchema_Builder_ConfigSchema is really the only class that
|
||||
should ever be creating HTMLPurifier_ConfigSchema, and HTMLPurifier_Config the
|
||||
only class that should be reading it.
|
||||
|
||||
All namespace related methods were removed; they are completely unnecessary
|
||||
now. Any $namespace, $name arguments must be replaced with $key (where
|
||||
$key == "$namespace.$name"), including for addAlias().
|
||||
|
||||
The $info and $defaults member variables are no longer indexed as
|
||||
[$namespace][$name]; they are now indexed as ["$namespace.$name"].
|
||||
|
||||
All deprecated methods were finally removed, after having yelled at you as
|
||||
an E_USER_NOTICE for a while now.
|
||||
|
||||
2.2 HTMLPurifier_ConfigSchema_Interchange
|
||||
|
||||
Member variable $namespaces was removed.
|
||||
|
||||
2.3 HTMLPurifier_ConfigSchema_Interchange_Id
|
||||
|
||||
Member variable $namespace and $directive removed; member variable $key added.
|
||||
Any method that took $namespace, $directive now takes $key.
|
||||
|
||||
2.4 HTMLPurifier_ConfigSchema_Interchange_Namespace
|
||||
|
||||
Removed.
|
||||
|
||||
vim: et sw=4 sts=4
|
@@ -1,164 +0,0 @@
|
||||
Configuration naming
|
||||
|
||||
HTML Purifier 4.0.0 features a new configuration naming system that
|
||||
allows arbitrary nesting of namespaces. While there are certain cases
|
||||
in which using two namespaces is obviously better (the canonical example
|
||||
is where we were using AutoFormatParam to contain directives for AutoFormat
|
||||
parameters), it is unclear whether or not a general migration to highly
|
||||
namespaced directives is a good idea or not.
|
||||
|
||||
== Case studies ==
|
||||
|
||||
=== Attr.* ===
|
||||
|
||||
We have a dead duck HTML.Attr.Name.UseCDATA which migrated before we decided
|
||||
to think this out thoroughly.
|
||||
|
||||
We currently have a large number of directives in the Attr.* namespace.
|
||||
These directives tweak the behavior of some HTML attributes. They have
|
||||
the properties:
|
||||
|
||||
* While they apply to only one attribute at a time, the attribute can
|
||||
span over multiple elements (not necessarily all attributes, either).
|
||||
The information of which elements it impacts is either omitted or
|
||||
informally stated (EnableID applies to all elements, DefaultImageAlt
|
||||
applies to <img> tags, AllowedRev doesn't say but only applies to a tags).
|
||||
|
||||
* There is a certain degree of clustering that could be applied, especially
|
||||
to the ID directives. The clustering could be done with respect to
|
||||
what element/attribute was used, i.e.
|
||||
|
||||
*.id -> EnableID, IDBlacklistRegexp, IDBlacklist, IDPrefixLocal, IDPrefix
|
||||
img.src -> DefaultInvalidImage
|
||||
img.alt -> DefaultImageAlt, DefaultInvalidImageAlt
|
||||
bdo.dir -> DefaultTextDir
|
||||
a.rel -> AllowedRel
|
||||
a.rev -> AllowedRev
|
||||
a.target -> AllowedFrameTargets
|
||||
a.name -> Name.UseCDATA
|
||||
|
||||
* The directives often reference generic attribute types that were specified
|
||||
in the DTD/specification. However, some of the behavior specifically relies
|
||||
on the fact that other use cases of the attribute are not, at current,
|
||||
supported by HTML Purifier.
|
||||
|
||||
AllowedRel, AllowedRev -> heavily <a> specific; if <link> ends up being
|
||||
allowed, we will also have to give users specificity there (we also
|
||||
want to preserve generality) DTD %Linktypes, HTML5 distinguishes
|
||||
between <link> and <a>/<area>
|
||||
AllowedFrameTargets -> heavily <a> specific, but also used by <area>
|
||||
and <form>. Transitional DTD %FrameTarget, not present in strict,
|
||||
HTML5 calls them "browsing contexts"
|
||||
Default*Image* -> as a default parameter, is almost entirely exlcusive
|
||||
to <img>
|
||||
EnableID -> global attribute
|
||||
Name.UseCDATA -> heavily <a> specific, but has heavy other usage by
|
||||
many things
|
||||
|
||||
== AutoFormat.* ==
|
||||
|
||||
These have the fairly normal pluggable architecture that lends itself to
|
||||
large amounts of namespaces (pluggability may be the key to figuring
|
||||
out when gratuitous namespacing is good.) Properties:
|
||||
|
||||
* Boolean directives are fair game for being namespaced: for example,
|
||||
RemoveEmpty.RemoveNbsp triggers RemoveEmpty.RemoveNbsp.Exceptions,
|
||||
the latter of which only makes sense when RemoveEmpty.RemoveNbsp
|
||||
is set to true. (The same applies to RemoveNbsp too)
|
||||
|
||||
The AutoFormat string is a bit long, but is the only bit of repeated
|
||||
context.
|
||||
|
||||
== Core.* ==
|
||||
|
||||
Core is the potpourri of directives, mostly regarding some minor behavioral
|
||||
tweaks for HTML handling abilities.
|
||||
|
||||
AggressivelyFixLt
|
||||
ConvertDocumentToFragment
|
||||
DirectLexLineNumberSyncInterval
|
||||
LexerImpl
|
||||
MaintainLineNumbers
|
||||
Lexer
|
||||
CollectErrors
|
||||
Language
|
||||
Error handling (Language is ostensibly a little more general, but
|
||||
it's only used for error handling right now)
|
||||
ColorKeywords
|
||||
CSS and HTML
|
||||
Encoding
|
||||
EscapeNonASCIICharacters
|
||||
Character encoding
|
||||
EscapeInvalidChildren
|
||||
EscapeInvalidTags
|
||||
HiddenElements
|
||||
RemoveInvalidImg
|
||||
Lexing/Output
|
||||
RemoveScriptContents
|
||||
Deprecated
|
||||
|
||||
== HTML.* ==
|
||||
|
||||
AllowedAttributes
|
||||
AllowedElements
|
||||
AllowedModules
|
||||
Allowed
|
||||
ForbiddenAttributes
|
||||
ForbiddenElements
|
||||
Element set tuning
|
||||
BlockWrapper
|
||||
Child def advanced twiddle
|
||||
CoreModules
|
||||
CustomDoctype
|
||||
Advanced HTMLModuleManager twiddles
|
||||
DefinitionID
|
||||
DefinitionRev
|
||||
Caching
|
||||
Doctype
|
||||
Parent
|
||||
Strict
|
||||
XHTML
|
||||
Global environment
|
||||
MaxImgLength
|
||||
Attribute twiddle? (applies to two attributes)
|
||||
Proprietary
|
||||
SafeEmbed
|
||||
SafeObject
|
||||
Trusted
|
||||
Extra functionality/tagsets
|
||||
TidyAdd
|
||||
TidyLevel
|
||||
TidyRemove
|
||||
Tidy
|
||||
|
||||
== Output.* ==
|
||||
|
||||
These directly affect the output of Generator. These are all advanced
|
||||
twiddles.
|
||||
|
||||
== URI.* ==
|
||||
|
||||
AllowedSchemes
|
||||
OverrideAllowedSchemes
|
||||
Scheme tuning
|
||||
Base
|
||||
DefaultScheme
|
||||
Host
|
||||
Global environment
|
||||
DefinitionID
|
||||
DefinitionRev
|
||||
Caching
|
||||
DisableExternalResources
|
||||
DisableExternal
|
||||
DisableResources
|
||||
Disable
|
||||
Contextual/authority tuning
|
||||
HostBlacklist
|
||||
Authority tuning
|
||||
MakeAbsolute
|
||||
MungeResources
|
||||
MungeSecretKey
|
||||
Munge
|
||||
Transformation behavior (munge can be grouped)
|
||||
|
||||
|
@@ -114,7 +114,7 @@ Test.Example</pre>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>VALUE-ALIASES</td>
|
||||
<td>'baz' => 'bar'</td>
|
||||
<td>'baz' => 'bar'</td>
|
||||
<td><em>Optional</em>. Mapping of one value to another, and
|
||||
should be a comma separated list of keypair duples. This
|
||||
is only allowed string, istring, text and itext TYPEs.</td>
|
||||
@@ -213,7 +213,7 @@ Test.Example</pre>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lookup</td>
|
||||
<td>array('key' => true)</td>
|
||||
<td>array('key' => true)</td>
|
||||
<td>Lookup array, used with <code>isset($var[$key])</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -223,7 +223,7 @@ Test.Example</pre>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>hash</td>
|
||||
<td>array('key' => 'val')</td>
|
||||
<td>array('key' => 'val')</td>
|
||||
<td>Associative array of keys to values</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -239,15 +239,15 @@ Test.Example</pre>
|
||||
object; users have a little bit of leeway when setting configuration
|
||||
values (for example, a lookup value can be specified as a list;
|
||||
HTML Purifier will flip it as necessary.) These types are defined
|
||||
in <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/VarParser.php">
|
||||
in <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/VarParser.php">
|
||||
library/HTMLPurifier/VarParser.php</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more information on what values are allowed, and how they are parsed,
|
||||
consult <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
||||
consult <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
||||
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php</a>, as well
|
||||
as <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/Interchange/Directive.php">
|
||||
as <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ConfigSchema/Interchange/Directive.php">
|
||||
library/HTMLPurifier/ConfigSchema/Interchange/Directive.php</a> for
|
||||
the semantics of the parsed values.
|
||||
</p>
|
||||
@@ -267,47 +267,12 @@ Test.Example</pre>
|
||||
If you ever make changes to your configuration directives, you
|
||||
will need to run this script again.
|
||||
</p>
|
||||
<h2>Adding in-house schema definitions</h2>
|
||||
|
||||
<p>
|
||||
Placing stuff directly in HTML Purifier's source tree is generally not a
|
||||
good idea, so HTML Purifier 4.0.0+ has some facilities in place to make your
|
||||
life easier.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The first is to pass an extra parameter to <code>maintenance/generate-schema-cache.php</code>
|
||||
with the location of your directory (relative or absolute path will do). For example,
|
||||
if I'm storing my custom definitions in <em>/var/htmlpurifier/myschema</em>, run:
|
||||
<code>php maintenance/generate-schema-cache.php /var/htmlpurifier/myschema</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Alternatively, you can create a small loader PHP file in the HTML Purifier base
|
||||
directory named <code>config-schema.php</code> (this is the same directory
|
||||
you would place a <code>test-settings.php</code> file). In this file, add
|
||||
the following line for each directory you want to load:
|
||||
</p>
|
||||
|
||||
<pre>$builder->buildDir($interchange, '/var/htmlpurifier/myschema');</pre>
|
||||
|
||||
<p>You can even load a single file using:</p>
|
||||
|
||||
<pre>$builder->buildFile($interchange, '/var/htmlpurifier/myschema/MyApp.Directive.txt');</pre>
|
||||
|
||||
<p>Storing custom definitions that you don't plan on sending back upstream in
|
||||
a separate directory is <em>definitely</em> a good idea! Additionally, picking
|
||||
a good namespace can go a long way to saving you grief if you want to use
|
||||
someone else's change, but they picked the same name, or if HTML Purifier
|
||||
decides to add support for a configuration directive that has the same name.</p>
|
||||
|
||||
<!-- TODO: how to name directives that rely on naming conventions -->
|
||||
|
||||
<h2>Errors</h2>
|
||||
|
||||
<p>
|
||||
All directive files go through a rigorous validation process
|
||||
through <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/Validator.php">
|
||||
through <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ConfigSchema/">
|
||||
library/HTMLPurifier/ConfigSchema/Validator.php</a>, as well
|
||||
as some basic checks during building. While
|
||||
listing every error out here is out-of-scope for this document, we
|
||||
@@ -374,7 +339,7 @@ Test.Example</pre>
|
||||
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
|
||||
correspondence currently. If the two formats diverge, any discrepancies
|
||||
will be described in <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
||||
will be described in <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
||||
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php</a>.
|
||||
</p>
|
||||
|
||||
@@ -405,8 +370,7 @@ Test.Example</pre>
|
||||
data. There is also an XML serializer, which is used to build documentation.
|
||||
</p>
|
||||
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -62,7 +62,6 @@
|
||||
do.
|
||||
</p>
|
||||
|
||||
</body></html>
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
</body></html>
|
||||
|
@@ -277,5 +277,3 @@ DEPRECATED-VERSION: If the directive was deprecated, when was it deprecated?
|
||||
DEPRECATED-USE: If the directive was deprecated, what should the user use now?
|
||||
REQUIRES: What classes does this configuration directive require, but are
|
||||
not part of the HTML Purifier core?
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -77,7 +77,6 @@ help you find the correct functionality more quickly. Here they are:</p>
|
||||
|
||||
</dl>
|
||||
|
||||
</body></html>
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
</body></html>
|
||||
|
@@ -27,7 +27,6 @@ that itch, put it here!</p>
|
||||
<li>Parallelize strategies</li>
|
||||
</ul>
|
||||
|
||||
</body></html>
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
</body></html>
|
||||
|
@@ -255,7 +255,7 @@ Mozilla on inside and needs -moz-outline, no IE support.</td></tr>
|
||||
<tr class="feature"><td>axis</td><td>TD, TH</td><td>W3C only: No browser implementation</td></tr>
|
||||
<tr class="feature"><td>char</td><td>COL, COLGROUP, TBODY, TD, TFOOT, TH, THEAD, TR</td><td>W3C only: No browser implementation</td></tr>
|
||||
<tr class="feature"><td>headers</td><td>TD, TH</td><td>W3C only: No browser implementation</td></tr>
|
||||
<tr class="impl-yes"><td>scope</td><td>TD, TH</td><td>W3C only: No browser implementation</td></tr>
|
||||
<tr class="feature"><td>scope</td><td>TD, TH</td><td>W3C only: No browser implementation</td></tr>
|
||||
</tbody>
|
||||
|
||||
<tbody class="impl-yes">
|
||||
@@ -303,7 +303,6 @@ Mozilla on inside and needs -moz-outline, no IE support.</td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</body></html>
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
</body></html>
|
||||
|
@@ -18,11 +18,12 @@
|
||||
<div id="home"><a href="http://htmlpurifier.org/">HTML Purifier</a> End-User Documentation</div>
|
||||
|
||||
<p>
|
||||
HTML Purifier has this quirk where if you try to allow certain elements or
|
||||
attributes, HTML Purifier will tell you that it's not supported, and that
|
||||
you should go to the forums to find out how to implement it. Well, this
|
||||
document is how to implement elements and attributes which HTML Purifier
|
||||
doesn't support out of the box.
|
||||
You may have heard of the <a href="dev-advanced-api.html">Advanced API</a>.
|
||||
If you're interested in reading dry prose and boring functional
|
||||
specifications, feel free to click that link to get a no-nonsense overview
|
||||
on the Advanced API. For the rest of us, there's this tutorial. By the time
|
||||
you're finished reading this, you should have a pretty good idea on
|
||||
how to implement custom tags and attributes that HTML Purifier may not have.
|
||||
</p>
|
||||
|
||||
<h2>Is it necessary?</h2>
|
||||
@@ -83,6 +84,17 @@
|
||||
limited to translations) above or below other corresponding text.
|
||||
</p>
|
||||
|
||||
<h3>XHTML 2.0</h3>
|
||||
|
||||
<p>
|
||||
<a href="http://www.w3.org/TR/xhtml2/">XHTML 2.0</a> is still a
|
||||
working draft, so any elements introduced in the
|
||||
specification have not been implemented and will not be implemented
|
||||
until we get a recommendation or proposal. Because XHTML 2.0 is
|
||||
an entirely new markup language, implementing rules for it will be
|
||||
no easy task.
|
||||
</p>
|
||||
|
||||
<h3>HTML 5</h3>
|
||||
|
||||
<p>
|
||||
@@ -144,11 +156,9 @@
|
||||
</p>
|
||||
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
if ($def = $config->maybeGetRawHTMLDefinition()) {
|
||||
// our code will go here
|
||||
}</pre>
|
||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML', 'DefinitionRev', 1);
|
||||
$def = $config->getHTMLDefinition(true);</pre>
|
||||
|
||||
<p>
|
||||
Assuming that HTML Purifier has already been properly loaded (hint:
|
||||
@@ -176,15 +186,23 @@ if ($def = $config->maybeGetRawHTMLDefinition()) {
|
||||
</li>
|
||||
<li>
|
||||
The fourth line retrieves a raw <code>HTMLPurifier_HTMLDefinition</code>
|
||||
object that we will be tweaking. Interestingly enough, we have
|
||||
placed it in an if block: this is because
|
||||
<code>maybeGetRawHTMLDefinition</code>, as its name suggests, may
|
||||
return a NULL, in which case we should skip doing any
|
||||
initialization. This, in fact, will correspond to when our fully
|
||||
customized object is already in the cache.
|
||||
object that we will be tweaking. If the parameter was removed, we
|
||||
would be retrieving a fully formed definition object, which is somewhat
|
||||
useless for customization purposes.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Broken backwards-compatibility</h3>
|
||||
|
||||
<p>
|
||||
Those of you who have already been twiddling around with the raw
|
||||
HTML definition object, you'll be noticing that you're getting an error
|
||||
when you attempt to retrieve the raw definition object without specifying
|
||||
a DefinitionID. It is vital to caching (see below) that you make a unique
|
||||
name for your customized definition, so make up something right now and
|
||||
things will operate again.
|
||||
</p>
|
||||
|
||||
<h2>Turn off caching</h2>
|
||||
|
||||
<p>
|
||||
@@ -193,10 +211,10 @@ if ($def = $config->maybeGetRawHTMLDefinition()) {
|
||||
</p>
|
||||
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
<strong>$config->set('Cache.DefinitionImpl', null); // TODO: remove this later!</strong>
|
||||
$def = $config->getHTMLDefinition(true);</pre>
|
||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML', 'DefinitionRev', 1);
|
||||
<strong>$config->set('Core', 'DefinitionCache', null); // remove this later!</strong>
|
||||
$def = $config->getHTMLDefinition(true);</pre>
|
||||
|
||||
<p>
|
||||
A few things should be mentioned about the caching mechanism before
|
||||
@@ -249,10 +267,10 @@ $def = $config->getHTMLDefinition(true);</pre>
|
||||
</p>
|
||||
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
$config->set('Cache.DefinitionImpl', null); // remove this later!
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML', 'DefinitionRev', 1);
|
||||
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
<strong>$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');</strong></pre>
|
||||
|
||||
<p>
|
||||
@@ -354,10 +372,10 @@ $def = $config->getHTMLDefinition(true);
|
||||
|
||||
<p>
|
||||
For a complete list, consult
|
||||
<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>;
|
||||
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/AttrTypes.php"><code>library/HTMLPurifier/AttrTypes.php</code></a>;
|
||||
more information on attributes that accept parameters can be found on their
|
||||
respective includes in
|
||||
<a href="http://repo.or.cz/w/htmlpurifier.git?a=tree;hb=HEAD;f=library/HTMLPurifier/AttrDef"><code>library/HTMLPurifier/AttrDef</code></a>.
|
||||
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/AttrDef/"><code>library/HTMLPurifier/AttrDef</code></a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -367,11 +385,11 @@ $def = $config->getHTMLDefinition(true);
|
||||
</p>
|
||||
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
$config->set('Cache.DefinitionImpl', null); // remove this later!
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
<strong>$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML', 'DefinitionRev', 1);
|
||||
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
<strong>$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||
array('_blank','_self','_target','_top')
|
||||
));</strong></pre>
|
||||
|
||||
@@ -706,7 +724,7 @@ $def = $config->getHTMLDefinition(true);
|
||||
or more flow elements, but no nested <code>form</code>s</strong></li>
|
||||
<li>What attributes does the element allow that are general? <strong>Common</strong></li>
|
||||
<li>What attributes does the element allow that are specific to this element? <strong>A whole bunch, see ATTLIST;
|
||||
we're going to do the vital ones: <code>action</code>, <code>method</code> and <code>name</code></strong></li>
|
||||
we're going to the vital ones: <code>action</code>, <code>method</code> and <code>name</code></strong></li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
@@ -714,14 +732,14 @@ $def = $config->getHTMLDefinition(true);
|
||||
</p>
|
||||
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
$config->set('Cache.DefinitionImpl', null); // remove this later!
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML', 'DefinitionRev', 1);
|
||||
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||
array('_blank','_self','_target','_top')
|
||||
));
|
||||
<strong>$form = $def->addElement(
|
||||
<strong>$form = $def->addElement(
|
||||
'form', // name
|
||||
'Block', // content set
|
||||
'Flow', // allowed children
|
||||
@@ -732,7 +750,7 @@ $def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||
'name' => 'ID'
|
||||
)
|
||||
);
|
||||
$form->excludes = array('form' => true);</strong></pre>
|
||||
$form->excludes = array('form' => true);</strong></pre>
|
||||
|
||||
<p>
|
||||
Each of the parameters corresponds to one of the questions we asked.
|
||||
@@ -746,7 +764,7 @@ $form->excludes = array('form' => true);</strong></pre>
|
||||
<p>
|
||||
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
|
||||
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
|
||||
check the <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/HTMLModule/"><code>library/HTMLPurifier/HTMLModule/</code></a> directory
|
||||
in your local HTML Purifier installation.
|
||||
</p>
|
||||
|
||||
@@ -771,80 +789,10 @@ $form->excludes = array('form' => true);</strong></pre>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<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://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ElementDef.php"><code>library/HTMLPurifier/ElementDef.php</code></a></li>
|
||||
<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://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ElementDef.php"><code>library/HTMLPurifier/ElementDef.php</code></a></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="optimized">Notes for HTML Purifier 4.2.0 and earlier</h3>
|
||||
|
||||
<p>
|
||||
Previously, this tutorial gave some incorrect template code for
|
||||
editing raw definitions, and that template code will now produce the
|
||||
error <q>Due to a documentation error in previous version of HTML
|
||||
Purifier...</q> Here is how to mechanically transform old-style
|
||||
code into new-style code.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
First, identify all code that edits the raw definition object, and
|
||||
put it together. Ensure none of this code must be run on every
|
||||
request; if some sub-part needs to always be run, move it outside
|
||||
this block. Here is an example below, with the raw definition
|
||||
object code bolded.
|
||||
</p>
|
||||
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
<strong>$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');</strong>
|
||||
$purifier = new HTMLPurifier($config);</pre>
|
||||
|
||||
<p>
|
||||
Next, replace the raw definition retrieval with a
|
||||
maybeGetRawHTMLDefinition method call inside an if conditional, and
|
||||
place the editing code inside that if block.
|
||||
</p>
|
||||
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
<strong>if ($def = $config->maybeGetRawHTMLDefinition()) {
|
||||
$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');
|
||||
}</strong>
|
||||
$purifier = new HTMLPurifier($config);</pre>
|
||||
|
||||
<p>
|
||||
And you're done! Alternatively, if you're OK with not ever caching
|
||||
your code, the following will still work and not emit warnings.
|
||||
</p>
|
||||
|
||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||
$def = $config->getHTMLDefinition(true);
|
||||
$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');
|
||||
$purifier = new HTMLPurifier($config);</pre>
|
||||
|
||||
<p>
|
||||
A slightly less efficient version of this was what was going on with
|
||||
old versions of HTML Purifier.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<em>Technical notes:</em> ajh pointed out on <a
|
||||
href="http://htmlpurifier.org/phorum/read.php?5,5164,5169#msg-5169">in a forum topic</a> that
|
||||
HTML Purifier appeared to be repeatedly writing to the cache even
|
||||
when a cache entry already existed. Investigation lead to the
|
||||
discovery of the following infelicity: caching of customized
|
||||
definitions didn't actually work! The problem was that even though
|
||||
a cache file would be written out at the end of the process, there
|
||||
was no way for HTML Purifier to say, <q>Actually, I've already got a
|
||||
copy of your work, no need to reconfigure your
|
||||
customizations</q>. This required the API to change: placing
|
||||
all of the customizations to the raw definition object in a
|
||||
conditional which could be skipped.
|
||||
</p>
|
||||
<div id="version">$Id: enduser-tidy.html 1158 2007-06-18 19:26:29Z Edward $</div>
|
||||
|
||||
</body></html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -31,7 +31,7 @@ by default.</p>
|
||||
|
||||
<p>IDs, however, are quite useful functionality to have, so if users start
|
||||
complaining about broken anchors you'll probably want to turn them back on
|
||||
with %Attr.EnableID. But before you go mucking around with the config
|
||||
with %HTML.EnableAttrID. But before you go mucking around with the config
|
||||
object, it's probably worth to take some precautions to keep your page
|
||||
validating. Why?</p>
|
||||
|
||||
@@ -56,8 +56,8 @@ validating. Why?</p>
|
||||
deal with the most obvious solution: preventing users from using any IDs that
|
||||
appear elsewhere on the document. The method is simple:</p>
|
||||
|
||||
<pre>$config->set('Attr.EnableID', true);
|
||||
$config->set('Attr.IDBlacklist' array(
|
||||
<pre>$config->set('HTML', 'EnableAttrID', true);
|
||||
$config->set('Attr', 'IDBlacklist' array(
|
||||
'list', 'of', 'attribute', 'values', 'that', 'are', 'forbidden'
|
||||
));</pre>
|
||||
|
||||
@@ -88,8 +88,8 @@ all, they might have simply specified a duplicate ID by accident.</p>
|
||||
<p>This method, too, is quite simple: add a prefix to all user IDs. With this
|
||||
code:</p>
|
||||
|
||||
<pre>$config->set('Attr.EnableID', true);
|
||||
$config->set('Attr.IDPrefix', 'user_');</pre>
|
||||
<pre>$config->set('HTML', 'EnableAttrID', true);
|
||||
$config->set('Attr', 'IDPrefix', 'user_');</pre>
|
||||
|
||||
<p>...this:</p>
|
||||
|
||||
@@ -109,7 +109,7 @@ user_ to the beginning."</p>
|
||||
nothing about multiple HTML Purifier outputs on one page. Thus, we have
|
||||
a second configuration value to piggy-back off of: %Attr.IDPrefixLocal:</p>
|
||||
|
||||
<pre>$config->set('Attr.IDPrefixLocal', 'comment' . $id . '_');</pre>
|
||||
<pre>$config->set('Attr', 'IDPrefixLocal', 'comment' . $id . '_');</pre>
|
||||
|
||||
<p>This new attributes does nothing but append on to regular IDPrefix, but is
|
||||
special in that it is volatile: it's value is determined at run-time and
|
||||
@@ -137,12 +137,11 @@ anchors is beyond me.</p>
|
||||
|
||||
<p>To revert back to pre-1.2.0 behavior, simply:</p>
|
||||
|
||||
<pre>$config->set('Attr.EnableID', true);</pre>
|
||||
<pre>$config->set('HTML', 'EnableAttrID', true);</pre>
|
||||
|
||||
<p>Don't come crying to me when your page mysteriously stops validating, though.</p>
|
||||
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -55,5 +55,3 @@ HTML tags. Things like blog comments are, in all likelihood, most appropriately
|
||||
written in an extremely restrictive set of markup that doesn't require
|
||||
all this functionality (or not written in HTML at all), although this may
|
||||
be changing in the future with the addition of levels of filtering.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -14,5 +14,3 @@ to be effective. Things to remember:
|
||||
|
||||
4. CSS: document pending
|
||||
Explain which CSS styles we blocked and why.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -115,6 +115,3 @@ if you decide to do that! Especially if you port HTML Purifier to C++.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -76,7 +76,7 @@ associated with it, although it may change depending on your doctype.</p>
|
||||
change the level of cleaning by setting the %HTML.TidyLevel configuration
|
||||
directive:</p>
|
||||
|
||||
<pre>$config->set('HTML.TidyLevel', 'heavy'); // burn baby burn!</pre>
|
||||
<pre>$config->set('HTML', 'TidyLevel', 'heavy'); // burn baby burn!</pre>
|
||||
|
||||
<h2>Is the light level really light?</h2>
|
||||
|
||||
@@ -165,17 +165,17 @@ smoketest</a>.</p>
|
||||
so happy about the br@clear implementation. That's perfectly fine!
|
||||
HTML Purifier will make accomodations:</p>
|
||||
|
||||
<pre>$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
|
||||
$config->set('HTML.TidyLevel', 'heavy'); // all changes, minus...
|
||||
<strong>$config->set('HTML.TidyRemove', 'br@clear');</strong></pre>
|
||||
<pre>$config->set('HTML', 'Doctype', 'XHTML 1.0 Transitional');
|
||||
$config->set('HTML', 'TidyLevel', 'heavy'); // all changes, minus...
|
||||
<strong>$config->set('HTML', 'TidyRemove', 'br@clear');</strong></pre>
|
||||
|
||||
<p>That third line does the magic, removing the br@clear fix
|
||||
from the module, ensuring that <code><br clear="both" /></code>
|
||||
will pass through unharmed. The reverse is possible too:</p>
|
||||
|
||||
<pre>$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
|
||||
$config->set('HTML.TidyLevel', 'none'); // no changes, plus...
|
||||
<strong>$config->set('HTML.TidyAdd', 'p@align');</strong></pre>
|
||||
<pre>$config->set('HTML', 'Doctype', 'XHTML 1.0 Transitional');
|
||||
$config->set('HTML', 'TidyLevel', 'none'); // no changes, plus...
|
||||
<strong>$config->set('HTML', 'TidyAdd', 'p@align');</strong></pre>
|
||||
|
||||
<p>In this case, all transformations are shut off, except for the p@align
|
||||
one, which you found handy.</p>
|
||||
@@ -225,7 +225,6 @@ 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
|
||||
effectively in the background.</p>
|
||||
|
||||
</body></html>
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
</body></html>
|
||||
|
@@ -130,26 +130,30 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Let's suppose I wanted to write a filter that converted links with a
|
||||
custom <code>image</code> scheme to its corresponding real path on
|
||||
our website:
|
||||
Let's suppose I wanted to write a filter that de-internationalized domain
|
||||
names by converting them to <a href="http://en.wikipedia.org/wiki/Punycode">Punycode</a>.
|
||||
Assuming that <code>punycode_encode($input)</code> converts <code>$input</code> to
|
||||
Punycode and returns <code>false</code> on failure:
|
||||
</p>
|
||||
|
||||
<pre>class HTMLPurifier_URIFilter_TransformImageScheme extends HTMLPurifier_URIFilter
|
||||
<pre>class HTMLPurifier_URIFilter_ConvertIDNToPunycode extends HTMLPurifier_URIFilter
|
||||
{
|
||||
public $name = 'TransformImageScheme';
|
||||
public $name = 'ConvertIDNToPunycode';
|
||||
public function filter(&$uri, $config, $context) {
|
||||
if ($uri->scheme !== 'image') return true;
|
||||
$img_name = $uri->path;
|
||||
// Overwrite the previous URI object
|
||||
$uri = new HTMLPurifier_URI('http', null, null, null, '/img/' . $img_name . '.png', null, null);
|
||||
if (is_null($uri->host)) return true;
|
||||
if ($uri->host == utf8_decode($uri->host)) {
|
||||
// is ASCII, abort
|
||||
return true;
|
||||
}
|
||||
$host = punycode_encode($uri->host);
|
||||
if ($host === false) return false;
|
||||
$uri->host = $host;
|
||||
return true;
|
||||
}
|
||||
}</pre>
|
||||
|
||||
<p>
|
||||
Notice I did not <code>return $uri;</code>. This filter would turn
|
||||
<code>image:Foo</code> into <code>/img/Foo.png</code>.
|
||||
Notice I did not <code>return $uri;</code>.
|
||||
</p>
|
||||
|
||||
<h2>Activating your filter</h2>
|
||||
@@ -160,45 +164,38 @@
|
||||
</p>
|
||||
|
||||
<pre>$uri = $config->getDefinition('URI');
|
||||
$uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>(), $config);</pre>
|
||||
$uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pre>
|
||||
|
||||
<p>
|
||||
After adding a filter, you won't be able to set configuration directives.
|
||||
Structure your code accordingly.
|
||||
If you want to be really fancy, you can define a configuration directive
|
||||
for your filter and have HTML Purifier automatically manage whether or
|
||||
not your filter gets loaded or not (this is how internal filters manage
|
||||
things):
|
||||
</p>
|
||||
|
||||
<!-- XXX: link to new documentation system -->
|
||||
|
||||
<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>HTMLPurifier_ConfigSchema::define(
|
||||
'URI', '<strong>NameOfFilter</strong>', false, 'bool',
|
||||
'<strong>What your filter does.</strong>'
|
||||
);
|
||||
$uri = $config->getDefinition('URI', true);
|
||||
$uri->registerFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Now, your filter will only be called when %URI.<strong>NameOfFilter</strong>
|
||||
is set to true.
|
||||
</p>
|
||||
|
||||
<h2>Examples</h2>
|
||||
|
||||
<p>
|
||||
Check the
|
||||
<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="proposal-new-directives.txt">the
|
||||
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/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
|
||||
new directives proposal document</a> for ideas on what could be implemented
|
||||
as a filter.
|
||||
</p>
|
||||
|
||||
</body></html>
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
</body></html>
|
||||
|
@@ -118,8 +118,9 @@ there are now many character encodings floating around.</p>
|
||||
see a page on the web, chances are it's encoded in one
|
||||
of these encodings.</li>
|
||||
<li><strong>Unicode-based encodings</strong> implement the
|
||||
Unicode standard and include UTF-8, UTF-16 and UTF-32/UCS-4.
|
||||
They go beyond 8-bits and support almost
|
||||
Unicode standard and include UTF-8, UCS-2 and UTF-16.
|
||||
They go beyond 8-bits (the first two are variable length,
|
||||
while the second one uses 16-bits), and support almost
|
||||
every language in the world. UTF-8 is gaining traction
|
||||
as the dominant international encoding of the web.</li>
|
||||
</ul>
|
||||
@@ -481,7 +482,7 @@ if we don't know it's character encoding? And how do we figure out
|
||||
the character encoding, if we don't know the contents of the
|
||||
<code>META</code> tag?</p>
|
||||
|
||||
<p>Fortunately for us, the characters we need to write the
|
||||
<p>Fortunantely for us, the characters we need to write the
|
||||
<code>META</code> are in ASCII, which is pretty much universal
|
||||
over every character encoding that is in common use today. So,
|
||||
all the web-browser has to do is parse all the way down until
|
||||
@@ -526,7 +527,7 @@ you don't have to use those user-unfriendly entities.</p>
|
||||
|
||||
<h3 id="whyutf8-user">User-friendly</h3>
|
||||
|
||||
<p>Websites encoded in Latin-1 (ISO-8859-1) which occasionally need
|
||||
<p>Websites encoded in Latin-1 (ISO-8859-1) which ocassionally need
|
||||
a special character outside of their scope often will use a character
|
||||
entity reference to achieve the desired effect. For instance, θ can be
|
||||
written <code>&theta;</code>, regardless of the character encoding's
|
||||
@@ -561,7 +562,7 @@ page on special characters</a> for more details.
|
||||
<h3 id="whyutf8-forms">Forms</h3>
|
||||
|
||||
<p>While we're on the tack of users, how do non-UTF-8 web forms deal
|
||||
with characters that are outside of their character set? Rather than
|
||||
with characters that our outside of their character set? Rather than
|
||||
discuss what UTF-8 does right, we're going to show what could go wrong
|
||||
if you didn't use UTF-8 and people tried to use characters outside
|
||||
of your character encoding.</p>
|
||||
@@ -584,15 +585,13 @@ disappeared off the web, so I am linking to the Web Archive copy.)</p>
|
||||
<h4 id="whyutf8-forms-urlencoded"><code>application/x-www-form-urlencoded</code></h4>
|
||||
|
||||
<p>This is the Content-Type that GET requests must use, and POST requests
|
||||
use by default. It involves the ubiquitous percent encoding format that
|
||||
use by default. It involves the ubiquituous percent encoding format that
|
||||
looks something like: <code>%C3%86</code>. There is no official way of
|
||||
determining the character encoding of such a request, since the percent
|
||||
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
|
||||
in. (<a href="http://tools.ietf.org/html/rfc3986#section-2.5">RFC 3986</a>
|
||||
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>
|
||||
in. 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
|
||||
(and this is a lot more common than you may think: take curly
|
||||
@@ -674,7 +673,7 @@ it up to the module iconv to do the dirty work.</p>
|
||||
<p>This approach, however, is not perfect. iconv is blithely unaware
|
||||
of HTML character entities. HTML Purifier, in order to
|
||||
protect against sophisticated escaping schemes, normalizes all character
|
||||
and numeric entity references before processing the text. This leads to
|
||||
and numeric entitie references before processing the text. This leads to
|
||||
one important ramification:</p>
|
||||
|
||||
<p><strong>Any character that is not supported by the target character
|
||||
@@ -770,7 +769,7 @@ the text when you try to convert it to UTF-8. You'll have to convert
|
||||
it to a binary field, convert it to a Shift-JIS field (the real encoding),
|
||||
and then finally to UTF-8. Many a website had pages irreversibly mangled
|
||||
because they didn't realize that they'd been deluding themselves about
|
||||
the character encoding all along; don't become the next victim.</p>
|
||||
the character encoding all along, don't become the next victim.</p>
|
||||
|
||||
<p>For <a href="http://www.postgresql.org/docs/8.2/static/multibyte.html">PostgreSQL</a>, there appears to be no direct way to change the
|
||||
encoding of a database (as of 8.2). You will have to dump the data, and then reimport
|
||||
@@ -790,7 +789,7 @@ usually supported).</p>
|
||||
|
||||
<h4 id="migrate-db-binary">Binary</h4>
|
||||
|
||||
<p>Due to the aforementioned compatibility issues, a more interoperable
|
||||
<p>Due to the abovementioned compatibility issues, a more interoperable
|
||||
way of storing UTF-8 text is to stuff it in a binary datatype.
|
||||
<code>CHAR</code> becomes <code>BINARY</code>, <code>VARCHAR</code> becomes
|
||||
<code>VARBINARY</code> and <code>TEXT</code> becomes <code>BLOB</code>.
|
||||
@@ -917,8 +916,8 @@ anyway. So we'll deal with the other two edge cases.</p>
|
||||
would like to read your website but get heaps of question marks or
|
||||
other meaningless characters. Fixing this problem requires the
|
||||
installation of a font or language pack which is often highly
|
||||
dependent on what the language is. <a href="http://bn.wikipedia.org/wiki/%E0%A6%89%E0%A6%87%E0%A6%95%E0%A6%BF%E0%A6%AA%E0%A7%87%E0%A6%A1%E0%A6%BF%E0%A6%AF%E0%A6%BC%E0%A6%BE:Bangla_script_display_and_input_help">Here is an example</a>
|
||||
of such a help file for the Bengali language; I am sure there are
|
||||
dependent on what the language is. <a href="http://bn.wikipedia.org/wiki/%E0%A6%89%E0%A6%87%E0%A6%95%E0%A6%BF%E0%A6%AA%E0%A7%87%E0%A6%A1%E0%A6%BF%E0%A6%AF%E0%A6%BC%E0%A6%BE:Bangla_script_display_help">Here is an example</a>
|
||||
of such a help file for the Bengali language, I am sure there are
|
||||
others out there too. You just have to point users to the appropriate
|
||||
help file.</p>
|
||||
|
||||
@@ -928,7 +927,7 @@ help file.</p>
|
||||
characters embedded in what otherwise would be very bland ASCII are
|
||||
letters of the
|
||||
<a href="http://en.wikipedia.org/wiki/International_Phonetic_Alphabet">International
|
||||
Phonetic Alphabet (IPA)</a>, use to designate pronunciations in a very standard
|
||||
Phonetic Alphabet (IPA)</a>, use to designate pronounciations in a very standard
|
||||
manner (you probably see them all the time in your dictionary). Your
|
||||
average font probably won't have support for all of the IPA characters
|
||||
like ʘ (bilabial click) or ʒ (voiced postalveolar fricative).
|
||||
@@ -941,11 +940,11 @@ most widely used browser in the entire world? Microsoft IE 6
|
||||
is not smart enough to borrow from other fonts when a character isn't
|
||||
present, so more often than not you'll be slapped with a nice big �.
|
||||
To get things to work, MSIE 6 needs a little nudge. You could configure it
|
||||
to use a different font to render the text, but you can achieve the same
|
||||
to use a different font to render the text, but you can acheive the same
|
||||
effect by selectively changing the font for blocks of special characters
|
||||
to known good Unicode fonts.</p>
|
||||
|
||||
<p>Fortunately, the folks over at Wikipedia have already done all the
|
||||
<p>Fortunantely, the folks over at Wikipedia have already done all the
|
||||
heavy lifting for you. Get the CSS from the horses mouth here:
|
||||
<a href="http://en.wikipedia.org/wiki/MediaWiki:Common.css">Common.css</a>,
|
||||
and search for ".IPA" There are also a smattering of
|
||||
@@ -972,7 +971,7 @@ users.</p>
|
||||
<h3 id="migrate-variablewidth">Dealing with variable width in functions</h3>
|
||||
|
||||
<p>When people claim that PHP6 will solve all our Unicode problems, they're
|
||||
misinformed. It will not fix any of the aforementioned troubles. It will,
|
||||
misinformed. It will not fix any of the abovementioned troubles. It will,
|
||||
however, fix the problem we are about to discuss: processing UTF-8 text
|
||||
in PHP.</p>
|
||||
|
||||
@@ -1035,7 +1034,7 @@ directory.</p>
|
||||
<p>Well, that's it. Hopefully this document has served as a very
|
||||
practical springboard into knowledge of how UTF-8 works. You may have
|
||||
decided that you don't want to migrate yet: that's fine, just know
|
||||
what will happen to your output and what bug reports you may receive.</p>
|
||||
what will happen to your output and what bug reports you may recieve.</p>
|
||||
|
||||
<p>Many other developers have already discussed the subject of Unicode,
|
||||
UTF-8 and internationalization, and I would like to defer to them for
|
||||
@@ -1055,6 +1054,3 @@ a more in-depth look into character sets and encodings.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -67,15 +67,15 @@ into your documents. YouTube's code goes like this:</p>
|
||||
</ol>
|
||||
|
||||
<p>What point 2 means is that if we have code like <code><span
|
||||
class="youtube-embed">AyPzM5WK8ys</span></code> your
|
||||
class="embed-youtube">AyPzM5WK8ys</span></code> your
|
||||
application can reconstruct the full object from this small snippet that
|
||||
passes through HTML Purifier <em>unharmed</em>.
|
||||
<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>
|
||||
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/Filter/YouTube.php">Show me the code!</a></p>
|
||||
|
||||
<p>And the corresponding usage:</p>
|
||||
|
||||
<pre><?php
|
||||
$config->set('Filter.YouTube', true);
|
||||
$config->set('Filter', 'YouTube', true);
|
||||
?></pre>
|
||||
|
||||
<p>There is a bit going in the two code snippets, so let's explain.</p>
|
||||
@@ -148,6 +148,3 @@ with the core!</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -8,8 +8,8 @@ require_once '../../library/HTMLPurifier.auto.php';
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
|
||||
// configuration goes here:
|
||||
$config->set('Core.Encoding', 'UTF-8'); // replace with your encoding
|
||||
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional'); // replace with your doctype
|
||||
$config->set('Core', 'Encoding', 'UTF-8'); // replace with your encoding
|
||||
$config->set('HTML', 'Doctype', 'XHTML 1.0 Transitional'); // replace with your doctype
|
||||
|
||||
$purifier = new HTMLPurifier($config);
|
||||
|
||||
@@ -20,4 +20,3 @@ $pure_html = $purifier->purify($html);
|
||||
|
||||
echo '<pre>' . htmlspecialchars($pure_html) . '</pre>';
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -4,6 +4,3 @@ function init() {
|
||||
element.innerHTML = '“'+element.innerHTML+'”';
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -98,8 +98,8 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
||||
<table class="table">
|
||||
|
||||
<thead><tr>
|
||||
<th style="width:10%">Type</th>
|
||||
<th style="width:20%">Name</th>
|
||||
<th width="10%">Type</th>
|
||||
<th width="20%">Name</th>
|
||||
<th>Description</th>
|
||||
</tr></thead>
|
||||
|
||||
@@ -117,12 +117,6 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
||||
<td>Common security issues that may still arise (half-baked).</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Development</td>
|
||||
<td><a href="dev-config-bcbreaks.txt">Config BC Breaks</a></td>
|
||||
<td>Backwards-incompatible changes in HTML Purifier 4.0.0</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Development</td>
|
||||
<td><a href="dev-code-quality.txt">Code Quality Issues</a></td>
|
||||
@@ -181,8 +175,6 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
||||
|
||||
</table>
|
||||
|
||||
<div id="version">$Id$</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -42,8 +42,7 @@ into the mix.</li>
|
||||
something like that?</li>
|
||||
</ol>
|
||||
|
||||
<div id="version">$Id$</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -19,5 +19,3 @@ Definition objects are complex datatypes influenced by their respective
|
||||
directive namespaces (HTMLDefinition with HTML and CSSDefinition with CSS).
|
||||
If any of these directives is updated, HTML Purifier forces the definition
|
||||
to be regenerated.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -30,5 +30,3 @@ Beyond that, HTML Purifier can magically merge common CSS values together,
|
||||
and a whole manner of other heuristic things. HTML Purifier should also
|
||||
make it easy for an admin to re-style the HTML semantically. Speed is not
|
||||
an issue. Also, better WYSIWYG editors are needed.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -1,211 +0,0 @@
|
||||
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)
|
||||
|
||||
vim: et sw=4 sts=4
|
@@ -133,5 +133,3 @@ Dramatic - border, list-style-position (list-style), margin, padding,
|
||||
|
||||
Dramatic elements substantially change the look of text in ways that should
|
||||
probably have been reserved to other areas.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -60,5 +60,3 @@ Neat functionality:
|
||||
- Roman numeral formatting
|
||||
|
||||
Items marked with a + likely need to be addressed by HTML Purifier
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -41,4 +41,3 @@ implemented, give us a ring, and we'll move it up the priority chain.
|
||||
absolute DNS. While this is actually the preferred method according to
|
||||
the RFC, most people opt to use a relative domain name relative to . (root).
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -1,218 +0,0 @@
|
||||
THE UNIVERSAL DESIGN PATTERN: PROPERTIES
|
||||
Steve Yegge
|
||||
|
||||
Implementation:
|
||||
get(name)
|
||||
put(name, value)
|
||||
has(name)
|
||||
remove(name)
|
||||
iteration, with filtering [this will be our namespaces]
|
||||
parent
|
||||
|
||||
Representations:
|
||||
- Keys are strings
|
||||
- It's nice to not need to quote keys (if we formulate our own language,
|
||||
consider this)
|
||||
- Property not present representation (key missing)
|
||||
- Frequent removal/re-add may have null help. If null is valid, use
|
||||
another value. (PHP semantics are weird here)
|
||||
|
||||
Data structures:
|
||||
- LinkedHashMap is wonderful (O(1) access and maintains order)
|
||||
- Using a special property that points to the parent is usual
|
||||
- Multiple inheritance possible, need rules for which to lookup first
|
||||
- Iterative inheritance is best
|
||||
- Consider performance!
|
||||
|
||||
Deletion
|
||||
- Tricky problem with inheritance
|
||||
- Distinguish between "not found" and "look in my parent for the property"
|
||||
[Maybe HTML Purifier won't allow deletion]
|
||||
|
||||
Read/write asymmetry (it's correct!)
|
||||
|
||||
Read-only plists
|
||||
- Allow ability to freeze [this is what we have already]
|
||||
- Don't overuse it
|
||||
|
||||
Performance:
|
||||
- Intern strings (PHP does this already)
|
||||
- Don't be case-insensitive
|
||||
- If all properties in a plist are known a-priori, you can use a "perfect"
|
||||
hash function. Often overkill.
|
||||
- Copy-on-read caching "plundering" reduces lookup, but uses memory and can
|
||||
grow stale. Use as last resort.
|
||||
- Refactoring to fields. Watch for API compatibility, system complexity,
|
||||
and lack of flexibility.
|
||||
- Refrigerator: external data-structure to hold plists
|
||||
|
||||
Transient properties:
|
||||
[Don't need to worry about this]
|
||||
- Use a separate plist for transient properties
|
||||
- Non-numeric override; numeric should ADD
|
||||
- Deletion: removeTransientProperty() and transientlyRemoveProperty()
|
||||
|
||||
Persistence:
|
||||
- XML/JSON are good
|
||||
- Text-based is good for readability, maintainability and bootstrapping
|
||||
- Compressed binary format for network transport [not necessary]
|
||||
- RDBMS or XML database
|
||||
|
||||
Querying: [not relevant]
|
||||
- XML database is nice for XPath/XQuery
|
||||
- jQuery for JSON
|
||||
- Just load it all into a program
|
||||
|
||||
Backfills/Data integrity:
|
||||
- Use usual methods
|
||||
- Lazy backfill is a nice hack
|
||||
|
||||
Type systems:
|
||||
- Flags: ReadOnly, Permanent, DontEnum
|
||||
- Typed properties isn't that useful [It's also Not-PHP]
|
||||
- Seperate meta-list of directive properties IS useful
|
||||
- Duck typing is useful for systems designed fully around properties pattern
|
||||
|
||||
Trade-off:
|
||||
+ Flexibility
|
||||
+ Extensibility
|
||||
+ Unit-testing/prototype-speed
|
||||
- Performance
|
||||
- Data integrity
|
||||
- Navagability/Query-ability
|
||||
- Reversability (hard to go back)
|
||||
|
||||
HTML Purifier
|
||||
|
||||
We are not happy with our current system of defining configuration directives,
|
||||
because it has become clear that things will get a lot nicer if we allow
|
||||
multiple namespaces, and there are some features that naturally lend themselves
|
||||
to inheritance, which we do not really support well.
|
||||
|
||||
One of the considered implementation changes would be to go from a structure
|
||||
like:
|
||||
|
||||
array(
|
||||
'Namespace' => array(
|
||||
'Directive' => 'val1',
|
||||
'Directive2' => 'val2',
|
||||
)
|
||||
)
|
||||
|
||||
to:
|
||||
|
||||
array(
|
||||
'Namespace.Directive' => 'val1',
|
||||
'Namespace.Directive2' => 'val2',
|
||||
)
|
||||
|
||||
The below implementation takes more memory, however, and it makes it a bit
|
||||
complicated to grab all values from a namespace.
|
||||
|
||||
The alternate implementation choice is to allow nested plists. This keeps
|
||||
iteration easy, but is problematic for inheritance (it would be difficult
|
||||
to distinguish a plist from an array) and retrieval (when specifying multiple
|
||||
namespaces we would need some multiple de-referencing).
|
||||
|
||||
----
|
||||
|
||||
We can bite the performance hit, and just do iteration with filter
|
||||
(the strncmp call should be relatively cheap). Then, users should be able
|
||||
to optimize doing something like:
|
||||
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
if (!file_exists('config.php')) {
|
||||
// set up $config
|
||||
$config->save('config.php');
|
||||
} else {
|
||||
$config->load('config.php');
|
||||
}
|
||||
|
||||
Or maybe memcache, or something. This means that "// set up $config" must
|
||||
not have any dynamic parts, or the user has to invalidate the cache when
|
||||
they do update it. We have to think about this a little more carefully; the
|
||||
file call might be more expensive.
|
||||
|
||||
----
|
||||
|
||||
This might get expensive, however, when we actually care about iterating
|
||||
over the configuration and want the actual values. So what about nesting the
|
||||
lists?
|
||||
|
||||
"ns.sub.directive" => values['ns']['sub']['directive']
|
||||
|
||||
We can distinguish between plists and arrays by using ArrayObjects for the
|
||||
plists, and regular arrays for the arrays? Alternatively, use ArrayObjects
|
||||
for the arrays, and regular arrays for the plists.
|
||||
|
||||
----
|
||||
|
||||
Implementation demands, and what has caused them:
|
||||
|
||||
1. DefinitionCache, the HTML, CSS and URI namespaces have caches attached to them
|
||||
Results:
|
||||
- getBatchSerial()
|
||||
- getBatch() : in general, the ability to traverse just a namespace
|
||||
|
||||
2. AutoFormat/Filter, this is a plugin architecture, directives not hard-coded
|
||||
- getBatch()
|
||||
|
||||
3. Configuration form
|
||||
- Namespaces used to organize directives
|
||||
|
||||
Other than that, we have a pure plist. PERHAPS we should maintain separate things
|
||||
for these different demands.
|
||||
|
||||
Issue 2: Directives for configuring the plugins are regular plists, but
|
||||
when enabling them, while it's "plist-ish", what you're really doing is adding
|
||||
them to an array of "autoformatters"/"filters" to enable. We can setup
|
||||
magic BC as well as in the new interface, but there should also be an
|
||||
add('AutoFormat', 'AutoParagraph'); which does the right thing.
|
||||
|
||||
One thing to consider is whether or not inheritance rules will apply to these.
|
||||
I'd say yes. That means that they're still plisty, in fact, the underlying
|
||||
implementation will probably be a plist. However, they will get their OWN
|
||||
plists, and will NOT support nesting.
|
||||
|
||||
Issue 1: Our current implementation is generally not efficient; md5(serialize($foo))
|
||||
is pretty expensive. So, I don't think there will be any problems if it
|
||||
gets "less" efficient, as long as we give users a properly fast alternative;
|
||||
DefinitionRev gives us a way to do this, by simply telling the user they must
|
||||
update it whenever they update Configuration directives as well. (There are
|
||||
obvious BC concerns here).
|
||||
|
||||
In such a case, we simply iterate over our plist (performing full retrievals
|
||||
for each value), grab the entries we care about, and then serialize and hash.
|
||||
It's going to be slow either way, due to the ability of plists to inherit.
|
||||
If we ksort(), we don't have to traverse the entire array, however, the
|
||||
cost of a ksort() call may not be worth it.
|
||||
|
||||
At this point, last time, I started worrying about the performance implications
|
||||
of allowing inheritance, and wondering whether or not I wanted to squash
|
||||
the plist. At first blush, our code might be under the assumption that
|
||||
accessing properties is cheap; but actually we prefer to copy out the value
|
||||
into a member variable if it's going to be used many times. With this is mind
|
||||
I don't think CPU consumption from a few nested function calls is going to
|
||||
be a problem. We *are* going to enforce a function only interface.
|
||||
|
||||
The next issue at hand is how we're going to manage the "special" plists,
|
||||
which should still be able to be inherited. Basically, it means that multiple
|
||||
plists would be attached to the configuration object, which is not the
|
||||
best for memory performance. The alternative is to keep them all in one
|
||||
big plist, and then eat the one-time cost of traversing the entire plist
|
||||
to grab the appropriate values.
|
||||
|
||||
I think at this point we can write the generic interface, and then set up separate
|
||||
plists if that ends up being necessary for performance (it probably won't.) Now
|
||||
lets code our generic plist implementation.
|
||||
|
||||
----
|
||||
|
||||
Iterating over the plist presents some problems. The way we've chosen to solve
|
||||
this is to squash all of the parents.
|
||||
|
||||
----
|
||||
|
||||
But I don't need iteration.
|
||||
|
||||
vim: et sw=4 sts=4
|
@@ -46,5 +46,3 @@ is eliminated completely, in the latter case, the text of the node
|
||||
would is preserved (as the parent node does allow PCDATA). Custom
|
||||
content model implementations probably are not the best way of handling
|
||||
these cases, instead, node bubbling should be implemented instead.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -26,5 +26,3 @@ Watch out: font-sizes can also be nested to get successively larger
|
||||
(although I do not relish having to keep track of context font-sizes,
|
||||
this may be necessary, especially for some of the more advanced features
|
||||
for preventing things like white on white).
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -40,8 +40,6 @@ the development of this library in these forum threads:</p>
|
||||
|
||||
<p>...as well as any I may have forgotten.</p>
|
||||
|
||||
<div id="version">$Id$</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
-->
|
||||
|
@@ -162,5 +162,3 @@ array of content set names to content set contents. If the content set
|
||||
already exists, your values are appended on to it (great for, say,
|
||||
registering the font tag as an inline element), otherwise it is
|
||||
created. They are substituted into content_model.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -22,5 +22,3 @@ HTML Purifier context.
|
||||
|
||||
These should be put into their own Tidy module, not loaded by default(?). These
|
||||
all qualify as "lenient" transforms.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -22,5 +22,3 @@ another DirectLex parser, other parsers like ph5p
|
||||
<http://jero.net/lab/ph5p/> can be adapted to DOMLex to support much more
|
||||
flexible HTML parsing (a cool feature I've seen is how they resolve
|
||||
<b>bold<i>both</b>italic</i>).
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -6,5 +6,3 @@ windows-live-mail-desktop-beta.html - donated by laacz, public domain
|
||||
img.png - LGPL, from <http://commons.wikimedia.org/wiki/Image:Pastille_chrome.png>
|
||||
|
||||
All other files are by me, and are licensed under LGPL.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -1,129 +0,0 @@
|
||||
<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>
|
@@ -72,5 +72,3 @@ q:after {
|
||||
.fixme:before {content:"Fix me: "; font-weight:bold; color:#C00; }
|
||||
|
||||
#applicability {margin: 1em 5%; font-style:italic;}
|
||||
|
||||
/* vim: et sw=4 sts=4 */
|
||||
|
@@ -11,8 +11,7 @@ class ConfigDoc_HTMLXSLTProcessor
|
||||
*/
|
||||
protected $xsltProcessor;
|
||||
|
||||
public function __construct($proc = false)
|
||||
{
|
||||
public function __construct($proc = false) {
|
||||
if ($proc === false) $proc = new XSLTProcessor();
|
||||
$this->xsltProcessor = $proc;
|
||||
}
|
||||
@@ -20,8 +19,7 @@ class ConfigDoc_HTMLXSLTProcessor
|
||||
/**
|
||||
* @note Allows a string $xsl filename to be passed
|
||||
*/
|
||||
public function importStylesheet($xsl)
|
||||
{
|
||||
public function importStylesheet($xsl) {
|
||||
if (is_string($xsl)) {
|
||||
$xsl_file = $xsl;
|
||||
$xsl = new DOMDocument();
|
||||
@@ -36,8 +34,7 @@ class ConfigDoc_HTMLXSLTProcessor
|
||||
* @return string HTML output
|
||||
* @todo Rename to transformToXHTML, as transformToHTML is misleading
|
||||
*/
|
||||
public function transformToHTML($xml)
|
||||
{
|
||||
public function transformToHTML($xml) {
|
||||
if (is_string($xml)) {
|
||||
$dom = new DOMDocument();
|
||||
$dom->load($xml);
|
||||
@@ -71,8 +68,7 @@ class ConfigDoc_HTMLXSLTProcessor
|
||||
* Bulk sets parameters for the XSL stylesheet
|
||||
* @param array $options Associative array of options to set
|
||||
*/
|
||||
public function setParameters($options)
|
||||
{
|
||||
public function setParameters($options) {
|
||||
foreach ($options as $name => $value) {
|
||||
$this->xsltProcessor->setParameter('', $name, $value);
|
||||
}
|
||||
@@ -81,11 +77,9 @@ class ConfigDoc_HTMLXSLTProcessor
|
||||
/**
|
||||
* Forward any other calls to the XSLT processor
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
public function __call($name, $arguments) {
|
||||
call_user_func_array(array($this->xsltProcessor, $name), $arguments);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -15,8 +15,7 @@ class FSTools
|
||||
/**
|
||||
* Returns a global instance of FSTools
|
||||
*/
|
||||
public static function singleton()
|
||||
{
|
||||
static public function singleton() {
|
||||
if (empty(FSTools::$singleton)) FSTools::$singleton = new FSTools();
|
||||
return FSTools::$singleton;
|
||||
}
|
||||
@@ -25,8 +24,7 @@ class FSTools
|
||||
* Sets our global singleton to something else; useful for overloading
|
||||
* functions.
|
||||
*/
|
||||
public static function setSingleton($singleton)
|
||||
{
|
||||
static public function setSingleton($singleton) {
|
||||
FSTools::$singleton = $singleton;
|
||||
}
|
||||
|
||||
@@ -35,8 +33,7 @@ class FSTools
|
||||
* @param string $folder Name of folder to create
|
||||
* @note Adapted from the PHP manual comment 76612
|
||||
*/
|
||||
public function mkdirr($folder)
|
||||
{
|
||||
public function mkdirr($folder) {
|
||||
$folders = preg_split("#[\\\\/]#", $folder);
|
||||
$base = '';
|
||||
for($i = 0, $c = count($folders); $i < $c; $i++) {
|
||||
@@ -60,8 +57,7 @@ class FSTools
|
||||
* so that copied files, if PHP, have includes removed
|
||||
* @note Adapted from http://aidanlister.com/repos/v/function.copyr.php
|
||||
*/
|
||||
public function copyr($source, $dest)
|
||||
{
|
||||
public function copyr($source, $dest) {
|
||||
// Simple copy for a file
|
||||
if (is_file($source)) {
|
||||
return $this->copy($source, $dest);
|
||||
@@ -96,8 +92,7 @@ class FSTools
|
||||
* ignore hidden files, unreadable files, etc. This function
|
||||
* applies to copyr().
|
||||
*/
|
||||
public function copyable($file)
|
||||
{
|
||||
public function copyable($file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -136,8 +131,7 @@ class FSTools
|
||||
/**
|
||||
* Recursively globs a directory.
|
||||
*/
|
||||
public function globr($dir, $pattern, $flags = NULL)
|
||||
{
|
||||
public function globr($dir, $pattern, $flags = NULL) {
|
||||
$files = $this->glob("$dir/$pattern", $flags);
|
||||
if ($files === false) $files = array();
|
||||
$sub_dirs = $this->glob("$dir/*", GLOB_ONLYDIR);
|
||||
@@ -154,11 +148,8 @@ class FSTools
|
||||
* @warning This function will not work for functions that need
|
||||
* to pass references; manually define a stub function for those.
|
||||
*/
|
||||
public function __call($name, $args)
|
||||
{
|
||||
public function __call($name, $args) {
|
||||
return call_user_func_array($name, $args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -23,8 +23,7 @@ class FSTools_File
|
||||
* Filename of file you wish to instantiate.
|
||||
* @note This file need not exist
|
||||
*/
|
||||
public function __construct($name, $fs = false)
|
||||
{
|
||||
public function __construct($name, $fs = false) {
|
||||
$this->name = $name;
|
||||
$this->fs = $fs ? $fs : FSTools::singleton();
|
||||
}
|
||||
@@ -39,32 +38,27 @@ class FSTools_File
|
||||
* Retrieves the contents of a file
|
||||
* @todo Throw an exception if file doesn't exist
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
public function get() {
|
||||
return $this->fs->file_get_contents($this->name);
|
||||
}
|
||||
|
||||
/** Writes contents to a file, creates new file if necessary */
|
||||
public function write($contents)
|
||||
{
|
||||
public function write($contents) {
|
||||
return $this->fs->file_put_contents($this->name, $contents);
|
||||
}
|
||||
|
||||
/** Deletes the file */
|
||||
public function delete()
|
||||
{
|
||||
public function delete() {
|
||||
return $this->fs->unlink($this->name);
|
||||
}
|
||||
|
||||
/** Returns true if file exists and is a file. */
|
||||
public function exists()
|
||||
{
|
||||
public function exists() {
|
||||
return $this->fs->is_file($this->name);
|
||||
}
|
||||
|
||||
/** Returns last file modification time */
|
||||
public function getMTime()
|
||||
{
|
||||
public function getMTime() {
|
||||
return $this->fs->filemtime($this->name);
|
||||
}
|
||||
|
||||
@@ -73,22 +67,19 @@ class FSTools_File
|
||||
* @note We ignore errors because of some weird owner trickery due
|
||||
* to SVN duality
|
||||
*/
|
||||
public function chmod($octal_code)
|
||||
{
|
||||
public function chmod($octal_code) {
|
||||
return @$this->fs->chmod($this->name, $octal_code);
|
||||
}
|
||||
|
||||
/** Opens file's handle */
|
||||
public function open($mode)
|
||||
{
|
||||
public function open($mode) {
|
||||
if ($this->handle) $this->close();
|
||||
$this->handle = $this->fs->fopen($this->name, $mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Closes file's handle */
|
||||
public function close()
|
||||
{
|
||||
public function close() {
|
||||
if (!$this->handle) return false;
|
||||
$status = $this->fs->fclose($this->handle);
|
||||
$this->handle = false;
|
||||
@@ -96,46 +87,38 @@ class FSTools_File
|
||||
}
|
||||
|
||||
/** Retrieves a line from an open file, with optional max length $length */
|
||||
public function getLine($length = null)
|
||||
{
|
||||
public function getLine($length = null) {
|
||||
if (!$this->handle) $this->open('r');
|
||||
if ($length === null) return $this->fs->fgets($this->handle);
|
||||
else return $this->fs->fgets($this->handle, $length);
|
||||
}
|
||||
|
||||
/** Retrieves a character from an open file */
|
||||
public function getChar()
|
||||
{
|
||||
public function getChar() {
|
||||
if (!$this->handle) $this->open('r');
|
||||
return $this->fs->fgetc($this->handle);
|
||||
}
|
||||
|
||||
/** Retrieves an $length bytes of data from an open data */
|
||||
public function read($length)
|
||||
{
|
||||
public function read($length) {
|
||||
if (!$this->handle) $this->open('r');
|
||||
return $this->fs->fread($this->handle, $length);
|
||||
}
|
||||
|
||||
/** Writes to an open file */
|
||||
public function put($string)
|
||||
{
|
||||
public function put($string) {
|
||||
if (!$this->handle) $this->open('a');
|
||||
return $this->fs->fwrite($this->handle, $string);
|
||||
}
|
||||
|
||||
/** Returns TRUE if the end of the file has been reached */
|
||||
public function eof()
|
||||
{
|
||||
public function eof() {
|
||||
if (!$this->handle) return true;
|
||||
return $this->fs->feof($this->handle);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
public function __destruct() {
|
||||
if ($this->handle) $this->close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -7,5 +7,3 @@
|
||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
||||
require_once 'HTMLPurifierExtras.php';
|
||||
require_once 'HTMLPurifierExtras.autoload.php';
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -17,10 +17,7 @@ if (function_exists('spl_autoload_register')) {
|
||||
spl_autoload_register('__autoload');
|
||||
}
|
||||
} elseif (!function_exists('__autoload')) {
|
||||
function __autoload($class)
|
||||
{
|
||||
function __autoload($class) {
|
||||
return HTMLPurifierExtras::autoload($class);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -7,16 +7,14 @@
|
||||
class HTMLPurifierExtras
|
||||
{
|
||||
|
||||
public static function autoload($class)
|
||||
{
|
||||
public static function autoload($class) {
|
||||
$path = HTMLPurifierExtras::getPath($class);
|
||||
if (!$path) return false;
|
||||
require $path;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getPath($class)
|
||||
{
|
||||
public static function getPath($class) {
|
||||
if (
|
||||
strncmp('FSTools', $class, 7) !== 0 &&
|
||||
strncmp('ConfigDoc', $class, 9) !== 0
|
||||
@@ -27,5 +25,3 @@ class HTMLPurifierExtras
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -28,5 +28,3 @@ the filesystem. It currently consists of two classes:
|
||||
method imaginable one would need.
|
||||
|
||||
Check the files themselves for more information.
|
||||
|
||||
vim: et sw=4 sts=4
|
||||
|
@@ -7,5 +7,3 @@
|
||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
||||
require_once 'HTMLPurifier/Bootstrap.php';
|
||||
require_once 'HTMLPurifier.autoload.php';
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -3,7 +3,6 @@
|
||||
/**
|
||||
* @file
|
||||
* Convenience file that registers autoload handler for HTML Purifier.
|
||||
* It also does some sanity checks.
|
||||
*/
|
||||
|
||||
if (function_exists('spl_autoload_register') && function_exists('spl_autoload_unregister')) {
|
||||
@@ -14,14 +13,7 @@ if (function_exists('spl_autoload_register') && function_exists('spl_autoload_un
|
||||
spl_autoload_register('__autoload');
|
||||
}
|
||||
} elseif (!function_exists('__autoload')) {
|
||||
function __autoload($class)
|
||||
{
|
||||
function __autoload($class) {
|
||||
return HTMLPurifier_Bootstrap::autoload($class);
|
||||
}
|
||||
}
|
||||
|
||||
if (ini_get('zend.ze1_compatibility_mode')) {
|
||||
trigger_error("HTML Purifier is not compatible with zend.ze1_compatibility_mode; please turn it off", E_USER_ERROR);
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -1,4 +0,0 @@
|
||||
<?php
|
||||
if (!defined('HTMLPURIFIER_PREFIX')) {
|
||||
define('HTMLPURIFIER_PREFIX', dirname(__FILE__));
|
||||
}
|
@@ -8,13 +8,11 @@
|
||||
|
||||
/**
|
||||
* Purify HTML.
|
||||
* @param string $html String HTML to purify
|
||||
* @param mixed $config Configuration to use, can be any value accepted by
|
||||
* @param $html String HTML to purify
|
||||
* @param $config Configuration to use, can be any value accepted by
|
||||
* HTMLPurifier_Config::create()
|
||||
* @return string
|
||||
*/
|
||||
function HTMLPurifier($html, $config = null)
|
||||
{
|
||||
function HTMLPurifier($html, $config = null) {
|
||||
static $purifier = false;
|
||||
if (!$purifier) {
|
||||
$purifier = new HTMLPurifier();
|
||||
@@ -22,4 +20,3 @@ function HTMLPurifier($html, $config = null)
|
||||
return $purifier->purify($html, $config);
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
|
||||
* FILE, changes will be overwritten the next time the script is run.
|
||||
*
|
||||
* @version 4.8.0
|
||||
* @version 3.1.0
|
||||
*
|
||||
* @warning
|
||||
* You must *not* include any other HTML Purifier files before this file,
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
require 'HTMLPurifier.php';
|
||||
require 'HTMLPurifier/Arborize.php';
|
||||
require 'HTMLPurifier/AttrCollections.php';
|
||||
require 'HTMLPurifier/AttrDef.php';
|
||||
require 'HTMLPurifier/AttrTransform.php';
|
||||
@@ -30,6 +29,7 @@ require 'HTMLPurifier/Definition.php';
|
||||
require 'HTMLPurifier/CSSDefinition.php';
|
||||
require 'HTMLPurifier/ChildDef.php';
|
||||
require 'HTMLPurifier/Config.php';
|
||||
require 'HTMLPurifier/ConfigDef.php';
|
||||
require 'HTMLPurifier/ConfigSchema.php';
|
||||
require 'HTMLPurifier/ContentSets.php';
|
||||
require 'HTMLPurifier/Context.php';
|
||||
@@ -42,7 +42,6 @@ require 'HTMLPurifier/Encoder.php';
|
||||
require 'HTMLPurifier/EntityLookup.php';
|
||||
require 'HTMLPurifier/EntityParser.php';
|
||||
require 'HTMLPurifier/ErrorCollector.php';
|
||||
require 'HTMLPurifier/ErrorStruct.php';
|
||||
require 'HTMLPurifier/Exception.php';
|
||||
require 'HTMLPurifier/Filter.php';
|
||||
require 'HTMLPurifier/Generator.php';
|
||||
@@ -53,13 +52,8 @@ require 'HTMLPurifier/IDAccumulator.php';
|
||||
require 'HTMLPurifier/Injector.php';
|
||||
require 'HTMLPurifier/Language.php';
|
||||
require 'HTMLPurifier/LanguageFactory.php';
|
||||
require 'HTMLPurifier/Length.php';
|
||||
require 'HTMLPurifier/Lexer.php';
|
||||
require 'HTMLPurifier/Node.php';
|
||||
require 'HTMLPurifier/PercentEncoder.php';
|
||||
require 'HTMLPurifier/PropertyList.php';
|
||||
require 'HTMLPurifier/PropertyListIterator.php';
|
||||
require 'HTMLPurifier/Queue.php';
|
||||
require 'HTMLPurifier/Strategy.php';
|
||||
require 'HTMLPurifier/StringHash.php';
|
||||
require 'HTMLPurifier/StringHashParser.php';
|
||||
@@ -72,16 +66,12 @@ require 'HTMLPurifier/URIFilter.php';
|
||||
require 'HTMLPurifier/URIParser.php';
|
||||
require 'HTMLPurifier/URIScheme.php';
|
||||
require 'HTMLPurifier/URISchemeRegistry.php';
|
||||
require 'HTMLPurifier/UnitConverter.php';
|
||||
require 'HTMLPurifier/VarParser.php';
|
||||
require 'HTMLPurifier/VarParserException.php';
|
||||
require 'HTMLPurifier/Zipper.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS.php';
|
||||
require 'HTMLPurifier/AttrDef/Clone.php';
|
||||
require 'HTMLPurifier/AttrDef/Enum.php';
|
||||
require 'HTMLPurifier/AttrDef/Integer.php';
|
||||
require 'HTMLPurifier/AttrDef/Lang.php';
|
||||
require 'HTMLPurifier/AttrDef/Switch.php';
|
||||
require 'HTMLPurifier/AttrDef/Text.php';
|
||||
require 'HTMLPurifier/AttrDef/URI.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Number.php';
|
||||
@@ -95,7 +85,6 @@ require 'HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Filter.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Font.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Ident.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Length.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
||||
@@ -104,8 +93,6 @@ require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/URI.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Bool.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Class.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Color.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/ID.php';
|
||||
@@ -113,12 +100,12 @@ require 'HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Length.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/LinkTypes.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/MultiLength.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/Email.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/Host.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/IPv6.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
||||
require 'HTMLPurifier/AttrTransform/Background.php';
|
||||
require 'HTMLPurifier/AttrTransform/BdoDir.php';
|
||||
require 'HTMLPurifier/AttrTransform/BgColor.php';
|
||||
require 'HTMLPurifier/AttrTransform/BoolToCSS.php';
|
||||
@@ -126,27 +113,20 @@ require 'HTMLPurifier/AttrTransform/Border.php';
|
||||
require 'HTMLPurifier/AttrTransform/EnumToCSS.php';
|
||||
require 'HTMLPurifier/AttrTransform/ImgRequired.php';
|
||||
require 'HTMLPurifier/AttrTransform/ImgSpace.php';
|
||||
require 'HTMLPurifier/AttrTransform/Input.php';
|
||||
require 'HTMLPurifier/AttrTransform/Lang.php';
|
||||
require 'HTMLPurifier/AttrTransform/Length.php';
|
||||
require 'HTMLPurifier/AttrTransform/Name.php';
|
||||
require 'HTMLPurifier/AttrTransform/NameSync.php';
|
||||
require 'HTMLPurifier/AttrTransform/Nofollow.php';
|
||||
require 'HTMLPurifier/AttrTransform/SafeEmbed.php';
|
||||
require 'HTMLPurifier/AttrTransform/SafeObject.php';
|
||||
require 'HTMLPurifier/AttrTransform/SafeParam.php';
|
||||
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||
require 'HTMLPurifier/AttrTransform/TargetBlank.php';
|
||||
require 'HTMLPurifier/AttrTransform/TargetNoreferrer.php';
|
||||
require 'HTMLPurifier/AttrTransform/Textarea.php';
|
||||
require 'HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require 'HTMLPurifier/ChildDef/Custom.php';
|
||||
require 'HTMLPurifier/ChildDef/Empty.php';
|
||||
require 'HTMLPurifier/ChildDef/List.php';
|
||||
require 'HTMLPurifier/ChildDef/Required.php';
|
||||
require 'HTMLPurifier/ChildDef/Optional.php';
|
||||
require 'HTMLPurifier/ChildDef/StrictBlockquote.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/Null.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Serializer.php';
|
||||
@@ -155,49 +135,32 @@ require 'HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
||||
require 'HTMLPurifier/HTMLModule/Bdo.php';
|
||||
require 'HTMLPurifier/HTMLModule/CommonAttributes.php';
|
||||
require 'HTMLPurifier/HTMLModule/Edit.php';
|
||||
require 'HTMLPurifier/HTMLModule/Forms.php';
|
||||
require 'HTMLPurifier/HTMLModule/Hypertext.php';
|
||||
require 'HTMLPurifier/HTMLModule/Iframe.php';
|
||||
require 'HTMLPurifier/HTMLModule/Image.php';
|
||||
require 'HTMLPurifier/HTMLModule/Legacy.php';
|
||||
require 'HTMLPurifier/HTMLModule/List.php';
|
||||
require 'HTMLPurifier/HTMLModule/Name.php';
|
||||
require 'HTMLPurifier/HTMLModule/Nofollow.php';
|
||||
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||
require 'HTMLPurifier/HTMLModule/Object.php';
|
||||
require 'HTMLPurifier/HTMLModule/Presentation.php';
|
||||
require 'HTMLPurifier/HTMLModule/Proprietary.php';
|
||||
require 'HTMLPurifier/HTMLModule/Ruby.php';
|
||||
require 'HTMLPurifier/HTMLModule/SafeEmbed.php';
|
||||
require 'HTMLPurifier/HTMLModule/SafeObject.php';
|
||||
require 'HTMLPurifier/HTMLModule/SafeScripting.php';
|
||||
require 'HTMLPurifier/HTMLModule/Scripting.php';
|
||||
require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tables.php';
|
||||
require 'HTMLPurifier/HTMLModule/Target.php';
|
||||
require 'HTMLPurifier/HTMLModule/TargetBlank.php';
|
||||
require 'HTMLPurifier/HTMLModule/TargetNoreferrer.php';
|
||||
require 'HTMLPurifier/HTMLModule/Text.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy.php';
|
||||
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/Name.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
||||
require 'HTMLPurifier/Injector/AutoParagraph.php';
|
||||
require 'HTMLPurifier/Injector/DisplayLinkURI.php';
|
||||
require 'HTMLPurifier/Injector/Linkify.php';
|
||||
require 'HTMLPurifier/Injector/PurifierLinkify.php';
|
||||
require 'HTMLPurifier/Injector/RemoveEmpty.php';
|
||||
require 'HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
|
||||
require 'HTMLPurifier/Injector/SafeObject.php';
|
||||
require 'HTMLPurifier/Lexer/DOMLex.php';
|
||||
require 'HTMLPurifier/Lexer/DirectLex.php';
|
||||
require 'HTMLPurifier/Node/Comment.php';
|
||||
require 'HTMLPurifier/Node/Element.php';
|
||||
require 'HTMLPurifier/Node/Text.php';
|
||||
require 'HTMLPurifier/Strategy/Composite.php';
|
||||
require 'HTMLPurifier/Strategy/Core.php';
|
||||
require 'HTMLPurifier/Strategy/FixNesting.php';
|
||||
@@ -214,19 +177,13 @@ require 'HTMLPurifier/Token/Start.php';
|
||||
require 'HTMLPurifier/Token/Text.php';
|
||||
require 'HTMLPurifier/URIFilter/DisableExternal.php';
|
||||
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
|
||||
require 'HTMLPurifier/URIFilter/DisableResources.php';
|
||||
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
|
||||
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||
require 'HTMLPurifier/URIFilter/Munge.php';
|
||||
require 'HTMLPurifier/URIFilter/SafeIframe.php';
|
||||
require 'HTMLPurifier/URIScheme/data.php';
|
||||
require 'HTMLPurifier/URIScheme/file.php';
|
||||
require 'HTMLPurifier/URIScheme/ftp.php';
|
||||
require 'HTMLPurifier/URIScheme/http.php';
|
||||
require 'HTMLPurifier/URIScheme/https.php';
|
||||
require 'HTMLPurifier/URIScheme/mailto.php';
|
||||
require 'HTMLPurifier/URIScheme/news.php';
|
||||
require 'HTMLPurifier/URIScheme/nntp.php';
|
||||
require 'HTMLPurifier/URIScheme/tel.php';
|
||||
require 'HTMLPurifier/VarParser/Flexible.php';
|
||||
require 'HTMLPurifier/VarParser/Native.php';
|
||||
|
@@ -7,8 +7,7 @@
|
||||
|
||||
require_once dirname(__FILE__) . '/HTMLPurifier.auto.php';
|
||||
|
||||
function kses($string, $allowed_html, $allowed_protocols = null)
|
||||
{
|
||||
function kses($string, $allowed_html, $allowed_protocols = null) {
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$allowed_elements = array();
|
||||
$allowed_attributes = array();
|
||||
@@ -18,13 +17,12 @@ function kses($string, $allowed_html, $allowed_protocols = null)
|
||||
$allowed_attributes["$element.$attribute"] = true;
|
||||
}
|
||||
}
|
||||
$config->set('HTML.AllowedElements', $allowed_elements);
|
||||
$config->set('HTML.AllowedAttributes', $allowed_attributes);
|
||||
$config->set('HTML', 'AllowedElements', $allowed_elements);
|
||||
$config->set('HTML', 'AllowedAttributes', $allowed_attributes);
|
||||
$allowed_schemes = array();
|
||||
if ($allowed_protocols !== null) {
|
||||
$config->set('URI.AllowedSchemes', $allowed_protocols);
|
||||
$config->set('URI', 'AllowedSchemes', $allowed_protocols);
|
||||
}
|
||||
$purifier = new HTMLPurifier($config);
|
||||
return $purifier->purify($string);
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -7,5 +7,3 @@
|
||||
*/
|
||||
|
||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
HTML Purifier 4.8.0 - Standards Compliant HTML Filtering
|
||||
HTML Purifier 3.1.0 - Standards Compliant HTML Filtering
|
||||
Copyright (C) 2006-2008 Edward Z. Yang
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
@@ -54,97 +54,66 @@
|
||||
class HTMLPurifier
|
||||
{
|
||||
|
||||
/**
|
||||
* Version of HTML Purifier.
|
||||
* @type string
|
||||
*/
|
||||
public $version = '4.8.0';
|
||||
/** Version of HTML Purifier */
|
||||
public $version = '3.1.0';
|
||||
|
||||
/**
|
||||
* Constant with version of HTML Purifier.
|
||||
*/
|
||||
const VERSION = '4.8.0';
|
||||
/** Constant with version of HTML Purifier */
|
||||
const VERSION = '3.1.0';
|
||||
|
||||
/**
|
||||
* Global configuration object.
|
||||
* @type HTMLPurifier_Config
|
||||
*/
|
||||
/** Global configuration object */
|
||||
public $config;
|
||||
|
||||
/**
|
||||
* Array of extra filter objects to run on HTML,
|
||||
* for backwards compatibility.
|
||||
* @type HTMLPurifier_Filter[]
|
||||
*/
|
||||
/** Array of extra HTMLPurifier_Filter objects to run on HTML, for backwards compatibility */
|
||||
private $filters = array();
|
||||
|
||||
/**
|
||||
* Single instance of HTML Purifier.
|
||||
* @type HTMLPurifier
|
||||
*/
|
||||
/** Single instance of HTML Purifier */
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_Strategy_Core
|
||||
*/
|
||||
protected $strategy;
|
||||
protected $strategy, $generator;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_Generator
|
||||
*/
|
||||
protected $generator;
|
||||
|
||||
/**
|
||||
* Resultant context of last run purification.
|
||||
* Is an array of contexts if the last called method was purifyArray().
|
||||
* @type HTMLPurifier_Context
|
||||
* Resultant HTMLPurifier_Context of last run purification. Is an array
|
||||
* of contexts if the last called method was purifyArray().
|
||||
*/
|
||||
public $context;
|
||||
|
||||
/**
|
||||
* Initializes the purifier.
|
||||
*
|
||||
* @param HTMLPurifier_Config|mixed $config Optional HTMLPurifier_Config object
|
||||
* for all instances of the purifier, if omitted, a default
|
||||
* configuration is supplied (which can be overridden on a
|
||||
* per-use basis).
|
||||
* @param $config Optional HTMLPurifier_Config object for all instances of
|
||||
* the purifier, if omitted, a default configuration is
|
||||
* supplied (which can be overridden on a per-use basis).
|
||||
* The parameter can also be any type that
|
||||
* HTMLPurifier_Config::create() supports.
|
||||
*/
|
||||
public function __construct($config = null)
|
||||
{
|
||||
public function __construct($config = null) {
|
||||
|
||||
$this->config = HTMLPurifier_Config::create($config);
|
||||
|
||||
$this->strategy = new HTMLPurifier_Strategy_Core();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a filter to process the output. First come first serve
|
||||
*
|
||||
* @param HTMLPurifier_Filter $filter HTMLPurifier_Filter object
|
||||
* @param $filter HTMLPurifier_Filter object
|
||||
*/
|
||||
public function addFilter($filter)
|
||||
{
|
||||
trigger_error(
|
||||
'HTMLPurifier->addFilter() is deprecated, use configuration directives' .
|
||||
' in the Filter namespace or Filter.Custom',
|
||||
E_USER_WARNING
|
||||
);
|
||||
public function addFilter($filter) {
|
||||
trigger_error('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom', E_USER_WARNING);
|
||||
$this->filters[] = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters an HTML snippet/document to be XSS-free and standards-compliant.
|
||||
*
|
||||
* @param string $html String of HTML to purify
|
||||
* @param HTMLPurifier_Config $config Config object for this operation,
|
||||
* if omitted, defaults to the config object specified during this
|
||||
* @param $html String of HTML to purify
|
||||
* @param $config HTMLPurifier_Config object for this operation, if omitted,
|
||||
* defaults to the config object specified during this
|
||||
* object's construction. The parameter can also be any type
|
||||
* that HTMLPurifier_Config::create() supports.
|
||||
*
|
||||
* @return string Purified HTML
|
||||
* @return Purified HTML
|
||||
*/
|
||||
public function purify($html, $config = null)
|
||||
{
|
||||
public function purify($html, $config = null) {
|
||||
|
||||
// :TODO: make the config merge in, instead of replace
|
||||
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
|
||||
|
||||
@@ -159,7 +128,7 @@ class HTMLPurifier
|
||||
$context->register('Generator', $this->generator);
|
||||
|
||||
// set up global context variables
|
||||
if ($config->get('Core.CollectErrors')) {
|
||||
if ($config->get('Core', 'CollectErrors')) {
|
||||
// may get moved out if other facilities use it
|
||||
$language_factory = HTMLPurifier_LanguageFactory::instance();
|
||||
$language = $language_factory->create($config, $context);
|
||||
@@ -182,12 +151,7 @@ class HTMLPurifier
|
||||
unset($filter_flags['Custom']);
|
||||
$filters = array();
|
||||
foreach ($filter_flags as $filter => $flag) {
|
||||
if (!$flag) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($filter, '.') !== false) {
|
||||
continue;
|
||||
}
|
||||
if (!$flag) continue;
|
||||
$class = "HTMLPurifier_Filter_$filter";
|
||||
$filters[] = new $class;
|
||||
}
|
||||
@@ -210,12 +174,9 @@ class HTMLPurifier
|
||||
// list of un-purified tokens
|
||||
$lexer->tokenizeHTML(
|
||||
// un-purified HTML
|
||||
$html,
|
||||
$config,
|
||||
$context
|
||||
$html, $config, $context
|
||||
),
|
||||
$config,
|
||||
$context
|
||||
$config, $context
|
||||
)
|
||||
);
|
||||
|
||||
@@ -230,15 +191,11 @@ class HTMLPurifier
|
||||
|
||||
/**
|
||||
* Filters an array of HTML snippets
|
||||
*
|
||||
* @param string[] $array_of_html Array of html snippets
|
||||
* @param HTMLPurifier_Config $config Optional config object for this operation.
|
||||
* @param $config Optional HTMLPurifier_Config object for this operation.
|
||||
* See HTMLPurifier::purify() for more details.
|
||||
*
|
||||
* @return string[] Array of purified HTML
|
||||
* @return Array of purified HTML
|
||||
*/
|
||||
public function purifyArray($array_of_html, $config = null)
|
||||
{
|
||||
public function purifyArray($array_of_html, $config = null) {
|
||||
$context_array = array();
|
||||
foreach ($array_of_html as $key => $html) {
|
||||
$array_of_html[$key] = $this->purify($html, $config);
|
||||
@@ -250,16 +207,11 @@ class HTMLPurifier
|
||||
|
||||
/**
|
||||
* Singleton for enforcing just one HTML Purifier in your system
|
||||
*
|
||||
* @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype
|
||||
* HTMLPurifier instance to overload singleton with,
|
||||
* or HTMLPurifier_Config instance to configure the
|
||||
* generated version with.
|
||||
*
|
||||
* @return HTMLPurifier
|
||||
* @param $prototype Optional prototype HTMLPurifier instance to
|
||||
* overload singleton with, or HTMLPurifier_Config
|
||||
* instance to configure the generated version with.
|
||||
*/
|
||||
public static function instance($prototype = null)
|
||||
{
|
||||
public static function instance($prototype = null) {
|
||||
if (!self::$instance || $prototype) {
|
||||
if ($prototype instanceof HTMLPurifier) {
|
||||
self::$instance = $prototype;
|
||||
@@ -273,20 +225,10 @@ class HTMLPurifier
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton for enforcing just one HTML Purifier in your system
|
||||
*
|
||||
* @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype
|
||||
* HTMLPurifier instance to overload singleton with,
|
||||
* or HTMLPurifier_Config instance to configure the
|
||||
* generated version with.
|
||||
*
|
||||
* @return HTMLPurifier
|
||||
* @note Backwards compatibility, see instance()
|
||||
*/
|
||||
public static function getInstance($prototype = null)
|
||||
{
|
||||
public static function getInstance($prototype = null) {
|
||||
return HTMLPurifier::instance($prototype);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
}
|
||||
|
@@ -13,7 +13,6 @@
|
||||
$__dir = dirname(__FILE__);
|
||||
|
||||
require_once $__dir . '/HTMLPurifier.php';
|
||||
require_once $__dir . '/HTMLPurifier/Arborize.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrCollections.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform.php';
|
||||
@@ -24,6 +23,7 @@ require_once $__dir . '/HTMLPurifier/Definition.php';
|
||||
require_once $__dir . '/HTMLPurifier/CSSDefinition.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/Config.php';
|
||||
require_once $__dir . '/HTMLPurifier/ConfigDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/ConfigSchema.php';
|
||||
require_once $__dir . '/HTMLPurifier/ContentSets.php';
|
||||
require_once $__dir . '/HTMLPurifier/Context.php';
|
||||
@@ -36,7 +36,6 @@ require_once $__dir . '/HTMLPurifier/Encoder.php';
|
||||
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
|
||||
require_once $__dir . '/HTMLPurifier/EntityParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
|
||||
require_once $__dir . '/HTMLPurifier/ErrorStruct.php';
|
||||
require_once $__dir . '/HTMLPurifier/Exception.php';
|
||||
require_once $__dir . '/HTMLPurifier/Filter.php';
|
||||
require_once $__dir . '/HTMLPurifier/Generator.php';
|
||||
@@ -47,13 +46,8 @@ require_once $__dir . '/HTMLPurifier/IDAccumulator.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector.php';
|
||||
require_once $__dir . '/HTMLPurifier/Language.php';
|
||||
require_once $__dir . '/HTMLPurifier/LanguageFactory.php';
|
||||
require_once $__dir . '/HTMLPurifier/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer.php';
|
||||
require_once $__dir . '/HTMLPurifier/Node.php';
|
||||
require_once $__dir . '/HTMLPurifier/PercentEncoder.php';
|
||||
require_once $__dir . '/HTMLPurifier/PropertyList.php';
|
||||
require_once $__dir . '/HTMLPurifier/PropertyListIterator.php';
|
||||
require_once $__dir . '/HTMLPurifier/Queue.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy.php';
|
||||
require_once $__dir . '/HTMLPurifier/StringHash.php';
|
||||
require_once $__dir . '/HTMLPurifier/StringHashParser.php';
|
||||
@@ -66,16 +60,12 @@ require_once $__dir . '/HTMLPurifier/URIFilter.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme.php';
|
||||
require_once $__dir . '/HTMLPurifier/URISchemeRegistry.php';
|
||||
require_once $__dir . '/HTMLPurifier/UnitConverter.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParserException.php';
|
||||
require_once $__dir . '/HTMLPurifier/Zipper.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Clone.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Enum.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Integer.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/URI.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Number.php';
|
||||
@@ -89,7 +79,6 @@ require_once $__dir . '/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Filter.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Font.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Ident.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
||||
@@ -98,8 +87,6 @@ require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
|
||||
@@ -107,12 +94,12 @@ require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/LinkTypes.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/MultiLength.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Host.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv6.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/BgColor.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BoolToCSS.php';
|
||||
@@ -120,27 +107,20 @@ require_once $__dir . '/HTMLPurifier/AttrTransform/Border.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/EnumToCSS.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgRequired.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/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/NameSync.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Nofollow.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/TargetBlank.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/TargetNoreferrer.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Textarea.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/List.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Required.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Optional.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/StrictBlockquote.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/Null.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Serializer.php';
|
||||
@@ -149,49 +129,32 @@ require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Bdo.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/CommonAttributes.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/Iframe.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Nofollow.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Proprietary.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/SafeScripting.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Scripting.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetBlank.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetNoreferrer.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.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/XHTMLAndHTML4.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTML.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/PurifierLinkify.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
|
||||
require_once $__dir . '/HTMLPurifier/Node/Comment.php';
|
||||
require_once $__dir . '/HTMLPurifier/Node/Element.php';
|
||||
require_once $__dir . '/HTMLPurifier/Node/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/Composite.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/Core.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/FixNesting.php';
|
||||
@@ -208,19 +171,13 @@ require_once $__dir . '/HTMLPurifier/Token/Start.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternal.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableResources.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/Munge.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/SafeIframe.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/data.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/file.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/mailto.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/news.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/nntp.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/tel.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser/Flexible.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser/Native.php';
|
||||
|
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Converts a stream of HTMLPurifier_Token into an HTMLPurifier_Node,
|
||||
* and back again.
|
||||
*
|
||||
* @note This transformation is not an equivalence. We mutate the input
|
||||
* token stream to make it so; see all [MUT] markers in code.
|
||||
*/
|
||||
class HTMLPurifier_Arborize
|
||||
{
|
||||
public static function arborize($tokens, $config, $context) {
|
||||
$definition = $config->getHTMLDefinition();
|
||||
$parent = new HTMLPurifier_Token_Start($definition->info_parent);
|
||||
$stack = array($parent->toNode());
|
||||
foreach ($tokens as $token) {
|
||||
$token->skip = null; // [MUT]
|
||||
$token->carryover = null; // [MUT]
|
||||
if ($token instanceof HTMLPurifier_Token_End) {
|
||||
$token->start = null; // [MUT]
|
||||
$r = array_pop($stack);
|
||||
assert($r->name === $token->name);
|
||||
assert(empty($token->attr));
|
||||
$r->endCol = $token->col;
|
||||
$r->endLine = $token->line;
|
||||
$r->endArmor = $token->armor;
|
||||
continue;
|
||||
}
|
||||
$node = $token->toNode();
|
||||
$stack[count($stack)-1]->children[] = $node;
|
||||
if ($token instanceof HTMLPurifier_Token_Start) {
|
||||
$stack[] = $node;
|
||||
}
|
||||
}
|
||||
assert(count($stack) == 1);
|
||||
return $stack[0];
|
||||
}
|
||||
|
||||
public static function flatten($node, $config, $context) {
|
||||
$level = 0;
|
||||
$nodes = array($level => new HTMLPurifier_Queue(array($node)));
|
||||
$closingTokens = array();
|
||||
$tokens = array();
|
||||
do {
|
||||
while (!$nodes[$level]->isEmpty()) {
|
||||
$node = $nodes[$level]->shift(); // FIFO
|
||||
list($start, $end) = $node->toTokenPair();
|
||||
if ($level > 0) {
|
||||
$tokens[] = $start;
|
||||
}
|
||||
if ($end !== NULL) {
|
||||
$closingTokens[$level][] = $end;
|
||||
}
|
||||
if ($node instanceof HTMLPurifier_Node_Element) {
|
||||
$level++;
|
||||
$nodes[$level] = new HTMLPurifier_Queue();
|
||||
foreach ($node->children as $childNode) {
|
||||
$nodes[$level]->push($childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
$level--;
|
||||
if ($level && isset($closingTokens[$level])) {
|
||||
while ($token = array_pop($closingTokens[$level])) {
|
||||
$tokens[] = $token;
|
||||
}
|
||||
}
|
||||
} while ($level > 0);
|
||||
return $tokens;
|
||||
}
|
||||
}
|
@@ -8,8 +8,7 @@ class HTMLPurifier_AttrCollections
|
||||
{
|
||||
|
||||
/**
|
||||
* Associative array of attribute collections, indexed by name.
|
||||
* @type array
|
||||
* Associative array of attribute collections, indexed by name
|
||||
*/
|
||||
public $info = array();
|
||||
|
||||
@@ -17,16 +16,10 @@ class HTMLPurifier_AttrCollections
|
||||
* Performs all expansions on internal data for use by other inclusions
|
||||
* It also collects all attribute collection extensions from
|
||||
* modules
|
||||
* @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance
|
||||
* @param HTMLPurifier_HTMLModule[] $modules Hash array of HTMLPurifier_HTMLModule members
|
||||
* @param $attr_types HTMLPurifier_AttrTypes instance
|
||||
* @param $modules Hash array of HTMLPurifier_HTMLModule members
|
||||
*/
|
||||
public function __construct($attr_types, $modules)
|
||||
{
|
||||
$this->doConstruct($attr_types, $modules);
|
||||
}
|
||||
|
||||
public function doConstruct($attr_types, $modules)
|
||||
{
|
||||
public function __construct($attr_types, $modules) {
|
||||
// load extensions from the modules
|
||||
foreach ($modules as $module) {
|
||||
foreach ($module->attr_collections as $coll_i => $coll) {
|
||||
@@ -37,9 +30,7 @@ class HTMLPurifier_AttrCollections
|
||||
if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) {
|
||||
// merge in includes
|
||||
$this->info[$coll_i][$attr_i] = array_merge(
|
||||
$this->info[$coll_i][$attr_i],
|
||||
$attr
|
||||
);
|
||||
$this->info[$coll_i][$attr_i], $attr);
|
||||
continue;
|
||||
}
|
||||
$this->info[$coll_i][$attr_i] = $attr;
|
||||
@@ -58,29 +49,20 @@ class HTMLPurifier_AttrCollections
|
||||
/**
|
||||
* Takes a reference to an attribute associative array and performs
|
||||
* all inclusions specified by the zero index.
|
||||
* @param array &$attr Reference to attribute array
|
||||
* @param &$attr Reference to attribute array
|
||||
*/
|
||||
public function performInclusions(&$attr)
|
||||
{
|
||||
if (!isset($attr[0])) {
|
||||
return;
|
||||
}
|
||||
public function performInclusions(&$attr) {
|
||||
if (!isset($attr[0])) return;
|
||||
$merge = $attr[0];
|
||||
$seen = array(); // recursion guard
|
||||
// loop through all the inclusions
|
||||
for ($i = 0; isset($merge[$i]); $i++) {
|
||||
if (isset($seen[$merge[$i]])) {
|
||||
continue;
|
||||
}
|
||||
if (isset($seen[$merge[$i]])) continue;
|
||||
$seen[$merge[$i]] = true;
|
||||
// foreach attribute of the inclusion, copy it over
|
||||
if (!isset($this->info[$merge[$i]])) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($this->info[$merge[$i]])) continue;
|
||||
foreach ($this->info[$merge[$i]] as $key => $value) {
|
||||
if (isset($attr[$key])) {
|
||||
continue;
|
||||
} // also catches more inclusions
|
||||
if (isset($attr[$key])) continue; // also catches more inclusions
|
||||
$attr[$key] = $value;
|
||||
}
|
||||
if (isset($this->info[$merge[$i]][0])) {
|
||||
@@ -94,24 +76,20 @@ class HTMLPurifier_AttrCollections
|
||||
/**
|
||||
* Expands all string identifiers in an attribute array by replacing
|
||||
* them with the appropriate values inside HTMLPurifier_AttrTypes
|
||||
* @param array &$attr Reference to attribute array
|
||||
* @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance
|
||||
* @param &$attr Reference to attribute array
|
||||
* @param $attr_types HTMLPurifier_AttrTypes instance
|
||||
*/
|
||||
public function expandIdentifiers(&$attr, $attr_types)
|
||||
{
|
||||
public function expandIdentifiers(&$attr, $attr_types) {
|
||||
|
||||
// because foreach will process new elements we add, make sure we
|
||||
// skip duplicates
|
||||
$processed = array();
|
||||
|
||||
foreach ($attr as $def_i => $def) {
|
||||
// skip inclusions
|
||||
if ($def_i === 0) {
|
||||
continue;
|
||||
}
|
||||
if ($def_i === 0) continue;
|
||||
|
||||
if (isset($processed[$def_i])) {
|
||||
continue;
|
||||
}
|
||||
if (isset($processed[$def_i])) continue;
|
||||
|
||||
// determine whether or not attribute is required
|
||||
if ($required = (strpos($def_i, '*') !== false)) {
|
||||
@@ -142,7 +120,8 @@ class HTMLPurifier_AttrCollections
|
||||
unset($attr[$def_i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -14,25 +14,23 @@ abstract class HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Tells us whether or not an HTML attribute is minimized.
|
||||
* Has no meaning in other contexts.
|
||||
* @type bool
|
||||
* Tells us whether or not an HTML attribute is minimized. Has no
|
||||
* meaning in other contexts.
|
||||
*/
|
||||
public $minimized = false;
|
||||
|
||||
/**
|
||||
* Tells us whether or not an HTML attribute is required.
|
||||
* Has no meaning in other contexts
|
||||
* @type bool
|
||||
* Tells us whether or not an HTML attribute is required. Has no
|
||||
* meaning in other contexts
|
||||
*/
|
||||
public $required = false;
|
||||
|
||||
/**
|
||||
* Validates and cleans passed string according to a definition.
|
||||
*
|
||||
* @param string $string String to be validated and cleaned.
|
||||
* @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object.
|
||||
* @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object.
|
||||
* @param $string String to be validated and cleaned.
|
||||
* @param $config Mandatory HTMLPurifier_Config object.
|
||||
* @param $context Mandatory HTMLPurifier_AttrContext object.
|
||||
*/
|
||||
abstract public function validate($string, $config, $context);
|
||||
|
||||
@@ -53,24 +51,25 @@ abstract class HTMLPurifier_AttrDef
|
||||
*
|
||||
* @warning This processing is inconsistent with XML's whitespace handling
|
||||
* as specified by section 3.3.3 and referenced XHTML 1.0 section
|
||||
* 4.7. However, note that we are NOT necessarily
|
||||
* parsing XML, thus, this behavior may still be correct. We
|
||||
* assume that newlines have been normalized.
|
||||
* 4.7. Compliant processing requires all line breaks normalized
|
||||
* to "\n", so the fix is not as simple as fixing it in this
|
||||
* function. Trim and whitespace collapsing are supposed to only
|
||||
* 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 = str_replace(array("\n", "\t", "\r"), ' ', $string);
|
||||
$string = str_replace("\n", '', $string);
|
||||
$string = str_replace(array("\r", "\t"), ' ', $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating this class from a string.
|
||||
* @param string $string String construction info
|
||||
* @return HTMLPurifier_AttrDef Created AttrDef object corresponding to $string
|
||||
* @param $string String construction info
|
||||
* @return Created AttrDef object corresponding to $string
|
||||
*/
|
||||
public function make($string)
|
||||
{
|
||||
public function make($string) {
|
||||
// default implementation, return a flyweight of this object.
|
||||
// If $string has an effect on the returned object (i.e. you
|
||||
// need to overload this method), it is best
|
||||
@@ -81,58 +80,10 @@ abstract class HTMLPurifier_AttrDef
|
||||
/**
|
||||
* Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work
|
||||
* properly. THIS IS A HACK!
|
||||
* @param string $string a CSS colour definition
|
||||
* @return string
|
||||
*/
|
||||
protected function mungeRgb($string)
|
||||
{
|
||||
protected function mungeRgb($string) {
|
||||
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a possibly escaped CSS string and returns the "pure"
|
||||
* version of it.
|
||||
*/
|
||||
protected function expandCSSEscape($string)
|
||||
{
|
||||
// flexibly parse it
|
||||
$ret = '';
|
||||
for ($i = 0, $c = strlen($string); $i < $c; $i++) {
|
||||
if ($string[$i] === '\\') {
|
||||
$i++;
|
||||
if ($i >= $c) {
|
||||
$ret .= '\\';
|
||||
break;
|
||||
}
|
||||
if (ctype_xdigit($string[$i])) {
|
||||
$code = $string[$i];
|
||||
for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) {
|
||||
if (!ctype_xdigit($string[$i])) {
|
||||
break;
|
||||
}
|
||||
$code .= $string[$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;
|
||||
}
|
||||
$ret .= $char;
|
||||
if ($i < $c && trim($string[$i]) !== '') {
|
||||
$i--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ($string[$i] === "\n") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$ret .= $string[$i];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -14,18 +14,11 @@
|
||||
class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $css
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($css, $config, $context)
|
||||
{
|
||||
public function validate($css, $config, $context) {
|
||||
|
||||
$css = $this->parseCDATA($css);
|
||||
|
||||
$definition = $config->getCSSDefinition();
|
||||
$allow_duplicates = $config->get("CSS.AllowDuplicates");
|
||||
|
||||
// we're going to break the spec and explode by semicolons.
|
||||
// This is because semicolon rarely appears in escaped form
|
||||
@@ -35,21 +28,10 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
||||
|
||||
$declarations = explode(';', $css);
|
||||
$propvalues = array();
|
||||
$new_declarations = '';
|
||||
|
||||
/**
|
||||
* Name of the current CSS property being validated.
|
||||
*/
|
||||
$property = false;
|
||||
$context->register('CurrentCSSProperty', $property);
|
||||
|
||||
foreach ($declarations as $declaration) {
|
||||
if (!$declaration) {
|
||||
continue;
|
||||
}
|
||||
if (!strpos($declaration, ':')) {
|
||||
continue;
|
||||
}
|
||||
if (!$declaration) continue;
|
||||
if (!strpos($declaration, ':')) continue;
|
||||
list($property, $value) = explode(':', $declaration, 2);
|
||||
$property = trim($property);
|
||||
$value = trim($value);
|
||||
@@ -59,45 +41,31 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
||||
$ok = true;
|
||||
break;
|
||||
}
|
||||
if (ctype_lower($property)) {
|
||||
break;
|
||||
}
|
||||
if (ctype_lower($property)) break;
|
||||
$property = strtolower($property);
|
||||
if (isset($definition->info[$property])) {
|
||||
$ok = true;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
if (!$ok) {
|
||||
continue;
|
||||
}
|
||||
} while(0);
|
||||
if (!$ok) continue;
|
||||
// inefficient call, since the validator will do this again
|
||||
if (strtolower(trim($value)) !== 'inherit') {
|
||||
// inherit works for everything (but only on the base property)
|
||||
$result = $definition->info[$property]->validate(
|
||||
$value,
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
$value, $config, $context );
|
||||
} else {
|
||||
$result = 'inherit';
|
||||
}
|
||||
if ($result === false) {
|
||||
continue;
|
||||
}
|
||||
if ($allow_duplicates) {
|
||||
$new_declarations .= "$property:$result;";
|
||||
} else {
|
||||
if ($result === false) continue;
|
||||
$propvalues[$property] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
$context->destroy('CurrentCSSProperty');
|
||||
|
||||
// procedure does not write the new CSS simultaneously, so it's
|
||||
// slightly inefficient, but it's the only way of getting rid of
|
||||
// duplicates. Perhaps config to optimize it, but not now.
|
||||
|
||||
$new_declarations = '';
|
||||
foreach ($propvalues as $prop => $value) {
|
||||
$new_declarations .= "$prop:$value;";
|
||||
}
|
||||
@@ -108,4 +76,3 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -3,32 +3,17 @@
|
||||
class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
public function __construct() {
|
||||
parent::__construct(false); // opacity is non-negative, but we will clamp it
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $number
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return string
|
||||
*/
|
||||
public function validate($number, $config, $context)
|
||||
{
|
||||
public function validate($number, $config, $context) {
|
||||
$result = parent::validate($number, $config, $context);
|
||||
if ($result === false) {
|
||||
if ($result === false) return $result;
|
||||
$float = (float) $result;
|
||||
if ($float < 0.0) $result = '0';
|
||||
if ($float > 1.0) $result = '1';
|
||||
return $result;
|
||||
}
|
||||
$float = (float)$result;
|
||||
if ($float < 0.0) {
|
||||
$result = '0';
|
||||
}
|
||||
if ($float > 1.0) {
|
||||
$result = '1';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
}
|
||||
|
@@ -9,16 +9,11 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
|
||||
/**
|
||||
* Local copy of component validators.
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
* @note See HTMLPurifier_AttrDef_Font::$info for a similar impl.
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
public function __construct($config) {
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['background-color'] = $def->info['background-color'];
|
||||
$this->info['background-image'] = $def->info['background-image'];
|
||||
@@ -27,25 +22,17 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
$this->info['background-position'] = $def->info['background-position'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
// regular pre-processing
|
||||
$string = $this->parseCDATA($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
if ($string === '') return false;
|
||||
|
||||
// munge rgb() decl if necessary
|
||||
$string = $this->mungeRgb($string);
|
||||
|
||||
// assumes URI doesn't have spaces in it
|
||||
$bits = explode(' ', $string); // bits to process
|
||||
$bits = explode(' ', strtolower($string)); // bits to process
|
||||
|
||||
$caught = array();
|
||||
$caught['color'] = false;
|
||||
@@ -55,27 +42,20 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
$caught['position'] = false;
|
||||
|
||||
$i = 0; // number of catches
|
||||
$none = false;
|
||||
|
||||
foreach ($bits as $bit) {
|
||||
if ($bit === '') {
|
||||
continue;
|
||||
}
|
||||
if ($bit === '') continue;
|
||||
foreach ($caught as $key => $status) {
|
||||
if ($key != 'position') {
|
||||
if ($status !== false) {
|
||||
continue;
|
||||
}
|
||||
if ($status !== false) continue;
|
||||
$r = $this->info['background-' . $key]->validate($bit, $config, $context);
|
||||
} else {
|
||||
$r = $bit;
|
||||
}
|
||||
if ($r === false) {
|
||||
continue;
|
||||
}
|
||||
if ($r === false) continue;
|
||||
if ($key == 'position') {
|
||||
if ($caught[$key] === false) {
|
||||
$caught[$key] = '';
|
||||
}
|
||||
if ($caught[$key] === false) $caught[$key] = '';
|
||||
$caught[$key] .= $r . ' ';
|
||||
} else {
|
||||
$caught[$key] = $r;
|
||||
@@ -85,9 +65,7 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
}
|
||||
}
|
||||
|
||||
if (!$i) {
|
||||
return false;
|
||||
}
|
||||
if (!$i) return false;
|
||||
if ($caught['position'] !== false) {
|
||||
$caught['position'] = $this->info['background-position']->
|
||||
validate($caught['position'], $config, $context);
|
||||
@@ -95,17 +73,14 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
|
||||
$ret = array();
|
||||
foreach ($caught as $value) {
|
||||
if ($value === false) {
|
||||
continue;
|
||||
}
|
||||
if ($value === false) continue;
|
||||
$ret[] = $value;
|
||||
}
|
||||
|
||||
if (empty($ret)) {
|
||||
return false;
|
||||
}
|
||||
if (empty($ret)) return false;
|
||||
return implode(' ', $ret);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -44,38 +44,22 @@
|
||||
class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef_CSS_Length
|
||||
*/
|
||||
protected $length;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef_CSS_Percentage
|
||||
*/
|
||||
protected $percentage;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
public function __construct() {
|
||||
$this->length = new HTMLPurifier_AttrDef_CSS_Length();
|
||||
$this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
$string = $this->parseCDATA($string);
|
||||
$bits = explode(' ', $string);
|
||||
|
||||
$keywords = array();
|
||||
$keywords['h'] = false; // left, right
|
||||
$keywords['v'] = false; // top, bottom
|
||||
$keywords['ch'] = false; // center (first word)
|
||||
$keywords['cv'] = false; // center (second word)
|
||||
$keywords['c'] = false; // center
|
||||
$measures = array();
|
||||
|
||||
$i = 0;
|
||||
@@ -89,21 +73,12 @@ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
|
||||
);
|
||||
|
||||
foreach ($bits as $bit) {
|
||||
if ($bit === '') {
|
||||
continue;
|
||||
}
|
||||
if ($bit === '') continue;
|
||||
|
||||
// test for keyword
|
||||
$lbit = ctype_lower($bit) ? $bit : strtolower($bit);
|
||||
if (isset($lookup[$lbit])) {
|
||||
$status = $lookup[$lbit];
|
||||
if ($status == 'c') {
|
||||
if ($i == 0) {
|
||||
$status = 'ch';
|
||||
} else {
|
||||
$status = 'cv';
|
||||
}
|
||||
}
|
||||
$keywords[$status] = $lbit;
|
||||
$i++;
|
||||
}
|
||||
@@ -121,37 +96,30 @@ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
|
||||
$measures[] = $r;
|
||||
$i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!$i) {
|
||||
return false;
|
||||
} // no valid values were caught
|
||||
if (!$i) return false; // no valid values were caught
|
||||
|
||||
|
||||
$ret = array();
|
||||
|
||||
// first keyword
|
||||
if ($keywords['h']) {
|
||||
$ret[] = $keywords['h'];
|
||||
} elseif ($keywords['ch']) {
|
||||
$ret[] = $keywords['ch'];
|
||||
$keywords['cv'] = false; // prevent re-use: center = center center
|
||||
} elseif (count($measures)) {
|
||||
$ret[] = array_shift($measures);
|
||||
if ($keywords['h']) $ret[] = $keywords['h'];
|
||||
elseif (count($measures)) $ret[] = array_shift($measures);
|
||||
elseif ($keywords['c']) {
|
||||
$ret[] = $keywords['c'];
|
||||
$keywords['c'] = false; // prevent re-use: center = center center
|
||||
}
|
||||
|
||||
if ($keywords['v']) {
|
||||
$ret[] = $keywords['v'];
|
||||
} elseif ($keywords['cv']) {
|
||||
$ret[] = $keywords['cv'];
|
||||
} elseif (count($measures)) {
|
||||
$ret[] = array_shift($measures);
|
||||
}
|
||||
if ($keywords['v']) $ret[] = $keywords['v'];
|
||||
elseif (count($measures)) $ret[] = array_shift($measures);
|
||||
elseif ($keywords['c']) $ret[] = $keywords['c'];
|
||||
|
||||
if (empty($ret)) {
|
||||
return false;
|
||||
}
|
||||
if (empty($ret)) return false;
|
||||
return implode(' ', $ret);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -8,29 +8,17 @@ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
|
||||
|
||||
/**
|
||||
* Local copy of properties this property is shorthand for.
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
*/
|
||||
protected $info = array();
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
public function __construct($config) {
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['border-width'] = $def->info['border-width'];
|
||||
$this->info['border-style'] = $def->info['border-style'];
|
||||
$this->info['border-top-color'] = $def->info['border-top-color'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
$string = $this->parseCDATA($string);
|
||||
$string = $this->mungeRgb($string);
|
||||
$bits = explode(' ', $string);
|
||||
@@ -38,9 +26,7 @@ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
|
||||
$ret = ''; // return value
|
||||
foreach ($bits as $bit) {
|
||||
foreach ($this->info as $propname => $validator) {
|
||||
if (isset($done[$propname])) {
|
||||
continue;
|
||||
}
|
||||
if (isset($done[$propname])) continue;
|
||||
$r = $validator->validate($bit, $config, $context);
|
||||
if ($r !== false) {
|
||||
$ret .= $r . ' ';
|
||||
@@ -51,6 +37,6 @@ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
|
||||
}
|
||||
return rtrim($ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -6,47 +6,29 @@
|
||||
class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $color
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($color, $config, $context)
|
||||
{
|
||||
public function validate($color, $config, $context) {
|
||||
|
||||
static $colors = null;
|
||||
if ($colors === null) {
|
||||
$colors = $config->get('Core.ColorKeywords');
|
||||
}
|
||||
if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
|
||||
|
||||
$color = trim($color);
|
||||
if ($color === '') {
|
||||
return false;
|
||||
}
|
||||
if ($color === '') return false;
|
||||
|
||||
$lower = strtolower($color);
|
||||
if (isset($colors[$lower])) {
|
||||
return $colors[$lower];
|
||||
}
|
||||
if (isset($colors[$lower])) return $colors[$lower];
|
||||
|
||||
if (strpos($color, 'rgb(') !== false) {
|
||||
// rgb literal handling
|
||||
$length = strlen($color);
|
||||
if (strpos($color, ')') !== $length - 1) {
|
||||
return false;
|
||||
}
|
||||
if (strpos($color, ')') !== $length - 1) return false;
|
||||
$triad = substr($color, 4, $length - 4 - 1);
|
||||
$parts = explode(',', $triad);
|
||||
if (count($parts) !== 3) {
|
||||
return false;
|
||||
}
|
||||
if (count($parts) !== 3) return false;
|
||||
$type = false; // to ensure that they're all the same type
|
||||
$new_parts = array();
|
||||
foreach ($parts as $part) {
|
||||
$part = trim($part);
|
||||
if ($part === '') {
|
||||
return false;
|
||||
}
|
||||
if ($part === '') return false;
|
||||
$length = strlen($part);
|
||||
if ($part[$length - 1] === '%') {
|
||||
// handle percents
|
||||
@@ -55,13 +37,9 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
|
||||
} elseif ($type !== 'percentage') {
|
||||
return false;
|
||||
}
|
||||
$num = (float)substr($part, 0, $length - 1);
|
||||
if ($num < 0) {
|
||||
$num = 0;
|
||||
}
|
||||
if ($num > 100) {
|
||||
$num = 100;
|
||||
}
|
||||
$num = (float) substr($part, 0, $length - 1);
|
||||
if ($num < 0) $num = 0;
|
||||
if ($num > 100) $num = 100;
|
||||
$new_parts[] = "$num%";
|
||||
} else {
|
||||
// handle integers
|
||||
@@ -70,14 +48,10 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
|
||||
} elseif ($type !== 'integer') {
|
||||
return false;
|
||||
}
|
||||
$num = (int)$part;
|
||||
if ($num < 0) {
|
||||
$num = 0;
|
||||
}
|
||||
if ($num > 255) {
|
||||
$num = 255;
|
||||
}
|
||||
$new_parts[] = (string)$num;
|
||||
$num = (int) $part;
|
||||
if ($num < 0) $num = 0;
|
||||
if ($num > 255) $num = 255;
|
||||
$new_parts[] = (string) $num;
|
||||
}
|
||||
}
|
||||
$new_triad = implode(',', $new_parts);
|
||||
@@ -91,15 +65,13 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
|
||||
$color = '#' . $color;
|
||||
}
|
||||
$length = strlen($hex);
|
||||
if ($length !== 3 && $length !== 6) {
|
||||
return false;
|
||||
}
|
||||
if (!ctype_xdigit($hex)) {
|
||||
return false;
|
||||
}
|
||||
if ($length !== 3 && $length !== 6) return false;
|
||||
if (!ctype_xdigit($hex)) return false;
|
||||
}
|
||||
|
||||
return $color;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -13,36 +13,25 @@ class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* List of objects that may process strings.
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
* List of HTMLPurifier_AttrDef objects that may process strings
|
||||
* @todo Make protected
|
||||
*/
|
||||
public $defs;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_AttrDef[] $defs List of HTMLPurifier_AttrDef objects
|
||||
* @param $defs List of HTMLPurifier_AttrDef objects
|
||||
*/
|
||||
public function __construct($defs)
|
||||
{
|
||||
public function __construct($defs) {
|
||||
$this->defs = $defs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
foreach ($this->defs as $i => $def) {
|
||||
$result = $this->defs[$i]->validate($string, $config, $context);
|
||||
if ($result !== false) {
|
||||
return $result;
|
||||
}
|
||||
if ($result !== false) return $result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -5,40 +5,22 @@
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef
|
||||
*/
|
||||
public $def;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
public $element;
|
||||
protected $def, $element;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_AttrDef $def Definition to wrap
|
||||
* @param string $element Element to deny
|
||||
* @param $def Definition to wrap
|
||||
* @param $element Element to deny
|
||||
*/
|
||||
public function __construct($def, $element)
|
||||
{
|
||||
public function __construct($def, $element) {
|
||||
$this->def = $def;
|
||||
$this->element = $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if CurrentToken is set and equal to $this->element
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
$token = $context->get('CurrentToken', true);
|
||||
if ($token && $token->name == $this->element) {
|
||||
return false;
|
||||
}
|
||||
if ($token && $token->name == $this->element) return false;
|
||||
return $this->def->validate($string, $config, $context);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -7,37 +7,23 @@
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef_Integer
|
||||
*/
|
||||
|
||||
protected $intValidator;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
public function __construct() {
|
||||
$this->intValidator = new HTMLPurifier_AttrDef_Integer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($value, $config, $context)
|
||||
{
|
||||
public function validate($value, $config, $context) {
|
||||
$value = $this->parseCDATA($value);
|
||||
if ($value === 'none') {
|
||||
return $value;
|
||||
}
|
||||
if ($value === 'none') return $value;
|
||||
// if we looped this we could support multiple filters
|
||||
$function_length = strcspn($value, '(');
|
||||
$function = trim(substr($value, 0, $function_length));
|
||||
if ($function !== 'alpha' &&
|
||||
$function !== 'Alpha' &&
|
||||
$function !== 'progid:DXImageTransform.Microsoft.Alpha'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
) return false;
|
||||
$cursor = $function_length + 1;
|
||||
$parameters_length = strcspn($value, ')', $cursor);
|
||||
$parameters = substr($value, $cursor, $parameters_length);
|
||||
@@ -48,23 +34,13 @@ class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
|
||||
list($key, $value) = explode('=', $param);
|
||||
$key = trim($key);
|
||||
$value = trim($value);
|
||||
if (isset($lookup[$key])) {
|
||||
continue;
|
||||
}
|
||||
if ($key !== 'opacity') {
|
||||
continue;
|
||||
}
|
||||
if (isset($lookup[$key])) continue;
|
||||
if ($key !== 'opacity') continue;
|
||||
$value = $this->intValidator->validate($value, $config, $context);
|
||||
if ($value === false) {
|
||||
continue;
|
||||
}
|
||||
$int = (int)$value;
|
||||
if ($int > 100) {
|
||||
$value = '100';
|
||||
}
|
||||
if ($int < 0) {
|
||||
$value = '0';
|
||||
}
|
||||
if ($value === false) continue;
|
||||
$int = (int) $value;
|
||||
if ($int > 100) $value = '100';
|
||||
if ($int < 0) $value = '0';
|
||||
$ret_params[] = "$key=$value";
|
||||
$lookup[$key] = true;
|
||||
}
|
||||
@@ -72,6 +48,5 @@ class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
|
||||
$ret_function = "$function($ret_parameters)";
|
||||
return $ret_function;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
}
|
||||
|
@@ -7,8 +7,8 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Local copy of validators
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
* Local copy of component validators.
|
||||
*
|
||||
* @note If we moved specific CSS property definitions to their own
|
||||
* classes instead of having them be assembled at run time by
|
||||
* CSSDefinition, this wouldn't be necessary. We'd instantiate
|
||||
@@ -16,11 +16,7 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
*/
|
||||
protected $info = array();
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
public function __construct($config) {
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['font-style'] = $def->info['font-style'];
|
||||
$this->info['font-variant'] = $def->info['font-variant'];
|
||||
@@ -30,14 +26,8 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
$this->info['font-family'] = $def->info['font-family'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
static $system_fonts = array(
|
||||
'caption' => true,
|
||||
'icon' => true,
|
||||
@@ -49,9 +39,7 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
|
||||
// regular pre-processing
|
||||
$string = $this->parseCDATA($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
if ($string === '') return false;
|
||||
|
||||
// check if it's one of the keywords
|
||||
$lowercase_string = strtolower($string);
|
||||
@@ -66,20 +54,15 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
$final = ''; // output
|
||||
|
||||
for ($i = 0, $size = count($bits); $i < $size; $i++) {
|
||||
if ($bits[$i] === '') {
|
||||
continue;
|
||||
}
|
||||
if ($bits[$i] === '') continue;
|
||||
switch ($stage) {
|
||||
case 0: // attempting to catch font-style, font-variant or font-weight
|
||||
|
||||
// attempting to catch font-style, font-variant or font-weight
|
||||
case 0:
|
||||
foreach ($stage_1 as $validator_name) {
|
||||
if (isset($caught[$validator_name])) {
|
||||
continue;
|
||||
}
|
||||
if (isset($caught[$validator_name])) continue;
|
||||
$r = $this->info[$validator_name]->validate(
|
||||
$bits[$i],
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
$bits[$i], $config, $context);
|
||||
if ($r !== false) {
|
||||
$final .= $r . ' ';
|
||||
$caught[$validator_name] = true;
|
||||
@@ -87,13 +70,11 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
}
|
||||
}
|
||||
// all three caught, continue on
|
||||
if (count($caught) >= 3) {
|
||||
$stage = 1;
|
||||
}
|
||||
if ($r !== false) {
|
||||
break;
|
||||
}
|
||||
case 1: // attempting to catch font-size and perhaps line-height
|
||||
if (count($caught) >= 3) $stage = 1;
|
||||
if ($r !== false) break;
|
||||
|
||||
// attempting to catch font-size and perhaps line-height
|
||||
case 1:
|
||||
$found_slash = false;
|
||||
if (strpos($bits[$i], '/') !== false) {
|
||||
list($font_size, $line_height) =
|
||||
@@ -108,19 +89,14 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
$line_height = false;
|
||||
}
|
||||
$r = $this->info['font-size']->validate(
|
||||
$font_size,
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
$font_size, $config, $context);
|
||||
if ($r !== false) {
|
||||
$final .= $r;
|
||||
// attempt to catch line-height
|
||||
if ($line_height === false) {
|
||||
// we need to scroll forward
|
||||
for ($j = $i + 1; $j < $size; $j++) {
|
||||
if ($bits[$j] === '') {
|
||||
continue;
|
||||
}
|
||||
if ($bits[$j] === '') continue;
|
||||
if ($bits[$j] === '/') {
|
||||
if ($found_slash) {
|
||||
return false;
|
||||
@@ -140,10 +116,7 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
if ($found_slash) {
|
||||
$i = $j;
|
||||
$r = $this->info['line-height']->validate(
|
||||
$line_height,
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
$line_height, $config, $context);
|
||||
if ($r !== false) {
|
||||
$final .= '/' . $r;
|
||||
}
|
||||
@@ -153,14 +126,13 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
case 2: // attempting to catch font-family
|
||||
|
||||
// attempting to catch font-family
|
||||
case 2:
|
||||
$font_family =
|
||||
implode(' ', array_slice($bits, $i, $size - $i));
|
||||
$r = $this->info['font-family']->validate(
|
||||
$font_family,
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
$font_family, $config, $context);
|
||||
if ($r !== false) {
|
||||
$final .= $r . ' ';
|
||||
// processing completed successfully
|
||||
@@ -171,6 +143,6 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -2,58 +2,12 @@
|
||||
|
||||
/**
|
||||
* Validates a font family list according to CSS spec
|
||||
* @todo whitelisting allowed fonts would be nice
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
protected $mask = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->mask = '_- ';
|
||||
for ($c = 'a'; $c <= 'z'; $c++) {
|
||||
$this->mask .= $c;
|
||||
}
|
||||
for ($c = 'A'; $c <= 'Z'; $c++) {
|
||||
$this->mask .= $c;
|
||||
}
|
||||
for ($c = '0'; $c <= '9'; $c++) {
|
||||
$this->mask .= $c;
|
||||
} // cast-y, but should be fine
|
||||
// special bytes used by UTF-8
|
||||
for ($i = 0x80; $i <= 0xFF; $i++) {
|
||||
// We don't bother excluding invalid bytes in this range,
|
||||
// because the our restriction of well-formed UTF-8 will
|
||||
// prevent these from ever occurring.
|
||||
$this->mask .= chr($i);
|
||||
}
|
||||
|
||||
/*
|
||||
PHP's internal strcspn implementation is
|
||||
O(length of string * length of mask), making it inefficient
|
||||
for large masks. However, it's still faster than
|
||||
preg_match 8)
|
||||
for (p = s1;;) {
|
||||
spanp = s2;
|
||||
do {
|
||||
if (*spanp == c || p == s1_end) {
|
||||
return p - s1;
|
||||
}
|
||||
} while (spanp++ < (s2_end - 1));
|
||||
c = *++p;
|
||||
}
|
||||
*/
|
||||
// possible optimization: invert the mask.
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
static $generic_names = array(
|
||||
'serif' => true,
|
||||
'sans-serif' => true,
|
||||
@@ -61,159 +15,49 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
||||
'fantasy' => true,
|
||||
'cursive' => true
|
||||
);
|
||||
$allowed_fonts = $config->get('CSS.AllowedFonts');
|
||||
|
||||
$string = $this->parseCDATA($string);
|
||||
// assume that no font names contain commas in them
|
||||
$fonts = explode(',', $string);
|
||||
$final = '';
|
||||
foreach ($fonts as $font) {
|
||||
foreach($fonts as $font) {
|
||||
$font = trim($font);
|
||||
if ($font === '') {
|
||||
continue;
|
||||
}
|
||||
if ($font === '') continue;
|
||||
// match a generic name
|
||||
if (isset($generic_names[$font])) {
|
||||
if ($allowed_fonts === null || isset($allowed_fonts[$font])) {
|
||||
$final .= $font . ', ';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// match a quoted name
|
||||
if ($font[0] === '"' || $font[0] === "'") {
|
||||
$length = strlen($font);
|
||||
if ($length <= 2) {
|
||||
continue;
|
||||
}
|
||||
if ($length <= 2) continue;
|
||||
$quote = $font[0];
|
||||
if ($font[$length - 1] !== $quote) {
|
||||
continue;
|
||||
}
|
||||
if ($font[$length - 1] !== $quote) continue;
|
||||
$font = substr($font, 1, $length - 2);
|
||||
// double-backslash processing is buggy
|
||||
$font = str_replace("\\$quote", $quote, $font); // de-escape quote
|
||||
$font = str_replace("\\\n", "\n", $font); // de-escape newlines
|
||||
}
|
||||
|
||||
$font = $this->expandCSSEscape($font);
|
||||
|
||||
// $font is a pure representation of the font name
|
||||
|
||||
if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctype_alnum($font) && $font !== '') {
|
||||
if (ctype_alnum($font)) {
|
||||
// very simple font, allow it in unharmed
|
||||
$final .= $font . ', ';
|
||||
continue;
|
||||
}
|
||||
|
||||
// bugger out on whitespace. form feed (0C) really
|
||||
// shouldn't show up regardless
|
||||
$font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font);
|
||||
// complicated font, requires quoting
|
||||
|
||||
// Here, there are various classes of characters which need
|
||||
// to be treated differently:
|
||||
// - Alphanumeric characters are essentially safe. We
|
||||
// handled these above.
|
||||
// - Spaces require quoting, though most parsers will do
|
||||
// the right thing if there aren't any characters that
|
||||
// can be misinterpreted
|
||||
// - Dashes rarely occur, but they fairly unproblematic
|
||||
// for parsing/rendering purposes.
|
||||
// The above characters cover the majority of Western font
|
||||
// names.
|
||||
// - Arbitrary Unicode characters not in ASCII. Because
|
||||
// most parsers give little thought to Unicode, treatment
|
||||
// of these codepoints is basically uniform, even for
|
||||
// punctuation-like codepoints. These characters can
|
||||
// show up in non-Western pages and are supported by most
|
||||
// major browsers, for example: "MS 明朝" is a
|
||||
// legitimate font-name
|
||||
// <http://ja.wikipedia.org/wiki/MS_明朝>. See
|
||||
// the CSS3 spec for more examples:
|
||||
// <http://www.w3.org/TR/2011/WD-css3-fonts-20110324/localizedfamilynames.png>
|
||||
// You can see live samples of these on the Internet:
|
||||
// <http://www.google.co.jp/search?q=font-family+MS+明朝|ゴシック>
|
||||
// However, most of these fonts have ASCII equivalents:
|
||||
// for example, 'MS Mincho', and it's considered
|
||||
// professional to use ASCII font names instead of
|
||||
// Unicode font names. Thanks Takeshi Terada for
|
||||
// providing this information.
|
||||
// The following characters, to my knowledge, have not been
|
||||
// used to name font names.
|
||||
// - Single quote. While theoretically you might find a
|
||||
// font name that has a single quote in its name (serving
|
||||
// as an apostrophe, e.g. Dave's Scribble), I haven't
|
||||
// been able to find any actual examples of this.
|
||||
// Internet Explorer's cssText translation (which I
|
||||
// believe is invoked by innerHTML) normalizes any
|
||||
// quoting to single quotes, and fails to escape single
|
||||
// quotes. (Note that this is not IE's behavior for all
|
||||
// CSS properties, just some sort of special casing for
|
||||
// font-family). So a single quote *cannot* be used
|
||||
// safely in the font-family context if there will be an
|
||||
// innerHTML/cssText translation. Note that Firefox 3.x
|
||||
// does this too.
|
||||
// - Double quote. In IE, these get normalized to
|
||||
// single-quotes, no matter what the encoding. (Fun
|
||||
// fact, in IE8, the 'content' CSS property gained
|
||||
// support, where they special cased to preserve encoded
|
||||
// double quotes, but still translate unadorned double
|
||||
// quotes into single quotes.) So, because their
|
||||
// fixpoint behavior is identical to single quotes, they
|
||||
// cannot be allowed either. Firefox 3.x displays
|
||||
// single-quote style behavior.
|
||||
// - Backslashes are reduced by one (so \\ -> \) every
|
||||
// iteration, so they cannot be used safely. This shows
|
||||
// up in IE7, IE8 and FF3
|
||||
// - Semicolons, commas and backticks are handled properly.
|
||||
// - The rest of the ASCII punctuation is handled properly.
|
||||
// We haven't checked what browsers do to unadorned
|
||||
// versions, but this is not important as long as the
|
||||
// browser doesn't /remove/ surrounding quotes (as IE does
|
||||
// for HTML).
|
||||
//
|
||||
// With these results in hand, we conclude that there are
|
||||
// various levels of safety:
|
||||
// - Paranoid: alphanumeric, spaces and dashes(?)
|
||||
// - International: Paranoid + non-ASCII Unicode
|
||||
// - Edgy: Everything except quotes, backslashes
|
||||
// - NoJS: Standards compliance, e.g. sod IE. Note that
|
||||
// with some judicious character escaping (since certain
|
||||
// types of escaping doesn't work) this is theoretically
|
||||
// OK as long as innerHTML/cssText is not called.
|
||||
// We believe that international is a reasonable default
|
||||
// (that we will implement now), and once we do more
|
||||
// extensive research, we may feel comfortable with dropping
|
||||
// it down to edgy.
|
||||
|
||||
// Edgy: alphanumeric, spaces, dashes, underscores and Unicode. Use of
|
||||
// str(c)spn assumes that the string was already well formed
|
||||
// Unicode (which of course it is).
|
||||
if (strspn($font, $this->mask) !== strlen($font)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Historical:
|
||||
// In the absence of innerHTML/cssText, these ugly
|
||||
// transforms don't pose a security risk (as \\ and \"
|
||||
// might--these escapes are not supported by most browsers).
|
||||
// We could try to be clever and use single-quote wrapping
|
||||
// when there is a double quote present, but I have choosen
|
||||
// not to implement that. (NOTE: you can reduce the amount
|
||||
// of escapes by one depending on what quoting style you use)
|
||||
// $font = str_replace('\\', '\\5C ', $font);
|
||||
// $font = str_replace('"', '\\22 ', $font);
|
||||
// $font = str_replace("'", '\\27 ', $font);
|
||||
|
||||
// font possibly with spaces, requires quoting
|
||||
// armor single quotes and new lines
|
||||
$font = str_replace("'", "\\'", $font);
|
||||
$font = str_replace("\n", "\\\n", $font);
|
||||
$final .= "'$font', ";
|
||||
}
|
||||
$final = rtrim($final, ', ');
|
||||
if ($final === '') {
|
||||
return false;
|
||||
}
|
||||
if ($final === '') return false;
|
||||
return $final;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates based on {ident} CSS grammar production
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Ident extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = trim($string);
|
||||
|
||||
// early abort: '' and '0' (strings that convert to false) are invalid
|
||||
if (!$string) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pattern = '/^(-?[A-Za-z_][A-Za-z_\-0-9]*)$/';
|
||||
if (!preg_match($pattern, $string)) {
|
||||
return false;
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@@ -5,34 +5,20 @@
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef
|
||||
*/
|
||||
public $def;
|
||||
/**
|
||||
* @type bool
|
||||
*/
|
||||
public $allow;
|
||||
protected $def, $allow;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_AttrDef $def Definition to wrap
|
||||
* @param bool $allow Whether or not to allow !important
|
||||
* @param $def Definition to wrap
|
||||
* @param $allow Whether or not to allow !important
|
||||
*/
|
||||
public function __construct($def, $allow = false)
|
||||
{
|
||||
public function __construct($def, $allow = false) {
|
||||
$this->def = $def;
|
||||
$this->allow = $allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intercepts and removes !important if necessary
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
// test for ! and important tokens
|
||||
$string = trim($string);
|
||||
$is_important = false;
|
||||
@@ -46,11 +32,7 @@ class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef
|
||||
}
|
||||
}
|
||||
$string = $this->def->validate($string, $config, $context);
|
||||
if ($this->allow && $is_important) {
|
||||
$string .= ' !important';
|
||||
}
|
||||
if ($this->allow && $is_important) $string .= ' !important';
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -7,71 +7,46 @@ class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_Length|string
|
||||
* Valid unit lookup table.
|
||||
* @warning The code assumes all units are two characters long. Be careful
|
||||
* if we have to change this behavior!
|
||||
*/
|
||||
protected $min;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_Length|string
|
||||
* @param $non_negative Bool indication whether or not negative values are
|
||||
* allowed.
|
||||
*/
|
||||
protected $max;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Length|string $min Minimum length, or null for no bound. String is also acceptable.
|
||||
* @param HTMLPurifier_Length|string $max Maximum length, or null for no bound. String is also acceptable.
|
||||
*/
|
||||
public function __construct($min = null, $max = null)
|
||||
{
|
||||
$this->min = $min !== null ? HTMLPurifier_Length::make($min) : null;
|
||||
$this->max = $max !== null ? HTMLPurifier_Length::make($max) : null;
|
||||
public function __construct($non_negative = false) {
|
||||
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = $this->parseCDATA($string);
|
||||
public function validate($length, $config, $context) {
|
||||
|
||||
$length = $this->parseCDATA($length);
|
||||
if ($length === '') return false;
|
||||
if ($length === '0') return '0';
|
||||
$strlen = strlen($length);
|
||||
if ($strlen === 1) return false; // impossible!
|
||||
|
||||
// we assume all units are two characters
|
||||
$unit = substr($length, $strlen - 2);
|
||||
if (!ctype_lower($unit)) $unit = strtolower($unit);
|
||||
$number = substr($length, 0, $strlen - 2);
|
||||
|
||||
if (!isset($this->units[$unit])) return false;
|
||||
|
||||
$number = $this->number_def->validate($number, $config, $context);
|
||||
if ($number === false) return false;
|
||||
|
||||
return $number . $unit;
|
||||
|
||||
// Optimizations
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
if ($string === '0') {
|
||||
return '0';
|
||||
}
|
||||
if (strlen($string) === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$length = HTMLPurifier_Length::make($string);
|
||||
if (!$length->isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->min) {
|
||||
$c = $length->compareTo($this->min);
|
||||
if ($c === false) {
|
||||
return false;
|
||||
}
|
||||
if ($c < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($this->max) {
|
||||
$c = $length->compareTo($this->max);
|
||||
if ($c === false) {
|
||||
return false;
|
||||
}
|
||||
if ($c > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $length->toString();
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -8,36 +8,23 @@ class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Local copy of validators.
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
* Local copy of component validators.
|
||||
* @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl.
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
public function __construct($config) {
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['list-style-type'] = $def->info['list-style-type'];
|
||||
$this->info['list-style-position'] = $def->info['list-style-position'];
|
||||
$this->info['list-style-image'] = $def->info['list-style-image'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
// regular pre-processing
|
||||
$string = $this->parseCDATA($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
if ($string === '') return false;
|
||||
|
||||
// assumes URI doesn't have spaces in it
|
||||
$bits = explode(' ', strtolower($string)); // bits to process
|
||||
@@ -51,29 +38,16 @@ class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
|
||||
$none = false;
|
||||
|
||||
foreach ($bits as $bit) {
|
||||
if ($i >= 3) {
|
||||
return;
|
||||
} // optimization bit
|
||||
if ($bit === '') {
|
||||
continue;
|
||||
}
|
||||
if ($i >= 3) return; // optimization bit
|
||||
if ($bit === '') continue;
|
||||
foreach ($caught as $key => $status) {
|
||||
if ($status !== false) {
|
||||
continue;
|
||||
}
|
||||
if ($status !== false) continue;
|
||||
$r = $this->info['list-style-' . $key]->validate($bit, $config, $context);
|
||||
if ($r === false) {
|
||||
continue;
|
||||
}
|
||||
if ($r === false) continue;
|
||||
if ($r === 'none') {
|
||||
if ($none) {
|
||||
continue;
|
||||
} else {
|
||||
$none = true;
|
||||
}
|
||||
if ($key == 'image') {
|
||||
continue;
|
||||
}
|
||||
if ($none) continue;
|
||||
else $none = true;
|
||||
if ($key == 'image') continue;
|
||||
}
|
||||
$caught[$key] = $r;
|
||||
$i++;
|
||||
@@ -81,32 +55,23 @@ class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
|
||||
}
|
||||
}
|
||||
|
||||
if (!$i) {
|
||||
return false;
|
||||
}
|
||||
if (!$i) return false;
|
||||
|
||||
$ret = array();
|
||||
|
||||
// construct type
|
||||
if ($caught['type']) {
|
||||
$ret[] = $caught['type'];
|
||||
}
|
||||
if ($caught['type']) $ret[] = $caught['type'];
|
||||
|
||||
// construct image
|
||||
if ($caught['image']) {
|
||||
$ret[] = $caught['image'];
|
||||
}
|
||||
if ($caught['image']) $ret[] = $caught['image'];
|
||||
|
||||
// construct position
|
||||
if ($caught['position']) {
|
||||
$ret[] = $caught['position'];
|
||||
if ($caught['position']) $ret[] = $caught['position'];
|
||||
|
||||
if (empty($ret)) return false;
|
||||
return implode(' ', $ret);
|
||||
|
||||
}
|
||||
|
||||
if (empty($ret)) {
|
||||
return false;
|
||||
}
|
||||
return implode(' ', $ret);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user