mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-08-04 13:18:00 +02:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
882ffed9ba | ||
|
86990a21f1 | ||
|
9573f0933d | ||
|
632bf2bbd4 | ||
|
ec86598446 | ||
|
b6c3f5e89b | ||
|
7c91104532 | ||
|
eac628f490 | ||
|
92913bc816 | ||
|
479d793562 | ||
|
e2c15f1c98 | ||
|
57ced3f361 | ||
|
c04a441b3e | ||
|
1bed8b6d5f | ||
|
33afd7d9e0 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -18,3 +18,5 @@ docs/doxygen*
|
||||
*.phpt.php
|
||||
*.phpt.skip.php
|
||||
*.htmlt.ini
|
||||
*.patch
|
||||
/*.php
|
||||
|
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.1.1
|
||||
PROJECT_NUMBER = 4.2.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 @@
|
||||
9 - Major security fixes
|
||||
4 - Minor feature enhancements
|
||||
|
||||
[ Appendix A: Release focus IDs ]
|
||||
0 - N/A
|
||||
|
20
NEWS
20
NEWS
@@ -9,6 +9,26 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
. Internal change
|
||||
==========================
|
||||
|
||||
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
|
||||
|
5
TODO
5
TODO
@@ -20,11 +20,14 @@ Things to do as soon as possible:
|
||||
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
|
||||
|
||||
FUTURE VERSIONS
|
||||
---------------
|
||||
|
||||
4.2 release [OMG CONFIG PONIES]
|
||||
4.3 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)
|
||||
|
13
WHATSNEW
13
WHATSNEW
@@ -1,5 +1,8 @@
|
||||
HTML Purifier 4.1.1 is a major security and bugfix release that
|
||||
improves on 4.1's fix for an XSS vulnerability exploitable on Internet
|
||||
Explorer. It also contains a number of important bugfixes, including
|
||||
the removal of improper logic that could result in infinite loops and
|
||||
fixed parsing for single-attributes with entities with DirectLex.
|
||||
HTML Purifier 4.2.0 is a minor release that implements a number of
|
||||
feature requests accumulated over half a year. New configuration
|
||||
options include %Core.RemoveProcessingInstructions,
|
||||
%CSS.ForbiddenProperties, %HTML.FlashAllowFullScreen and
|
||||
%Core.NormalizeNewlines. Additionally,%URI.DisableResources is
|
||||
now functional and file: is an optionally supported URI scheme.
|
||||
There are also some minor bugfixes, usability improvements and
|
||||
documentation updates.
|
||||
|
@@ -40,12 +40,26 @@
|
||||
</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" />
|
||||
@@ -192,10 +206,13 @@
|
||||
<td>
|
||||
<xsl:variable name="type" select="text()" />
|
||||
<xsl:attribute name="class">type type-<xsl:value-of select="$type" /></xsl:attribute>
|
||||
<xsl:value-of select="$typeLookup/type[@id=$type]/text()" />
|
||||
<xsl:if test="@allow-null='yes'">
|
||||
(or null)
|
||||
</xsl:if>
|
||||
<a>
|
||||
<xsl:attribute name="href">#type-<xsl:value-of select="$type" /></xsl:attribute>
|
||||
<xsl:value-of select="$typeLookup/type[@id=$type]/@name" />
|
||||
<xsl:if test="@allow-null='yes'">
|
||||
(or null)
|
||||
</xsl:if>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
@@ -1,16 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<types>
|
||||
<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>
|
||||
<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>
|
||||
</types>
|
||||
|
||||
<!-- vim: et sw=4 sts=4
|
||||
|
@@ -6,7 +6,7 @@
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>81</line>
|
||||
<line>269</line>
|
||||
<line>284</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
||||
<line>53</line>
|
||||
@@ -42,6 +42,11 @@
|
||||
<line>275</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="CSS.ForbiddenProperties">
|
||||
<file name="HTMLPurifier/CSSDefinition.php">
|
||||
<line>289</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Cache.DefinitionImpl">
|
||||
<file name="HTMLPurifier/DefinitionCacheFactory.php">
|
||||
<line>49</line>
|
||||
@@ -104,10 +109,18 @@
|
||||
<line>87</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.Newline">
|
||||
<directive id="Core.NormalizeNewlines">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>101</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>266</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Output.Newline">
|
||||
<file name="HTMLPurifier/Generator.php">
|
||||
<line>102</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.BlockWrapper">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
@@ -136,12 +149,12 @@
|
||||
</directive>
|
||||
<directive id="HTML.ForbiddenElements">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>337</line>
|
||||
<line>342</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.ForbiddenAttributes">
|
||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
||||
<line>338</line>
|
||||
<line>343</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.Trusted">
|
||||
@@ -149,7 +162,7 @@
|
||||
<line>202</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>258</line>
|
||||
<line>271</line>
|
||||
</file>
|
||||
<file name="HTMLPurifier/HTMLModule/Image.php">
|
||||
<line>27</line>
|
||||
@@ -211,7 +224,12 @@
|
||||
</directive>
|
||||
<directive id="Core.ConvertDocumentToFragment">
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>267</line>
|
||||
<line>282</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.RemoveProcessingInstructions">
|
||||
<file name="HTMLPurifier/Lexer.php">
|
||||
<line>303</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="URI.">
|
||||
@@ -337,6 +355,11 @@
|
||||
<line>13</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.FlashAllowFullScreen">
|
||||
<file name="HTMLPurifier/AttrTransform/SafeParam.php">
|
||||
<line>37</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Core.EscapeInvalidChildren">
|
||||
<file name="HTMLPurifier/ChildDef/Required.php">
|
||||
<line>62</line>
|
||||
|
@@ -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.1.1
|
||||
* @version 4.2.0
|
||||
*
|
||||
* @warning
|
||||
* You must *not* include any other HTML Purifier files before this file,
|
||||
@@ -196,10 +196,12 @@ 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/URIScheme/data.php';
|
||||
require 'HTMLPurifier/URIScheme/file.php';
|
||||
require 'HTMLPurifier/URIScheme/ftp.php';
|
||||
require 'HTMLPurifier/URIScheme/http.php';
|
||||
require 'HTMLPurifier/URIScheme/https.php';
|
||||
|
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
HTML Purifier 4.1.1 - Standards Compliant HTML Filtering
|
||||
HTML Purifier 4.2.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.1.1';
|
||||
public $version = '4.2.0';
|
||||
|
||||
/** Constant with version of HTML Purifier */
|
||||
const VERSION = '4.1.1';
|
||||
const VERSION = '4.2.0';
|
||||
|
||||
/** Global configuration object */
|
||||
public $config;
|
||||
|
@@ -190,10 +190,12 @@ 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/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';
|
||||
|
@@ -33,6 +33,13 @@ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform
|
||||
case 'allowNetworking':
|
||||
$attr['value'] = 'internal';
|
||||
break;
|
||||
case 'allowFullScreen':
|
||||
if ($config->get('HTML.FlashAllowFullScreen')) {
|
||||
$attr['value'] = ($attr['value'] == 'true') ? 'true' : 'false';
|
||||
} else {
|
||||
$attr['value'] = 'false';
|
||||
}
|
||||
break;
|
||||
case 'wmode':
|
||||
$attr['value'] = 'window';
|
||||
break;
|
||||
|
@@ -272,20 +272,29 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
||||
// setup allowed elements
|
||||
$support = "(for information on implementing this, see the ".
|
||||
"support forums) ";
|
||||
$allowed_attributes = $config->get('CSS.AllowedProperties');
|
||||
if ($allowed_attributes !== null) {
|
||||
$allowed_properties = $config->get('CSS.AllowedProperties');
|
||||
if ($allowed_properties !== null) {
|
||||
foreach ($this->info as $name => $d) {
|
||||
if(!isset($allowed_attributes[$name])) unset($this->info[$name]);
|
||||
unset($allowed_attributes[$name]);
|
||||
if(!isset($allowed_properties[$name])) unset($this->info[$name]);
|
||||
unset($allowed_properties[$name]);
|
||||
}
|
||||
// emit errors
|
||||
foreach ($allowed_attributes as $name => $d) {
|
||||
foreach ($allowed_properties as $name => $d) {
|
||||
// :TODO: Is this htmlspecialchars() call really necessary?
|
||||
$name = htmlspecialchars($name);
|
||||
trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
$forbidden_properties = $config->get('CSS.ForbiddenProperties');
|
||||
if ($forbidden_properties !== null) {
|
||||
foreach ($this->info as $name => $d) {
|
||||
if (isset($forbidden_properties[$name])) {
|
||||
unset($this->info[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -20,7 +20,7 @@ class HTMLPurifier_Config
|
||||
/**
|
||||
* HTML Purifier's version
|
||||
*/
|
||||
public $version = '4.1.1';
|
||||
public $version = '4.2.0';
|
||||
|
||||
/**
|
||||
* Bool indicator whether or not to automatically finalize
|
||||
|
Binary file not shown.
0
library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt
Executable file → Normal file
0
library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt
Executable file → Normal file
@@ -0,0 +1,13 @@
|
||||
CSS.ForbiddenProperties
|
||||
TYPE: lookup
|
||||
VERSION: 4.2.0
|
||||
DEFAULT: array()
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
This is the logical inverse of %CSS.AllowedProperties, and it will
|
||||
override that directive or any other directive. If possible,
|
||||
%CSS.AllowedProperties is recommended over this directive,
|
||||
because it can sometimes be difficult to tell whether or not you've
|
||||
forbidden all of the CSS properties you truly would like to disallow.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@@ -0,0 +1,11 @@
|
||||
Core.NormalizeNewlines
|
||||
TYPE: bool
|
||||
VERSION: 4.2.0
|
||||
DEFAULT: true
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
Whether or not to normalize newlines to the operating
|
||||
system default. When <code>false</code>, HTML Purifier
|
||||
will attempt to preserve mixed newline files.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@@ -0,0 +1,11 @@
|
||||
Core.RemoveProcessingInstructions
|
||||
TYPE: bool
|
||||
VERSION: 4.2.0
|
||||
DEFAULT: false
|
||||
--DESCRIPTION--
|
||||
Instead of escaping processing instructions in the form <code><? ...
|
||||
?></code>, remove it out-right. This may be useful if the HTML
|
||||
you are validating contains XML processing instruction gunk, however,
|
||||
it can also be user-unfriendly for people attempting to post PHP
|
||||
snippets.
|
||||
--# vim: et sw=4 sts=4
|
@@ -3,6 +3,11 @@ TYPE: bool
|
||||
VERSION: 3.1.0
|
||||
DEFAULT: false
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
<strong>Warning:</strong> Deprecated in favor of %HTML.SafeObject and
|
||||
%Output.FlashCompat (turn both on to allow YouTube videos and other
|
||||
Flash content).
|
||||
</p>
|
||||
<p>
|
||||
This directive enables YouTube video embedding in HTML Purifier. Check
|
||||
<a href="http://htmlpurifier.org/docs/enduser-youtube.html">this document
|
||||
|
@@ -5,11 +5,14 @@ DEFAULT: NULL
|
||||
--DESCRIPTION--
|
||||
|
||||
<p>
|
||||
This is a convenience directive that rolls the functionality of
|
||||
%HTML.AllowedElements and %HTML.AllowedAttributes into one directive.
|
||||
This is a preferred convenience directive that combines
|
||||
%HTML.AllowedElements and %HTML.AllowedAttributes.
|
||||
Specify elements and attributes that are allowed using:
|
||||
<code>element1[attr1|attr2],element2...</code>. You can also use
|
||||
newlines instead of commas to separate elements.
|
||||
<code>element1[attr1|attr2],element2...</code>. For example,
|
||||
if you would like to only allow paragraphs and links, specify
|
||||
<code>a[href],p</code>. You can specify attributes that apply
|
||||
to all elements using an asterisk, e.g. <code>*[lang]</code>.
|
||||
You can also use newlines instead of commas to separate elements.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Warning</strong>:
|
||||
|
@@ -4,12 +4,17 @@ VERSION: 1.3.0
|
||||
DEFAULT: NULL
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
If HTML Purifier's tag set is unsatisfactory for your needs, you
|
||||
can overload it with your own list of tags to allow. Note that this
|
||||
method is subtractive: it does its job by taking away from HTML Purifier
|
||||
usual feature set, so you cannot add a tag that HTML Purifier never
|
||||
supported in the first place (like embed, form or head). If you
|
||||
change this, you probably also want to change %HTML.AllowedAttributes.
|
||||
If HTML Purifier's tag set is unsatisfactory for your needs, you can
|
||||
overload it with your own list of tags to allow. If you change
|
||||
this, you probably also want to change %HTML.AllowedAttributes; see
|
||||
also %HTML.Allowed which lets you set allowed elements and
|
||||
attributes at the same time.
|
||||
</p>
|
||||
<p>
|
||||
If you attempt to allow an element that HTML Purifier does not know
|
||||
about, HTML Purifier will raise an error. You will need to manually
|
||||
tell HTML Purifier about this element by using the
|
||||
<a href="http://htmlpurifier.org/docs/enduser-customize.html">advanced customization features.</a>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Warning:</strong> If another directive conflicts with the
|
||||
|
@@ -0,0 +1,11 @@
|
||||
HTML.FlashAllowFullScreen
|
||||
TYPE: bool
|
||||
VERSION: 4.2.0
|
||||
DEFAULT: false
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
Whether or not to permit embedded Flash content from
|
||||
%HTML.SafeObject to expand to the full screen. Corresponds to
|
||||
the <code>allowFullScreen</code> parameter.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@@ -12,6 +12,6 @@ array (
|
||||
--DESCRIPTION--
|
||||
Whitelist that defines the schemes that a URI is allowed to have. This
|
||||
prevents XSS attacks from using pseudo-schemes like javascript or mocha.
|
||||
There is also support for the <code>data</code> URI scheme, but it is not
|
||||
enabled by default.
|
||||
There is also support for the <code>data</code> and <code>file</code>
|
||||
URI schemes, but they are not enabled by default.
|
||||
--# vim: et sw=4 sts=4
|
||||
|
@@ -1,12 +1,15 @@
|
||||
URI.DisableResources
|
||||
TYPE: bool
|
||||
VERSION: 1.3.0
|
||||
VERSION: 4.2.0
|
||||
DEFAULT: false
|
||||
--DESCRIPTION--
|
||||
|
||||
<p>
|
||||
Disables embedding resources, essentially meaning no pictures. You can
|
||||
still link to them though. See %URI.DisableExternalResources for why
|
||||
this might be a good idea.
|
||||
</p>
|
||||
<p>
|
||||
<em>Note:</em> While this directive has been available since 1.3.0,
|
||||
it didn't actually start doing anything until 4.2.0.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
||||
|
@@ -98,9 +98,11 @@ class HTMLPurifier_Generator
|
||||
}
|
||||
|
||||
// Normalize newlines to system defined value
|
||||
$nl = $this->config->get('Output.Newline');
|
||||
if ($nl === null) $nl = PHP_EOL;
|
||||
if ($nl !== "\n") $html = str_replace("\n", $nl, $html);
|
||||
if ($this->config->get('Core.NormalizeNewlines')) {
|
||||
$nl = $this->config->get('Output.Newline');
|
||||
if ($nl === null) $nl = PHP_EOL;
|
||||
if ($nl !== "\n") $html = str_replace("\n", $nl, $html);
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
@@ -215,7 +217,10 @@ class HTMLPurifier_Generator
|
||||
* permissible for non-attribute output.
|
||||
* @return String escaped data.
|
||||
*/
|
||||
public function escape($string, $quote = ENT_COMPAT) {
|
||||
public function escape($string, $quote = null) {
|
||||
// Workaround for APC bug on Mac Leopard reported by sidepodcast
|
||||
// http://htmlpurifier.org/phorum/read.php?3,4823,4846
|
||||
if ($quote === null) $quote = ENT_COMPAT;
|
||||
return htmlspecialchars($string, $quote, 'UTF-8');
|
||||
}
|
||||
|
||||
|
@@ -300,7 +300,12 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
|
||||
unset($allowed_attributes_mutable[$key]);
|
||||
}
|
||||
}
|
||||
if ($delete) unset($this->info[$tag]->attr[$attr]);
|
||||
if ($delete) {
|
||||
if ($this->info[$tag]->attr[$attr]->required) {
|
||||
trigger_error("Required attribute '$attr' in element '$tag' was not allowed, which means '$tag' will not be allowed either", E_USER_WARNING);
|
||||
}
|
||||
unset($this->info[$tag]->attr[$attr]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// emit errors
|
||||
|
@@ -22,6 +22,7 @@ class HTMLPurifier_Injector_SafeObject extends HTMLPurifier_Injector
|
||||
'movie' => true,
|
||||
'flashvars' => true,
|
||||
'src' => true,
|
||||
'allowFullScreen' => true, // if omitted, assume to be 'false'
|
||||
);
|
||||
|
||||
public function prepare($config, $context) {
|
||||
|
@@ -230,6 +230,17 @@ class HTMLPurifier_Lexer
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Special Internet Explorer conditional comments should be removed.
|
||||
*/
|
||||
protected static function removeIEConditional($string) {
|
||||
return preg_replace(
|
||||
'#<!--\[if [^>]+\]>.*<!\[endif\]-->#si', // probably should generalize for all strings
|
||||
'',
|
||||
$string
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for escapeCDATA() that does the work.
|
||||
*
|
||||
@@ -252,14 +263,18 @@ class HTMLPurifier_Lexer
|
||||
public function normalize($html, $config, $context) {
|
||||
|
||||
// normalize newlines to \n
|
||||
$html = str_replace("\r\n", "\n", $html);
|
||||
$html = str_replace("\r", "\n", $html);
|
||||
if ($config->get('Core.NormalizeNewlines')) {
|
||||
$html = str_replace("\r\n", "\n", $html);
|
||||
$html = str_replace("\r", "\n", $html);
|
||||
}
|
||||
|
||||
if ($config->get('HTML.Trusted')) {
|
||||
// escape convoluted CDATA
|
||||
$html = $this->escapeCommentedCDATA($html);
|
||||
}
|
||||
|
||||
$html = $this->removeIEConditional($html);
|
||||
|
||||
// escape CDATA
|
||||
$html = $this->escapeCDATA($html);
|
||||
|
||||
@@ -284,6 +299,11 @@ class HTMLPurifier_Lexer
|
||||
// represent non-SGML characters (horror, horror!)
|
||||
$html = HTMLPurifier_Encoder::cleanUTF8($html);
|
||||
|
||||
// if processing instructions are to removed, remove them now
|
||||
if ($config->get('Core.RemoveProcessingInstructions')) {
|
||||
$html = preg_replace('#<\?.+?\?>#s', '', $html);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
@@ -125,8 +125,6 @@ class HTML5 {
|
||||
const EOF = 5;
|
||||
|
||||
public function __construct($data) {
|
||||
$data = str_replace("\r\n", "\n", $data);
|
||||
$data = str_replace("\r", null, $data);
|
||||
|
||||
$this->data = $data;
|
||||
$this->char = -1;
|
||||
|
11
library/HTMLPurifier/URIFilter/DisableResources.php
Normal file
11
library/HTMLPurifier/URIFilter/DisableResources.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class HTMLPurifier_URIFilter_DisableResources extends HTMLPurifier_URIFilter
|
||||
{
|
||||
public $name = 'DisableResources';
|
||||
public function filter(&$uri, $config, $context) {
|
||||
return !$context->get('EmbeddedURI', true);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
26
library/HTMLPurifier/URIScheme/file.php
Normal file
26
library/HTMLPurifier/URIScheme/file.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates file as defined by RFC 1630 and RFC 1738.
|
||||
*/
|
||||
class HTMLPurifier_URIScheme_file extends HTMLPurifier_URIScheme {
|
||||
|
||||
// Generally file:// URLs are not accessible from most
|
||||
// machines, so placing them as an img src is incorrect.
|
||||
public $browsable = false;
|
||||
|
||||
public function validate(&$uri, $config, $context) {
|
||||
parent::validate($uri, $config, $context);
|
||||
// Authentication method is not supported
|
||||
$uri->userinfo = null;
|
||||
// file:// makes no provisions for accessing the resource
|
||||
$uri->port = null;
|
||||
// While it seems to work on Firefox, the querystring has
|
||||
// no possible effect and is thus stripped.
|
||||
$uri->query = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@@ -62,7 +62,7 @@ class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser
|
||||
foreach ($var as $keypair) {
|
||||
$c = explode(':', $keypair, 2);
|
||||
if (!isset($c[1])) continue;
|
||||
$nvar[$c[0]] = $c[1];
|
||||
$nvar[trim($c[0])] = trim($c[1]);
|
||||
}
|
||||
$var = $nvar;
|
||||
}
|
||||
@@ -79,8 +79,15 @@ class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser
|
||||
return $new;
|
||||
} else break;
|
||||
}
|
||||
if ($type === self::ALIST) {
|
||||
trigger_error("Array list did not have consecutive integer indexes", E_USER_WARNING);
|
||||
return array_values($var);
|
||||
}
|
||||
if ($type === self::LOOKUP) {
|
||||
foreach ($var as $key => $value) {
|
||||
if ($value !== true) {
|
||||
trigger_error("Lookup array has non-true value at key '$key'; maybe your input array was not indexed numerically", E_USER_WARNING);
|
||||
}
|
||||
$var[$key] = true;
|
||||
}
|
||||
}
|
||||
|
@@ -144,6 +144,12 @@ class HTMLPurifier_AttrDef_CSSTest extends HTMLPurifier_AttrDefHarness
|
||||
$this->assertDef('overflow:scroll;');
|
||||
}
|
||||
|
||||
function testForbidden() {
|
||||
$this->config->set('CSS.ForbiddenProperties', 'float');
|
||||
$this->assertDef('float:left;', false);
|
||||
$this->assertDef('text-align:right;');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -122,17 +122,20 @@ a[href|title]
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_global_preferredSyntax() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', 'style');
|
||||
$this->assertPurification_AllowedAttributes_global_style();
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_global_verboseSyntax() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', '*@style');
|
||||
$this->assertPurification_AllowedAttributes_global_style();
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_global_discouragedSyntax() {
|
||||
// Emit errors eventually
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', '*.style');
|
||||
$this->assertPurification_AllowedAttributes_global_style();
|
||||
}
|
||||
@@ -144,16 +147,19 @@ a[href|title]
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_local_preferredSyntax() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', 'p@style');
|
||||
$this->assertPurification_AllowedAttributes_local_p_style();
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_local_discouragedSyntax() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', 'p.style');
|
||||
$this->assertPurification_AllowedAttributes_local_p_style();
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_multiple() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', 'p@style,br@class,title');
|
||||
$this->assertPurification(
|
||||
'<p style="font-weight:bold;" class="foo" title="foo">Jelly</p><br style="clear:both;" class="foo" title="foo" />',
|
||||
@@ -162,29 +168,34 @@ a[href|title]
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_local_invalidAttribute() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', array('p@style', 'p@<foo>'));
|
||||
$this->expectError(new PatternExpectation("/Attribute '<foo>' in element 'p' not supported/"));
|
||||
$this->assertPurification_AllowedAttributes_local_p_style();
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_global_invalidAttribute() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', array('style', '<foo>'));
|
||||
$this->expectError(new PatternExpectation("/Global attribute '<foo>' is not supported in any elements/"));
|
||||
$this->assertPurification_AllowedAttributes_global_style();
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_local_invalidAttributeDueToMissingElement() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', 'p.style,foo.style');
|
||||
$this->expectError(new PatternExpectation("/Cannot allow attribute 'style' if element 'foo' is not allowed\/supported/"));
|
||||
$this->assertPurification_AllowedAttributes_local_p_style();
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_duplicate() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', 'p.style,p@style');
|
||||
$this->assertPurification_AllowedAttributes_local_p_style();
|
||||
}
|
||||
|
||||
function test_AllowedAttributes_multipleErrors() {
|
||||
$this->config->set('HTML.AllowedElements', array('p', 'br'));
|
||||
$this->config->set('HTML.AllowedAttributes', 'p.style,foo.style,<foo>');
|
||||
$this->expectError(new PatternExpectation("/Cannot allow attribute 'style' if element 'foo' is not allowed\/supported/"));
|
||||
$this->expectError(new PatternExpectation("/Global attribute '<foo>' is not supported in any elements/"));
|
||||
@@ -347,6 +358,12 @@ a[href|title]
|
||||
);
|
||||
}
|
||||
|
||||
function test_notAllowedRequiredAttributeError() {
|
||||
$this->expectError("Required attribute 'src' in element 'img' was not allowed, which means 'img' will not be allowed either");
|
||||
$this->config->set('HTML.Allowed', 'img[alt]');
|
||||
$this->config->getHTMLDefinition();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
@@ -6,8 +6,7 @@ class HTMLPurifier_HTMLModule_SafeObjectTest extends HTMLPurifier_HTMLModuleHarn
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->config->set('HTML.DefinitionID', 'HTMLPurifier_HTMLModule_SafeObjectTest');
|
||||
$def = $this->config->getHTMLDefinition(true);
|
||||
$def->manager->addModule('SafeObject');
|
||||
$this->config->set('HTML.SafeObject', true);
|
||||
}
|
||||
|
||||
function testMinimal() {
|
||||
@@ -38,6 +37,13 @@ class HTMLPurifier_HTMLModule_SafeObjectTest extends HTMLPurifier_HTMLModuleHarn
|
||||
);
|
||||
}
|
||||
|
||||
function testFullScreen() {
|
||||
$this->config->set('HTML.FlashAllowFullScreen', true);
|
||||
$this->assertResult(
|
||||
'<b><object width="425" height="344" type="application/x-shockwave-flash" data="Foobar"><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><param name="flashvars" value="foobarbaz=bally" /><param name="movie" value="http://www.youtube.com/v/RVtEQxH7PWA&hl=en" /><param name="wmode" value="window" /><param name="allowFullScreen" value="true" /></object></b>'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
6
tests/HTMLPurifier/HTMLT/double-youtube.htmlt
Normal file
6
tests/HTMLPurifier/HTMLT/double-youtube.htmlt
Normal file
@@ -0,0 +1,6 @@
|
||||
--INI--
|
||||
HTML.SafeObject = true
|
||||
Output.FlashCompat = true
|
||||
--HTML--
|
||||
<object width="425" height="350" data="http://www.youtube.com/v/BdU--T8rLns" type="application/x-shockwave-flash"><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><param name="movie" value="http://www.youtube.com/v/BdU--T8rLns" /><param name="wmode" value="window" /><!--[if IE]><embed width="425" height="350" src="http://www.youtube.com/v/BdU--T8rLns" allowScriptAccess="never" allowNetworking="internal" wmode="window" /><![endif]--></object>
|
||||
--# vim: et sw=4 sts=4
|
5
tests/HTMLPurifier/HTMLT/file-uri.htmlt
Normal file
5
tests/HTMLPurifier/HTMLT/file-uri.htmlt
Normal file
@@ -0,0 +1,5 @@
|
||||
--INI--
|
||||
URI.AllowedSchemes = file
|
||||
--HTML--
|
||||
<a href="file:///foo">foo</a>
|
||||
--# vim: et sw=4 sts=4
|
@@ -710,6 +710,39 @@ div {}
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_ignoreIECondComment() {
|
||||
$this->assertTokenization(
|
||||
'<!--[if IE]>foo<a>bar<!-- baz --><![endif]-->',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_removeProcessingInstruction() {
|
||||
$this->config->set('Core.RemoveProcessingInstructions', true);
|
||||
$this->assertTokenization(
|
||||
'<?xml blah blah ?>',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_removeNewline() {
|
||||
$this->config->set('Core.NormalizeNewlines', true);
|
||||
$input = "plain\rtext\r\n";
|
||||
$expect = array(
|
||||
new HTMLPurifier_Token_Text("plain\ntext\n")
|
||||
);
|
||||
}
|
||||
|
||||
function test_tokenizeHTML_noRemoveNewline() {
|
||||
$this->config->set('Core.NormalizeNewlines', false);
|
||||
$input = "plain\rtext\r\n";
|
||||
$expect = array(
|
||||
new HTMLPurifier_Token_Text("plain\rtext\r\n")
|
||||
);
|
||||
$this->assertTokenization($input, $expect);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
function test_tokenizeHTML_() {
|
||||
|
24
tests/HTMLPurifier/URIFilter/DisableResourcesTest.php
Normal file
24
tests/HTMLPurifier/URIFilter/DisableResourcesTest.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
class HTMLPurifier_URIFilter_DisableResourcesTest extends HTMLPurifier_URIFilterHarness
|
||||
{
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->filter = new HTMLPurifier_URIFilter_DisableResources();
|
||||
$var = true;
|
||||
$this->context->register('EmbeddedURI', $var);
|
||||
}
|
||||
|
||||
function testRemoveResource() {
|
||||
$this->assertFiltering('/foo/bar', false);
|
||||
}
|
||||
|
||||
function testPreserveRegular() {
|
||||
$this->context->destroy('EmbeddedURI'); // undo setUp
|
||||
$this->assertFiltering('/foo/bar');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@@ -165,6 +165,13 @@ class HTMLPurifier_URISchemeTest extends HTMLPurifier_URIHarness
|
||||
);
|
||||
}
|
||||
|
||||
function test_file_basic() {
|
||||
$this->assertValidation(
|
||||
'file://user@MYCOMPUTER:12/foo/bar?baz#frag',
|
||||
'file://MYCOMPUTER/foo/bar#frag'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
|
Reference in New Issue
Block a user