mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-08-04 05:07:55 +02:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d516e2f8de | ||
|
631021733b | ||
|
344e0640b6 | ||
|
62d2550e16 | ||
|
087145a71b | ||
|
a44187a5c1 | ||
|
c0ad68108a | ||
|
83a574491e | ||
|
3b537365a4 | ||
|
8a8b123d33 | ||
|
72db575446 | ||
|
d8bb73ce46 | ||
|
f90372f8ab | ||
|
f38fca32a9 | ||
|
5a23004652 | ||
|
6705140082 | ||
|
cb7162a995 | ||
|
2189a9430f | ||
|
7291f19347 | ||
|
9fcffd6533 | ||
|
31dce298ea | ||
|
8c9d461a62 | ||
|
7291a9647e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -20,3 +20,5 @@ docs/doxygen*
|
||||
*.htmlt.ini
|
||||
*.patch
|
||||
/*.php
|
||||
vendor
|
||||
composer.lock
|
||||
|
2
Doxyfile
2
Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 4.4.0
|
||||
PROJECT_NUMBER = 4.5.0
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
2
FOCUS
2
FOCUS
@@ -1,4 +1,4 @@
|
||||
8 - Minor security fixes
|
||||
4 - Minor feature enhancements
|
||||
|
||||
[ Appendix A: Release focus IDs ]
|
||||
0 - N/A
|
||||
|
26
NEWS
26
NEWS
@@ -9,6 +9,30 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
. Internal change
|
||||
==========================
|
||||
|
||||
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.EnableExcludes; can be set to 'false' 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
|
||||
'false'.
|
||||
- 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
|
||||
@@ -21,7 +45,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
: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.
|
||||
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
|
||||
|
3
TODO
3
TODO
@@ -13,6 +13,7 @@ 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
|
||||
@@ -31,7 +32,7 @@ Things to do as soon as possible:
|
||||
FUTURE VERSIONS
|
||||
---------------
|
||||
|
||||
4.5 release [OMG CONFIG PONIES]
|
||||
4.6 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)
|
||||
|
14
WHATSNEW
14
WHATSNEW
@@ -1,8 +1,6 @@
|
||||
HTML Purifier 4.4.0 is a minor security release addressing a security
|
||||
vulnerability associated with some optional functionality. It also
|
||||
contains an accumulation of new features and bugfixes over half a year.
|
||||
New configuration options include %HTML.TargetBlank,
|
||||
%HTML.AllowedComments, %HTML.AllowedCommentsRegexp, %HTML.SafeIframe,
|
||||
%URI.SafeIframeRegexp, %Core.EnableIDNA (requires PEAR Net_IDNA2 module and
|
||||
doesn't work for PHP 5.0.5). We also now support the 'scope' attribute on
|
||||
tables.
|
||||
HTML Purifier 4.5.0 is a minor bugfix and feature release, containing an
|
||||
accumulation of changes over a year. CSS support has been extended to
|
||||
support display:inline-block, white-space, underscores in font families,
|
||||
page-break-* CSS3 properties (when proprietary is enabled.) We now use
|
||||
SHA-1 to identify cached definitions, and the semantics of stacked
|
||||
attribute transforms has changed slightly.
|
||||
|
22
composer.json
Normal file
22
composer.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"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"]
|
||||
}
|
||||
}
|
@@ -24,32 +24,32 @@
|
||||
</directive>
|
||||
<directive id="CSS.Proprietary">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>214</line>
|
||||
<line>215</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowTricky">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>218</line>
|
||||
<line>219</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.Trusted">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>222</line>
|
||||
<line>223</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowImportant">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>226</line>
|
||||
<line>227</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.AllowedProperties">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>296</line>
|
||||
<line>302</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.ForbiddenProperties">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>310</line>
|
||||
<line>316</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Cache.DefinitionImpl">
|
||||
@@ -80,18 +80,18 @@
|
||||
<directive id="Core.Encoding">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>337</line>
|
||||
<line>367</line>
|
||||
<line>372</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Test.ForceNoIconv">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>341</line>
|
||||
<line>374</line>
|
||||
<line>379</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.EscapeNonASCIICharacters">
|
||||
<file name="HTMLPurifier/Encoder.php">
|
||||
<line>368</line>
|
||||
<line>373</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.CommentScriptContents">
|
||||
@@ -209,14 +209,22 @@
|
||||
<line>228</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Nofollow">
|
||||
<directive id="HTML.SafeScripting">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>231</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/HTMLModule/SafeScripting.php">
|
||||
<line>17</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Nofollow">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>234</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.TargetBlank">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>234</line>
|
||||
<line>237</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.IDBlacklist">
|
||||
@@ -254,7 +262,7 @@
|
||||
</directive>
|
||||
<directive id="URI.">
|
||||
<file name="HTMLPurifier/URIDefinition.php">
|
||||
<line>59</line>
|
||||
<line>60</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/URIFilter/Munge.php">
|
||||
<line>12</line>
|
||||
@@ -262,7 +270,7 @@
|
||||
</directive>
|
||||
<directive id="URI.Host">
|
||||
<file name="HTMLPurifier/URIDefinition.php">
|
||||
<line>69</line>
|
||||
<line>70</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/URIScheme.php">
|
||||
<line>81</line>
|
||||
@@ -270,12 +278,12 @@
|
||||
</directive>
|
||||
<directive id="URI.Base">
|
||||
<file name="HTMLPurifier/URIDefinition.php">
|
||||
<line>70</line>
|
||||
<line>71</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.DefaultScheme">
|
||||
<file name="HTMLPurifier/URIDefinition.php">
|
||||
<line>77</line>
|
||||
<line>78</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.AllowedSchemes">
|
||||
@@ -411,17 +419,17 @@
|
||||
</directive>
|
||||
<directive id="Filter.ExtractStyleBlocks.TidyImpl">
|
||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
||||
<line>54</line>
|
||||
<line>55</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Filter.ExtractStyleBlocks.Scope">
|
||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
||||
<line>78</line>
|
||||
<line>79</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Filter.ExtractStyleBlocks.Escaping">
|
||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
||||
<line>276</line>
|
||||
<line>277</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.SafeIframe">
|
||||
@@ -465,12 +473,12 @@
|
||||
</directive>
|
||||
<directive id="AutoFormat.RemoveEmpty.RemoveNbsp">
|
||||
<file name="HTMLPurifier/Injector/RemoveEmpty.php">
|
||||
<line>12</line>
|
||||
<line>15</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions">
|
||||
<file name="HTMLPurifier/Injector/RemoveEmpty.php">
|
||||
<line>13</line>
|
||||
<line>16</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.AggressivelyFixLt">
|
||||
@@ -483,6 +491,11 @@
|
||||
<line>70</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.DisableExcludes">
|
||||
<file name="HTMLPurifier/Strategy/FixNesting.php">
|
||||
<line>57</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.EscapeInvalidTags">
|
||||
<file name="HTMLPurifier/Strategy/MakeWellFormed.php">
|
||||
<line>53</line>
|
||||
|
4
library/HTMLPurifier.composer.php
Normal file
4
library/HTMLPurifier.composer.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
if (!defined('HTMLPURIFIER_PREFIX')) {
|
||||
define('HTMLPURIFIER_PREFIX', __DIR__);
|
||||
}
|
@@ -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.4.0
|
||||
* @version 4.5.0
|
||||
*
|
||||
* @warning
|
||||
* You must *not* include any other HTML Purifier files before this file,
|
||||
@@ -165,6 +165,7 @@ 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';
|
||||
|
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
HTML Purifier 4.4.0 - Standards Compliant HTML Filtering
|
||||
HTML Purifier 4.5.0 - Standards Compliant HTML Filtering
|
||||
Copyright (C) 2006-2008 Edward Z. Yang
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
@@ -55,10 +55,10 @@ class HTMLPurifier
|
||||
{
|
||||
|
||||
/** Version of HTML Purifier */
|
||||
public $version = '4.4.0';
|
||||
public $version = '4.5.0';
|
||||
|
||||
/** Constant with version of HTML Purifier */
|
||||
const VERSION = '4.4.0';
|
||||
const VERSION = '4.5.0';
|
||||
|
||||
/** Global configuration object */
|
||||
public $config;
|
||||
|
@@ -159,6 +159,7 @@ 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';
|
||||
|
@@ -32,7 +32,7 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
$string = $this->mungeRgb($string);
|
||||
|
||||
// assumes URI doesn't have spaces in it
|
||||
$bits = explode(' ', strtolower($string)); // bits to process
|
||||
$bits = explode(' ', $string); // bits to process
|
||||
|
||||
$caught = array();
|
||||
$caught['color'] = false;
|
||||
|
@@ -9,7 +9,7 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
||||
protected $mask = null;
|
||||
|
||||
public function __construct() {
|
||||
$this->mask = '- ';
|
||||
$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
|
||||
@@ -165,7 +165,7 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
||||
// extensive research, we may feel comfortable with dropping
|
||||
// it down to edgy.
|
||||
|
||||
// Edgy: alphanumeric, spaces, dashes and Unicode. Use of
|
||||
// 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)) {
|
||||
|
@@ -14,7 +14,8 @@ class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef
|
||||
$string = trim($string);
|
||||
|
||||
if (empty($string)) return false;
|
||||
if (isset($colors[strtolower($string)])) return $colors[$string];
|
||||
$lower = strtolower($string);
|
||||
if (isset($colors[$lower])) return $colors[$lower];
|
||||
if ($string[0] === '#') $hex = substr($string, 1);
|
||||
else $hex = $string;
|
||||
|
||||
|
@@ -26,7 +26,7 @@ class HTMLPurifier_AttrTransform_Nofollow extends HTMLPurifier_AttrTransform
|
||||
|
||||
if ($scheme->browsable && !$url->isLocal($config, $context)) {
|
||||
if (isset($attr['rel'])) {
|
||||
$rels = explode(' ', $attr);
|
||||
$rels = explode(' ', $attr['rel']);
|
||||
if (!in_array('nofollow', $rels)) {
|
||||
$rels[] = 'nofollow';
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@ class HTMLPurifier_AttrTransform_TargetBlank extends HTMLPurifier_AttrTransform
|
||||
$scheme = $url->getSchemeObj($config, $context);
|
||||
|
||||
if ($scheme->browsable && !$url->isBenign($config, $context)) {
|
||||
$attr['target'] = 'blank';
|
||||
$attr['target'] = '_blank';
|
||||
}
|
||||
|
||||
return $attr;
|
||||
|
@@ -70,32 +70,37 @@ class HTMLPurifier_Bootstrap
|
||||
if ( ($funcs = spl_autoload_functions()) === false ) {
|
||||
spl_autoload_register($autoload);
|
||||
} elseif (function_exists('spl_autoload_unregister')) {
|
||||
$buggy = version_compare(PHP_VERSION, '5.2.11', '<');
|
||||
$compat = version_compare(PHP_VERSION, '5.1.2', '<=') &&
|
||||
version_compare(PHP_VERSION, '5.1.0', '>=');
|
||||
foreach ($funcs as $func) {
|
||||
if ($buggy && is_array($func)) {
|
||||
// :TRICKY: There are some compatibility issues and some
|
||||
// places where we need to error out
|
||||
$reflector = new ReflectionMethod($func[0], $func[1]);
|
||||
if (!$reflector->isStatic()) {
|
||||
throw new Exception('
|
||||
HTML Purifier autoloader registrar is not compatible
|
||||
with non-static object methods due to PHP Bug #44144;
|
||||
Please do not use HTMLPurifier.autoload.php (or any
|
||||
file that includes this file); instead, place the code:
|
||||
spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\'))
|
||||
after your own autoloaders.
|
||||
');
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
// prepend flag exists, no need for shenanigans
|
||||
spl_autoload_register($autoload, true, true);
|
||||
} else {
|
||||
$buggy = version_compare(PHP_VERSION, '5.2.11', '<');
|
||||
$compat = version_compare(PHP_VERSION, '5.1.2', '<=') &&
|
||||
version_compare(PHP_VERSION, '5.1.0', '>=');
|
||||
foreach ($funcs as $func) {
|
||||
if ($buggy && is_array($func)) {
|
||||
// :TRICKY: There are some compatibility issues and some
|
||||
// places where we need to error out
|
||||
$reflector = new ReflectionMethod($func[0], $func[1]);
|
||||
if (!$reflector->isStatic()) {
|
||||
throw new Exception('
|
||||
HTML Purifier autoloader registrar is not compatible
|
||||
with non-static object methods due to PHP Bug #44144;
|
||||
Please do not use HTMLPurifier.autoload.php (or any
|
||||
file that includes this file); instead, place the code:
|
||||
spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\'))
|
||||
after your own autoloaders.
|
||||
');
|
||||
}
|
||||
// Suprisingly, spl_autoload_register supports the
|
||||
// Class::staticMethod callback format, although call_user_func doesn't
|
||||
if ($compat) $func = implode('::', $func);
|
||||
}
|
||||
// Suprisingly, spl_autoload_register supports the
|
||||
// Class::staticMethod callback format, although call_user_func doesn't
|
||||
if ($compat) $func = implode('::', $func);
|
||||
spl_autoload_unregister($func);
|
||||
}
|
||||
spl_autoload_unregister($func);
|
||||
spl_autoload_register($autoload);
|
||||
foreach ($funcs as $func) spl_autoload_register($func);
|
||||
}
|
||||
spl_autoload_register($autoload);
|
||||
foreach ($funcs as $func) spl_autoload_register($func);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -208,8 +208,9 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
||||
|
||||
$this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2);
|
||||
|
||||
// partial support
|
||||
$this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(array('nowrap'));
|
||||
// These CSS properties don't work on many browsers, but we live
|
||||
// in THE FUTURE!
|
||||
$this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line'));
|
||||
|
||||
if ($config->get('CSS.Proprietary')) {
|
||||
$this->doSetupProprietary($config);
|
||||
@@ -249,12 +250,17 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
||||
// only opacity, for now
|
||||
$this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter();
|
||||
|
||||
// more CSS3
|
||||
$this->info['page-break-after'] =
|
||||
$this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum(array('auto','always','avoid','left','right'));
|
||||
$this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto','avoid'));
|
||||
|
||||
}
|
||||
|
||||
protected function doSetupTricky($config) {
|
||||
$this->info['display'] = new HTMLPurifier_AttrDef_Enum(array(
|
||||
'inline', 'block', 'list-item', 'run-in', 'compact',
|
||||
'marker', 'table', 'inline-table', 'table-row-group',
|
||||
'marker', 'table', 'inline-block', 'inline-table', 'table-row-group',
|
||||
'table-header-group', 'table-footer-group', 'table-row',
|
||||
'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none'
|
||||
));
|
||||
|
@@ -20,7 +20,7 @@ class HTMLPurifier_Config
|
||||
/**
|
||||
* HTML Purifier's version
|
||||
*/
|
||||
public $version = '4.4.0';
|
||||
public $version = '4.5.0';
|
||||
|
||||
/**
|
||||
* Bool indicator whether or not to automatically finalize
|
||||
@@ -189,7 +189,7 @@ class HTMLPurifier_Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a md5 signature of a segment of the configuration object
|
||||
* Returns a SHA-1 signature of a segment of the configuration object
|
||||
* that uniquely identifies that particular configuration
|
||||
* @note Revision is handled specially and is removed from the batch
|
||||
* before processing!
|
||||
@@ -199,18 +199,18 @@ class HTMLPurifier_Config
|
||||
if (empty($this->serials[$namespace])) {
|
||||
$batch = $this->getBatch($namespace);
|
||||
unset($batch['DefinitionRev']);
|
||||
$this->serials[$namespace] = md5(serialize($batch));
|
||||
$this->serials[$namespace] = sha1(serialize($batch));
|
||||
}
|
||||
return $this->serials[$namespace];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a md5 signature for the entire configuration object
|
||||
* Returns a SHA-1 signature for the entire configuration object
|
||||
* that uniquely identifies that particular configuration
|
||||
*/
|
||||
public function getSerial() {
|
||||
if (empty($this->serial)) {
|
||||
$this->serial = md5(serialize($this->getAll()));
|
||||
$this->serial = sha1(serialize($this->getAll()));
|
||||
}
|
||||
return $this->serial;
|
||||
}
|
||||
@@ -682,6 +682,7 @@ class HTMLPurifier_Config
|
||||
$trace = debug_backtrace();
|
||||
// zip(tail(trace), trace) -- but PHP is not Haskell har har
|
||||
for ($i = 0, $c = count($trace); $i < $c - 1; $i++) {
|
||||
// XXX this is not correct on some versions of HTML Purifier
|
||||
if ($trace[$i + 1]['class'] === 'HTMLPurifier_Config') {
|
||||
continue;
|
||||
}
|
||||
|
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
Core.DisableExcludes
|
||||
TYPE: bool
|
||||
DEFAULT: false
|
||||
VERSION: 4.5.0
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
This directive disables SGML-style exclusions, e.g. the exclusion of
|
||||
<code><object></code> in any descendant of a
|
||||
<code><pre></code> tag. Disabling excludes will allow some
|
||||
invalid documents to pass through HTML Purifier, but HTML Purifier
|
||||
will also be less likely to accidentally remove large documents during
|
||||
processing.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@@ -0,0 +1,10 @@
|
||||
HTML.SafeScripting
|
||||
TYPE: lookup
|
||||
VERSION: 4.5.0
|
||||
DEFAULT: array()
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
Whether or not to permit script tags to external scripts in documents.
|
||||
Inline scripting is not allowed, and the script must match an explicit whitelist.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@@ -30,13 +30,25 @@ class HTMLPurifier_ElementDef
|
||||
*/
|
||||
public $attr = array();
|
||||
|
||||
// XXX: Design note: currently, it's not possible to override
|
||||
// previously defined AttrTransforms without messing around with
|
||||
// the final generated config. This is by design; a previous version
|
||||
// used an associated list of attr_transform, but it was extremely
|
||||
// easy to accidentally override other attribute transforms by
|
||||
// forgetting to specify an index (and just using 0.) While we
|
||||
// could check this by checking the index number and complaining,
|
||||
// there is a second problem which is that it is not at all easy to
|
||||
// tell when something is getting overridden. Combine this with a
|
||||
// codebase where this isn't really being used, and it's perfect for
|
||||
// nuking.
|
||||
|
||||
/**
|
||||
* Indexed list of tag's HTMLPurifier_AttrTransform to be done before validation
|
||||
* List of tags HTMLPurifier_AttrTransform to be done before validation
|
||||
*/
|
||||
public $attr_transform_pre = array();
|
||||
|
||||
/**
|
||||
* Indexed list of tag's HTMLPurifier_AttrTransform to be done after validation
|
||||
* List of tags HTMLPurifier_AttrTransform to be done after validation
|
||||
*/
|
||||
public $attr_transform_post = array();
|
||||
|
||||
@@ -144,9 +156,9 @@ class HTMLPurifier_ElementDef
|
||||
}
|
||||
$this->attr[$k] = $v;
|
||||
}
|
||||
$this->_mergeAssocArray($this->attr_transform_pre, $def->attr_transform_pre);
|
||||
$this->_mergeAssocArray($this->attr_transform_post, $def->attr_transform_post);
|
||||
$this->_mergeAssocArray($this->excludes, $def->excludes);
|
||||
$this->attr_transform_pre = array_merge($this->attr_transform_pre, $def->attr_transform_pre);
|
||||
$this->attr_transform_post = array_merge($this->attr_transform_post, $def->attr_transform_post);
|
||||
|
||||
if(!empty($def->content_model)) {
|
||||
$this->content_model =
|
||||
|
@@ -355,7 +355,12 @@ class HTMLPurifier_Encoder
|
||||
$str = utf8_encode($str);
|
||||
return $str;
|
||||
}
|
||||
trigger_error('Encoding not supported, please install iconv', E_USER_ERROR);
|
||||
$bug = HTMLPurifier_Encoder::testIconvTruncateBug();
|
||||
if ($bug == self::ICONV_OK) {
|
||||
trigger_error('Encoding not supported, please install iconv', E_USER_ERROR);
|
||||
} else {
|
||||
trigger_error('You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 and http://sourceware.org/bugzilla/show_bug.cgi?id=13541', E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -33,6 +33,7 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
|
||||
|
||||
public function __construct() {
|
||||
$this->_tidy = new csstidy();
|
||||
$this->_tidy->set_cfg('lowercase_s', false);
|
||||
$this->_id_attrdef = new HTMLPurifier_AttrDef_HTML_ID(true);
|
||||
$this->_class_attrdef = new HTMLPurifier_AttrDef_CSS_Ident();
|
||||
$this->_enum_attrdef = new HTMLPurifier_AttrDef_Enum(array('first-child', 'link', 'visited', 'active', 'hover', 'focus'));
|
||||
|
@@ -21,7 +21,7 @@ class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule
|
||||
// inclusions wrong for bdo: bdo allows Lang
|
||||
)
|
||||
);
|
||||
$bdo->attr_transform_post['required-dir'] = new HTMLPurifier_AttrTransform_BdoDir();
|
||||
$bdo->attr_transform_post[] = new HTMLPurifier_AttrTransform_BdoDir();
|
||||
|
||||
$this->attr_collections['I18N']['dir'] = 'Enum#ltr,rtl';
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ class HTMLPurifier_HTMLModule_Name extends HTMLPurifier_HTMLModule
|
||||
$element = $this->addBlankElement($name);
|
||||
$element->attr['name'] = 'CDATA';
|
||||
if (!$config->get('HTML.Attr.Name.UseCDATA')) {
|
||||
$element->attr_transform_post['NameSync'] = new HTMLPurifier_AttrTransform_NameSync();
|
||||
$element->attr_transform_post[] = new HTMLPurifier_AttrTransform_NameSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
37
library/HTMLPurifier/HTMLModule/SafeScripting.php
Normal file
37
library/HTMLPurifier/HTMLModule/SafeScripting.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A "safe" script module. No inline JS is allowed, and pointed to JS
|
||||
* files must match whitelist.
|
||||
*/
|
||||
class HTMLPurifier_HTMLModule_SafeScripting extends HTMLPurifier_HTMLModule
|
||||
{
|
||||
|
||||
public $name = 'SafeScripting';
|
||||
|
||||
public function setup($config) {
|
||||
|
||||
// These definitions are not intrinsically safe: the attribute transforms
|
||||
// are a vital part of ensuring safety.
|
||||
|
||||
$allowed = $config->get('HTML.SafeScripting');
|
||||
$script = $this->addElement(
|
||||
'script',
|
||||
'Inline',
|
||||
'Empty',
|
||||
null,
|
||||
array(
|
||||
// While technically not required by the spec, we're forcing
|
||||
// it to this value.
|
||||
'type' => 'Enum#text/javascript',
|
||||
'src*' => new HTMLPurifier_AttrDef_Enum(array_keys($allowed))
|
||||
)
|
||||
);
|
||||
$script->attr_transform_pre[] =
|
||||
$script->attr_transform_post[] = new HTMLPurifier_AttrTransform_ScriptRequired();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@@ -45,8 +45,8 @@ class HTMLPurifier_HTMLModule_Scripting extends HTMLPurifier_HTMLModule
|
||||
);
|
||||
$this->info['script']->content_model = '#PCDATA';
|
||||
$this->info['script']->content_model_type = 'optional';
|
||||
$this->info['script']->attr_transform_pre['type'] =
|
||||
$this->info['script']->attr_transform_post['type'] =
|
||||
$this->info['script']->attr_transform_pre[] =
|
||||
$this->info['script']->attr_transform_post[] =
|
||||
new HTMLPurifier_AttrTransform_ScriptRequired();
|
||||
}
|
||||
}
|
||||
|
@@ -228,6 +228,9 @@ class HTMLPurifier_HTMLModuleManager
|
||||
if ($config->get('HTML.SafeEmbed')) {
|
||||
$modules[] = 'SafeEmbed';
|
||||
}
|
||||
if ($config->get('HTML.SafeScripting') !== array()) {
|
||||
$modules[] = 'SafeScripting';
|
||||
}
|
||||
if ($config->get('HTML.Nofollow')) {
|
||||
$modules[] = 'Nofollow';
|
||||
}
|
||||
|
@@ -5,6 +5,9 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
|
||||
|
||||
private $context, $config, $attrValidator, $removeNbsp, $removeNbspExceptions;
|
||||
|
||||
// TODO: make me configurable
|
||||
private $_exclude = array('colgroup' => 1, 'th' => 1, 'td' => 1, 'iframe' => 1);
|
||||
|
||||
public function prepare($config, $context) {
|
||||
parent::prepare($config, $context);
|
||||
$this->config = $config;
|
||||
@@ -30,7 +33,7 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
|
||||
break;
|
||||
}
|
||||
if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
|
||||
if ($token->name == 'colgroup') return;
|
||||
if (isset($this->_exclude[$token->name])) return;
|
||||
$this->attrValidator->validateToken($token, $this->config, $this->context);
|
||||
$token->armor['ValidateAttributes'] = true;
|
||||
if (isset($token->attr['id']) || isset($token->attr['name'])) return;
|
||||
|
@@ -26,6 +26,22 @@
|
||||
* translated into text depends on the child definitions.
|
||||
*
|
||||
* @todo Enable nodes to be bubbled out of the structure.
|
||||
*
|
||||
* @warning This algorithm (though it may be hard to see) proceeds from
|
||||
* a top-down fashion. Thus, parents are processed before
|
||||
* children. This is easy to implement and has a nice effiency
|
||||
* benefit, in that if a node is removed, we never waste any
|
||||
* time processing it, but it also means that if a child
|
||||
* changes in a non-encapsulated way (e.g. it is removed), we
|
||||
* need to go back and reprocess the parent to see if those
|
||||
* changes resulted in problems for the parent. See
|
||||
* [BACKTRACK] for an example of this. In the current
|
||||
* implementation, this backtracking can only be triggered when
|
||||
* a node is removed and if that node was the sole node, the
|
||||
* parent would need to be removed. As such, it is easy to see
|
||||
* that backtracking only incurs constant overhead. If more
|
||||
* sophisticated backtracking is implemented, care must be
|
||||
* taken to avoid nontermination or exponential blowup.
|
||||
*/
|
||||
|
||||
class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
|
||||
@@ -38,6 +54,8 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
|
||||
// get a copy of the HTML definition
|
||||
$definition = $config->getHTMLDefinition();
|
||||
|
||||
$excludes_enabled = !$config->get('Core.DisableExcludes');
|
||||
|
||||
// insert implicit "parent" node, will be removed at end.
|
||||
// DEFINITION CALL
|
||||
$parent_name = $definition->info_parent;
|
||||
@@ -147,7 +165,7 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
|
||||
// parent exclusions. The array should not be very large, two
|
||||
// elements at most.
|
||||
$excluded = false;
|
||||
if (!empty($exclude_stack)) {
|
||||
if (!empty($exclude_stack) && $excludes_enabled) {
|
||||
foreach ($exclude_stack as $lookup) {
|
||||
if (isset($lookup[$tokens[$i]->name])) {
|
||||
$excluded = true;
|
||||
@@ -235,7 +253,7 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
|
||||
// our current implementation claims that that case would
|
||||
// not allow empty, even if it did
|
||||
if (!$parent_def->child->allow_empty) {
|
||||
// we need to do a double-check
|
||||
// we need to do a double-check [BACKTRACK]
|
||||
$i = $parent_index;
|
||||
array_pop($stack);
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ class HTMLPurifier_URIDefinition extends HTMLPurifier_Definition
|
||||
public function __construct() {
|
||||
$this->registerFilter(new HTMLPurifier_URIFilter_DisableExternal());
|
||||
$this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources());
|
||||
$this->registerFilter(new HTMLPurifier_URIFilter_DisableResources());
|
||||
$this->registerFilter(new HTMLPurifier_URIFilter_HostBlacklist());
|
||||
$this->registerFilter(new HTMLPurifier_URIFilter_SafeIframe());
|
||||
$this->registerFilter(new HTMLPurifier_URIFilter_MakeAbsolute());
|
||||
|
@@ -64,10 +64,12 @@ class HTMLPurifier_URIScheme_data extends HTMLPurifier_URIScheme {
|
||||
file_put_contents($file, $raw_data);
|
||||
if (function_exists('exif_imagetype')) {
|
||||
$image_code = exif_imagetype($file);
|
||||
unlink($file);
|
||||
} elseif (function_exists('getimagesize')) {
|
||||
set_error_handler(array($this, 'muteErrorHandler'));
|
||||
$info = getimagesize($file);
|
||||
restore_error_handler();
|
||||
unlink($file);
|
||||
if ($info == false) return false;
|
||||
$image_code = $info[2];
|
||||
} else {
|
||||
|
@@ -9,6 +9,7 @@ class HTMLPurifier_AttrDef_HTML_ColorTest extends HTMLPurifier_AttrDefHarness
|
||||
$this->assertDef('foo', false);
|
||||
$this->assertDef('43', false);
|
||||
$this->assertDef('red', '#FF0000');
|
||||
$this->assertDef('RED', '#FF0000');
|
||||
$this->assertDef('#FF0000');
|
||||
$this->assertDef('#453443');
|
||||
$this->assertDef('453443', '#453443');
|
||||
|
@@ -22,12 +22,16 @@ class HTMLPurifier_ElementDefTest extends HTMLPurifier_Harness
|
||||
'overloaded-attr' => $overloaded_old,
|
||||
'removed-attr' => $removed,
|
||||
);
|
||||
/*
|
||||
$def1->attr_transform_pre =
|
||||
$def1->attr_transform_post = array(
|
||||
'old-transform' => $old,
|
||||
'overloaded-transform' => $overloaded_old,
|
||||
'removed-transform' => $removed,
|
||||
);
|
||||
*/
|
||||
$def1->attr_transform_pre[] = $old;
|
||||
$def1->attr_transform_post[] = $old;
|
||||
$def1->child = $overloaded_old;
|
||||
$def1->content_model = 'old';
|
||||
$def1->content_model_type = $overloaded_old;
|
||||
@@ -44,12 +48,16 @@ class HTMLPurifier_ElementDefTest extends HTMLPurifier_Harness
|
||||
'overloaded-attr' => $overloaded_new,
|
||||
'removed-attr' => false,
|
||||
);
|
||||
/*
|
||||
$def2->attr_transform_pre =
|
||||
$def2->attr_transform_post = array(
|
||||
'new-transform' => $new,
|
||||
'overloaded-transform' => $overloaded_new,
|
||||
'removed-transform' => false,
|
||||
);
|
||||
*/
|
||||
$def2->attr_transform_pre[] = $new;
|
||||
$def2->attr_transform_post[] = $new;
|
||||
$def2->child = $new;
|
||||
$def2->content_model = '#SUPER | new';
|
||||
$def2->content_model_type = $overloaded_new;
|
||||
@@ -70,11 +78,14 @@ class HTMLPurifier_ElementDefTest extends HTMLPurifier_Harness
|
||||
'new-attr' => $new,
|
||||
));
|
||||
$this->assertIdentical($def1->attr_transform_pre, $def1->attr_transform_post);
|
||||
$this->assertIdentical($def1->attr_transform_pre, array($old, $new));
|
||||
/*
|
||||
$this->assertIdentical($def1->attr_transform_pre, array(
|
||||
'old-transform' => $old,
|
||||
'overloaded-transform' => $overloaded_new,
|
||||
'new-transform' => $new,
|
||||
));
|
||||
*/
|
||||
$this->assertIdentical($def1->child, $new);
|
||||
$this->assertIdentical($def1->content_model, 'old | new');
|
||||
$this->assertIdentical($def1->content_model_type, $overloaded_new);
|
||||
|
@@ -39,6 +39,7 @@ class HTMLPurifier_EncoderTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function test_convertToUTF8_spuriousEncoding() {
|
||||
if (!HTMLPurifier_Encoder::iconvAvailable()) return;
|
||||
$this->config->set('Core.Encoding', 'utf99');
|
||||
$this->expectError('Invalid encoding utf99');
|
||||
$this->assertIdentical(
|
||||
@@ -87,7 +88,7 @@ class HTMLPurifier_EncoderTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function test_convertFromUTF8_iconvNoChars() {
|
||||
if (!function_exists('iconv')) return;
|
||||
if (!HTMLPurifier_Encoder::iconvAvailable()) return;
|
||||
$this->config->set('Core.Encoding', 'ISO-8859-1');
|
||||
$this->assertIdentical(
|
||||
HTMLPurifier_Encoder::convertFromUTF8($this->getZhongWen(), $this->config, $this->context),
|
||||
@@ -169,14 +170,16 @@ class HTMLPurifier_EncoderTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function test_testEncodingSupportsASCII() {
|
||||
$this->assertASCIISupportCheck('Shift_JIS', array("\xC2\xA5" => '\\', "\xE2\x80\xBE" => '~'));
|
||||
$this->assertASCIISupportCheck('JOHAB', array("\xE2\x82\xA9" => '\\'));
|
||||
if (HTMLPurifier_Encoder::iconvAvailable()) {
|
||||
$this->assertASCIISupportCheck('Shift_JIS', array("\xC2\xA5" => '\\', "\xE2\x80\xBE" => '~'));
|
||||
$this->assertASCIISupportCheck('JOHAB', array("\xE2\x82\xA9" => '\\'));
|
||||
}
|
||||
$this->assertASCIISupportCheck('ISO-8859-1', array());
|
||||
$this->assertASCIISupportCheck('dontexist', array()); // canary
|
||||
}
|
||||
|
||||
function testShiftJIS() {
|
||||
if (!function_exists('iconv')) return;
|
||||
if (!HTMLPurifier_Encoder::iconvAvailable()) return;
|
||||
$this->config->set('Core.Encoding', 'Shift_JIS');
|
||||
// This actually looks like a Yen, but we're going to treat it differently
|
||||
$this->assertIdentical(
|
||||
@@ -190,7 +193,7 @@ class HTMLPurifier_EncoderTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function testIconvTruncateBug() {
|
||||
if (!function_exists('iconv')) return;
|
||||
if (!HTMLPurifier_Encoder::iconvAvailable()) return;
|
||||
if (HTMLPurifier_Encoder::testIconvTruncateBug() !== HTMLPurifier_Encoder::ICONV_TRUNCATES) return;
|
||||
$this->config->set('Core.Encoding', 'ISO-8859-1');
|
||||
$this->assertIdentical(
|
||||
@@ -200,7 +203,7 @@ class HTMLPurifier_EncoderTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function testIconvChunking() {
|
||||
if (!function_exists('iconv')) return;
|
||||
if (!HTMLPurifier_Encoder::iconvAvailable()) return;
|
||||
if (HTMLPurifier_Encoder::testIconvTruncateBug() !== HTMLPurifier_Encoder::ICONV_TRUNCATES) return;
|
||||
$this->assertIdentical(HTMLPurifier_Encoder::iconv('utf-8', 'iso-8859-1//IGNORE', "a\xF3\xA0\x80\xA0b", 4), 'ab');
|
||||
$this->assertIdentical(HTMLPurifier_Encoder::iconv('utf-8', 'iso-8859-1//IGNORE', "aa\xE4\xB8\xADb", 4), 'aab');
|
||||
|
@@ -226,6 +226,10 @@ text-align:center;
|
||||
$this->assertCleanCSS("doesnt-exist { text-align:center }", "");
|
||||
}
|
||||
|
||||
function test_cleanCSS_caseSensitive() {
|
||||
$this->assertCleanCSS("a .foo #ID div.cl#foo {\nbackground:url(\"http://foo/BAR\");\n}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -6,18 +6,19 @@ class HTMLPurifier_HTMLModule_NofollowTest extends HTMLPurifier_HTMLModuleHarnes
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->config->set('HTML.Nofollow', true);
|
||||
$this->config->set('Attr.AllowedRel', array("nofollow", "blah"));
|
||||
}
|
||||
|
||||
function testNofollow() {
|
||||
$this->assertResult(
|
||||
'<a href="http://google.com">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>',
|
||||
'<a href="http://google.com" rel="nofollow">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>'
|
||||
'<a href="http://google.com">x</a><a href="http://google.com" rel="blah">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>',
|
||||
'<a href="http://google.com" rel="nofollow">x</a><a href="http://google.com" rel="blah nofollow">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>'
|
||||
);
|
||||
}
|
||||
|
||||
function testNofollowDupe() {
|
||||
$this->assertResult(
|
||||
'<a href="http://google.com" rel="nofollow">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>'
|
||||
'<a href="http://google.com" rel="nofollow">x</a><a href="http://google.com" rel="blah nofollow">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>'
|
||||
);
|
||||
}
|
||||
|
||||
|
33
tests/HTMLPurifier/HTMLModule/SafeScriptingTest.php
Normal file
33
tests/HTMLPurifier/HTMLModule/SafeScriptingTest.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
class HTMLPurifier_HTMLModule_SafeScriptingTest extends HTMLPurifier_HTMLModuleHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->config->set('HTML.SafeScripting', array('http://localhost/foo.js'));
|
||||
}
|
||||
|
||||
function testMinimal() {
|
||||
$this->assertResult(
|
||||
'<script></script>',
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
function testGood() {
|
||||
$this->assertResult(
|
||||
'<script type="text/javascript" src="http://localhost/foo.js" />'
|
||||
);
|
||||
}
|
||||
|
||||
function testBad() {
|
||||
$this->assertResult(
|
||||
'<script type="text/javascript" src="http://localhost/foobar.js" />',
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@@ -11,7 +11,7 @@ class HTMLPurifier_HTMLModule_TargetBlankTest extends HTMLPurifier_HTMLModuleHar
|
||||
function testTargetBlank() {
|
||||
$this->assertResult(
|
||||
'<a href="http://google.com">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>',
|
||||
'<a href="http://google.com" target="blank">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>'
|
||||
'<a href="http://google.com" target="_blank">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>'
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
--SKIPIF--
|
||||
if (!function_exists('iconv')) return true;
|
||||
if (!HTMLPurifier_Encoder::iconvAvailable()) return true;
|
||||
--INI--
|
||||
Core.Encoding = "Shift_JIS"
|
||||
Core.EscapeNonASCIICharacters = true
|
||||
|
@@ -1,5 +1,5 @@
|
||||
--SKIPIF--
|
||||
if (!function_exists('iconv')) return true;
|
||||
if (!HTMLPurifier_Encoder::iconvAvailable()) return true;
|
||||
--INI--
|
||||
Core.Encoding = Shift_JIS
|
||||
--HTML--
|
||||
|
@@ -139,6 +139,11 @@ class HTMLPurifier_Strategy_FixNestingTest extends HTMLPurifier_StrategyHarness
|
||||
$this->assertResult('<blockquote>text</blockquote>', '<blockquote><p>text</p></blockquote>');
|
||||
}
|
||||
|
||||
function testDisabledExcludes() {
|
||||
$this->config->set('Core.DisableExcludes', true);
|
||||
$this->assertResult('<pre><font><font></font></font></pre>');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -33,6 +33,12 @@ class HTMLPurifier_URISchemeTest extends HTMLPurifier_URIHarness
|
||||
);
|
||||
}
|
||||
|
||||
function test_http_uppercase() {
|
||||
$this->assertValidation(
|
||||
'http://example.com/FOO'
|
||||
);
|
||||
}
|
||||
|
||||
function test_http_removeDefaultPort() {
|
||||
$this->assertValidation(
|
||||
'http://example.com:80',
|
||||
|
@@ -36,6 +36,11 @@ class HTMLPurifierTest extends HTMLPurifier_Harness
|
||||
);
|
||||
}
|
||||
|
||||
function testDisableResources() {
|
||||
$this->config->set('URI.DisableResources', true);
|
||||
$this->assertPurification('<img src="foo.jpg" />', '');
|
||||
}
|
||||
|
||||
function test_addFilter_deprecated() {
|
||||
$this->expectError('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom');
|
||||
generate_mock_once('HTMLPurifier_Filter');
|
||||
|
Reference in New Issue
Block a user