Update HTML Purifier to version 4.4.0.
parent
f9c0fc6eb7
commit
dd205fbad6
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates based on {ident} CSS grammar production
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Ident extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
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
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Dummy AttrDef that mimics another AttrDef, BUT it generates clones
|
||||
* with make.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_Clone extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* What we're cloning
|
||||
*/
|
||||
protected $clone;
|
||||
|
||||
public function __construct($clone) {
|
||||
$this->clone = $clone;
|
||||
}
|
||||
|
||||
public function validate($v, $config, $context) {
|
||||
return $this->clone->validate($v, $config, $context);
|
||||
}
|
||||
|
||||
public function make($string) {
|
||||
return clone $this->clone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
// must be called POST validation
|
||||
|
||||
/**
|
||||
* Adds target="blank" to all outbound links. This transform is
|
||||
* only attached if Attr.TargetBlank is TRUE. This works regardless
|
||||
* of whether or not Attr.AllowedFrameTargets
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_TargetBlank extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
private $parser;
|
||||
|
||||
public function __construct() {
|
||||
$this->parser = new HTMLPurifier_URIParser();
|
||||
}
|
||||
|
||||
public function transform($attr, $config, $context) {
|
||||
|
||||
if (!isset($attr['href'])) {
|
||||
return $attr;
|
||||
}
|
||||
|
||||
// XXX Kind of inefficient
|
||||
$url = $this->parser->parse($attr['href']);
|
||||
$scheme = $url->getSchemeObj($config, $context);
|
||||
|
||||
if ($scheme->browsable && !$url->isBenign($config, $context)) {
|
||||
$attr['target'] = 'blank';
|
||||
}
|
||||
|
||||
return $attr;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Definition for list containers ul and ol.
|
||||
*/
|
||||
class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef
|
||||
{
|
||||
public $type = 'list';
|
||||
// lying a little bit, so that we can handle ul and ol ourselves
|
||||
// XXX: This whole business with 'wrap' is all a bit unsatisfactory
|
||||
public $elements = array('li' => true, 'ul' => true, 'ol' => true);
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
// Flag for subclasses
|
||||
$this->whitespace = false;
|
||||
|
||||
// if there are no tokens, delete parent node
|
||||
if (empty($tokens_of_children)) return false;
|
||||
|
||||
// the new set of children
|
||||
$result = array();
|
||||
|
||||
// current depth into the nest
|
||||
$nesting = 0;
|
||||
|
||||
// a little sanity check to make sure it's not ALL whitespace
|
||||
$all_whitespace = true;
|
||||
|
||||
$seen_li = false;
|
||||
$need_close_li = false;
|
||||
|
||||
foreach ($tokens_of_children as $token) {
|
||||
if (!empty($token->is_whitespace)) {
|
||||
$result[] = $token;
|
||||
continue;
|
||||
}
|
||||
$all_whitespace = false; // phew, we're not talking about whitespace
|
||||
|
||||
if ($nesting == 1 && $need_close_li) {
|
||||
$result[] = new HTMLPurifier_Token_End('li');
|
||||
$nesting--;
|
||||
$need_close_li = false;
|
||||
}
|
||||
|
||||
$is_child = ($nesting == 0);
|
||||
|
||||
if ($token instanceof HTMLPurifier_Token_Start) {
|
||||
$nesting++;
|
||||
} elseif ($token instanceof HTMLPurifier_Token_End) {
|
||||
$nesting--;
|
||||
}
|
||||
|
||||
if ($is_child) {
|
||||
if ($token->name === 'li') {
|
||||
// good
|
||||
$seen_li = true;
|
||||
} elseif ($token->name === 'ul' || $token->name === 'ol') {
|
||||
// we want to tuck this into the previous li
|
||||
$need_close_li = true;
|
||||
$nesting++;
|
||||
if (!$seen_li) {
|
||||
// create a new li element
|
||||
$result[] = new HTMLPurifier_Token_Start('li');
|
||||
} else {
|
||||
// backtrack until </li> found
|
||||
while(true) {
|
||||
$t = array_pop($result);
|
||||
if ($t instanceof HTMLPurifier_Token_End) {
|
||||
// XXX actually, these invariants could very plausibly be violated
|
||||
// if we are doing silly things with modifying the set of allowed elements.
|
||||
// FORTUNATELY, it doesn't make a difference, since the allowed
|
||||
// elements are hard-coded here!
|
||||
if ($t->name !== 'li') {
|
||||
trigger_error("Only li present invariant violated in List ChildDef", E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
} elseif ($t instanceof HTMLPurifier_Token_Empty) { // bleagh
|
||||
if ($t->name !== 'li') {
|
||||
trigger_error("Only li present invariant violated in List ChildDef", E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
// XXX this should have a helper for it...
|
||||
$result[] = new HTMLPurifier_Token_Start('li', $t->attr, $t->line, $t->col, $t->armor);
|
||||
break;
|
||||
} else {
|
||||
if (!$t->is_whitespace) {
|
||||
trigger_error("Only whitespace present invariant violated in List ChildDef", E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// start wrapping (this doesn't precisely mimic
|
||||
// browser behavior, but what browsers do is kind of
|
||||
// hard to mimic in a standards compliant way
|
||||
// XXX Actually, this has no impact in practice,
|
||||
// because this gets handled earlier. Arguably,
|
||||
// we should rip out all of that processing
|
||||
$result[] = new HTMLPurifier_Token_Start('li');
|
||||
$nesting++;
|
||||
$seen_li = true;
|
||||
$need_close_li = true;
|
||||
}
|
||||
}
|
||||
$result[] = $token;
|
||||
}
|
||||
if ($need_close_li) {
|
||||
$result[] = new HTMLPurifier_Token_End('li');
|
||||
}
|
||||
if (empty($result)) return false;
|
||||
if ($all_whitespace) {
|
||||
return false;
|
||||
}
|
||||
if ($tokens_of_children == $result) return true;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interchange component class describing namespaces.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* Name of namespace defined.
|
||||
*/
|
||||
public $namespace;
|
||||
|
||||
/**
|
||||
* HTML description.
|
||||
*/
|
||||
public $description;
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
Attr
|
||||
DESCRIPTION: Features regarding attribute validation.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
AutoFormat
|
||||
DESCRIPTION: Configuration for activating auto-formatting functionality (also known as <code>Injector</code>s)
|
||||
--# vim: et sw=4 sts=4
|
@ -1,12 +0,0 @@
|
||||
AutoFormatParam.PurifierLinkifyDocURL
|
||||
TYPE: string
|
||||
VERSION: 2.0.1
|
||||
DEFAULT: '#%s'
|
||||
--DESCRIPTION--
|
||||
|
||||
<p>
|
||||
Location of configuration documentation to link to, let %s substitute
|
||||
into the configuration's namespace and directive names sans the percent
|
||||
sign.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
AutoFormatParam
|
||||
DESCRIPTION: Configuration for customizing auto-formatting functionality
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
CSS
|
||||
DESCRIPTION: Configuration regarding allowed CSS.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Cache
|
||||
DESCRIPTION: Configuration for DefinitionCache and related subclasses.
|
||||
--# vim: et sw=4 sts=4
|
@ -0,0 +1,9 @@
|
||||
Core.EnableIDNA
|
||||
TYPE: bool
|
||||
DEFAULT: false
|
||||
VERSION: 4.4.0
|
||||
--DESCRIPTION--
|
||||
Allows international domain names in URLs. This configuration option
|
||||
requires the PEAR Net_IDNA2 module to be installed. It operates by
|
||||
punycoding any internationalized host names for maximum portability.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Core
|
||||
DESCRIPTION: Core features that are always available.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Filter
|
||||
DESCRIPTION: Directives for turning filters on and off, or specifying custom filters.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,14 +0,0 @@
|
||||
FilterParam.ExtractStyleBlocksEscaping
|
||||
TYPE: bool
|
||||
VERSION: 3.0.0
|
||||
DEFAULT: true
|
||||
ALIASES: Filter.ExtractStyleBlocksEscaping
|
||||
--DESCRIPTION--
|
||||
|
||||
<p>
|
||||
Whether or not to escape the dangerous characters <, > and &
|
||||
as \3C, \3E and \26, respectively. This is can be safely set to false
|
||||
if the contents of StyleBlocks will be placed in an external stylesheet,
|
||||
where there is no risk of it being interpreted as HTML.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@ -1,29 +0,0 @@
|
||||
FilterParam.ExtractStyleBlocksScope
|
||||
TYPE: string/null
|
||||
VERSION: 3.0.0
|
||||
DEFAULT: NULL
|
||||
ALIASES: Filter.ExtractStyleBlocksScope
|
||||
--DESCRIPTION--
|
||||
|
||||
<p>
|
||||
If you would like users to be able to define external stylesheets, but
|
||||
only allow them to specify CSS declarations for a specific node and
|
||||
prevent them from fiddling with other elements, use this directive.
|
||||
It accepts any valid CSS selector, and will prepend this to any
|
||||
CSS declaration extracted from the document. For example, if this
|
||||
directive is set to <code>#user-content</code> and a user uses the
|
||||
selector <code>a:hover</code>, the final selector will be
|
||||
<code>#user-content a:hover</code>.
|
||||
</p>
|
||||
<p>
|
||||
The comma shorthand may be used; consider the above example, with
|
||||
<code>#user-content, #user-content2</code>, the final selector will
|
||||
be <code>#user-content a:hover, #user-content2 a:hover</code>.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Warning:</strong> It is possible for users to bypass this measure
|
||||
using a naughty + selector. This is a bug in CSS Tidy 1.3, not HTML
|
||||
Purifier, and I am working to get it fixed. Until then, HTML Purifier
|
||||
performs a basic check to prevent this.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@ -1,15 +0,0 @@
|
||||
FilterParam.ExtractStyleBlocksTidyImpl
|
||||
TYPE: mixed/null
|
||||
VERSION: 3.1.0
|
||||
DEFAULT: NULL
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
If left NULL, HTML Purifier will attempt to instantiate a <code>csstidy</code>
|
||||
class to use for internal cleaning. This will usually be good enough.
|
||||
</p>
|
||||
<p>
|
||||
However, for trusted user input, you can set this to <code>false</code> to
|
||||
disable cleaning. In addition, you can supply your own concrete implementation
|
||||
of Tidy's interface to use, although I don't know why you'd want to do that.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
FilterParam
|
||||
DESCRIPTION: Configuration for filters.
|
||||
--# vim: et sw=4 sts=4
|
@ -0,0 +1,10 @@
|
||||
HTML.AllowedComments
|
||||
TYPE: lookup
|
||||
VERSION: 4.4.0
|
||||
DEFAULT: array()
|
||||
--DESCRIPTION--
|
||||
A whitelist which indicates what explicit comment bodies should be
|
||||
allowed, modulo leading and trailing whitespace. See also %HTML.AllowedCommentsRegexp
|
||||
(these directives are union'ed together, so a comment is considered
|
||||
valid if any directive deems it valid.)
|
||||
--# vim: et sw=4 sts=4
|
@ -0,0 +1,15 @@
|
||||
HTML.AllowedCommentsRegexp
|
||||
TYPE: string/null
|
||||
VERSION: 4.4.0
|
||||
DEFAULT: NULL
|
||||
--DESCRIPTION--
|
||||
A regexp, which if it matches the body of a comment, indicates that
|
||||
it should be allowed. Trailing and leading spaces are removed prior
|
||||
to running this regular expression.
|
||||
<strong>Warning:</strong> Make sure you specify
|
||||
correct anchor metacharacters <code>^regex$</code>, otherwise you may accept
|
||||
comments that you did not mean to! In particular, the regex <code>/foo|bar/</code>
|
||||
is probably not sufficiently strict, since it also allows <code>foobar</code>.
|
||||
See also %HTML.AllowedComments (these directives are union'ed together,
|
||||
so a comment is considered valid if any directive deems it valid.)
|
||||
--# vim: et sw=4 sts=4
|
@ -0,0 +1,13 @@
|
||||
HTML.SafeIframe
|
||||
TYPE: bool
|
||||
VERSION: 4.4.0
|
||||
DEFAULT: false
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
Whether or not to permit iframe tags in untrusted documents. This
|
||||
directive must be accompanied by a whitelist of permitted iframes,
|
||||
such as %URI.SafeIframeRegexp, otherwise it will fatally error.
|
||||
This directive has no effect on strict doctypes, as iframes are not
|
||||
valid.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@ -0,0 +1,8 @@
|
||||
HTML.TargetBlank
|
||||
TYPE: bool
|
||||
VERSION: 4.4.0
|
||||
DEFAULT: FALSE
|
||||
--DESCRIPTION--
|
||||
If enabled, <code>target=blank</code> attributes are added to all outgoing links.
|
||||
(This includes links from an HTTPS version of a page to an HTTP version.)
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
HTML
|
||||
DESCRIPTION: Configuration regarding allowed HTML.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Output
|
||||
DESCRIPTION: Configuration relating to the generation of (X)HTML.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Test
|
||||
DESCRIPTION: Developer testing configuration for our unit tests.
|
||||
--# vim: et sw=4 sts=4
|
@ -0,0 +1,22 @@
|
||||
URI.SafeIframeRegexp
|
||||
TYPE: string/null
|
||||
VERSION: 4.4.0
|
||||
DEFAULT: NULL
|
||||
--DESCRIPTION--
|
||||
<p>
|
||||
A PCRE regular expression that will be matched against an iframe URI. This is
|
||||
a relatively inflexible scheme, but works well enough for the most common
|
||||
use-case of iframes: embedded video. This directive only has an effect if
|
||||
%HTML.SafeIframe is enabled. Here are some example values:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>%^http://www.youtube.com/embed/%</code> - Allow YouTube videos</li>
|
||||
<li><code>%^http://player.vimeo.com/video/%</code> - Allow Vimeo videos</li>
|
||||
<li><code>%^http://(www.youtube.com/embed/|player.vimeo.com/video/)%</code> - Allow both</li>
|
||||
</ul>
|
||||
<p>
|
||||
Note that this directive does not give you enough granularity to, say, disable
|
||||
all <code>autoplay</code> videos. Pipe up on the HTML Purifier forums if this
|
||||
is a capability you want.
|
||||
</p>
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
URI
|
||||
DESCRIPTION: Features regarding Uniform Resource Identifiers.
|
||||
--# vim: et sw=4 sts=4
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* XHTML 1.1 Iframe Module provides inline frames.
|
||||
*
|
||||
* @note This module is not considered safe unless an Iframe
|
||||
* whitelisting mechanism is specified. Currently, the only
|
||||
* such mechanism is %URL.SafeIframeRegexp
|
||||
*/
|
||||
class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
|
||||
{
|
||||
|
||||
public $name = 'Iframe';
|
||||
public $safe = false;
|
||||
|
||||
public function setup($config) {
|
||||
if ($config->get('HTML.SafeIframe')) {
|
||||
$this->safe = true;
|
||||
}
|
||||
$this->addElement(
|
||||
'iframe', 'Inline', 'Flow', 'Common',
|
||||
array(
|
||||
'src' => 'URI#embedded',
|
||||
'width' => 'Length',
|
||||
'height' => 'Length',
|
||||
'name' => 'ID',
|
||||
'scrolling' => 'Enum#yes,no,auto',
|
||||
'frameborder' => 'Enum#0,1',
|
||||
'longdesc' => 'URI',
|
||||
'marginheight' => 'Pixels',
|
||||
'marginwidth' => 'Pixels',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Module adds the target=blank attribute transformation to a tags. It
|
||||
* is enabled by HTML.TargetBlank
|
||||
*/
|
||||
class HTMLPurifier_HTMLModule_TargetBlank extends HTMLPurifier_HTMLModule
|
||||
{
|
||||
|
||||
public $name = 'TargetBlank';
|
||||
|
||||
public function setup($config) {
|
||||
$a = $this->addBlankElement('a');
|
||||
$a->attr_transform_post[] = new HTMLPurifier_AttrTransform_TargetBlank();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@ -1,139 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proof-of-concept lexer that uses the PEAR package XML_HTMLSax3 to parse HTML.
|
||||
*
|
||||
* PEAR, not suprisingly, also has a SAX parser for HTML. I don't know
|
||||
* very much about implementation, but it's fairly well written. However, that
|
||||
* abstraction comes at a price: performance. You need to have it installed,
|
||||
* and if the API changes, it might break our adapter. Not sure whether or not
|
||||
* it's UTF-8 aware, but it has some entity parsing trouble (in all areas,
|
||||
* text and attributes).
|
||||
*
|
||||
* Quite personally, I don't recommend using the PEAR class, and the defaults
|
||||
* don't use it. The unit tests do perform the tests on the SAX parser too, but
|
||||
* whatever it does for poorly formed HTML is up to it.
|
||||
*
|
||||
* @todo Generalize so that XML_HTMLSax is also supported.
|
||||
*
|
||||
* @warning Entity-resolution inside attributes is broken.
|
||||
*/
|
||||
|
||||
class HTMLPurifier_Lexer_PEARSax3 extends HTMLPurifier_Lexer
|
||||
{
|
||||
|
||||
/**
|
||||
* Internal accumulator array for SAX parsers.
|
||||
*/
|
||||
protected $tokens = array();
|
||||
protected $last_token_was_empty;
|
||||
|
||||
private $parent_handler;
|
||||
private $stack = array();
|
||||
|
||||
public function tokenizeHTML($string, $config, $context) {
|
||||
|
||||
$this->tokens = array();
|
||||
$this->last_token_was_empty = false;
|
||||
|
||||
$string = $this->normalize($string, $config, $context);
|
||||
|
||||
$this->parent_handler = set_error_handler(array($this, 'muteStrictErrorHandler'));
|
||||
|
||||
$parser = new XML_HTMLSax3();
|
||||
$parser->set_object($this);
|
||||
$parser->set_element_handler('openHandler','closeHandler');
|
||||
$parser->set_data_handler('dataHandler');
|
||||
$parser->set_escape_handler('escapeHandler');
|
||||
|
||||
// doesn't seem to work correctly for attributes
|
||||
$parser->set_option('XML_OPTION_ENTITIES_PARSED', 1);
|
||||
|
||||
$parser->parse($string);
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
return $this->tokens;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Open tag event handler, interface is defined by PEAR package.
|
||||
*/
|
||||
public function openHandler(&$parser, $name, $attrs, $closed) {
|
||||
// entities are not resolved in attrs
|
||||
foreach ($attrs as $key => $attr) {
|
||||
$attrs[$key] = $this->parseData($attr);
|
||||
}
|
||||
if ($closed) {
|
||||
$this->tokens[] = new HTMLPurifier_Token_Empty($name, $attrs);
|
||||
$this->last_token_was_empty = true;
|
||||
} else {
|
||||
$this->tokens[] = new HTMLPurifier_Token_Start($name, $attrs);
|
||||
}
|
||||
$this->stack[] = $name;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close tag event handler, interface is defined by PEAR package.
|
||||
*/
|
||||
public function closeHandler(&$parser, $name) {
|
||||
// HTMLSax3 seems to always send empty tags an extra close tag
|
||||
// check and ignore if you see it:
|
||||
// [TESTME] to make sure it doesn't overreach
|
||||
if ($this->last_token_was_empty) {
|
||||
$this->last_token_was_empty = false;
|
||||
return true;
|
||||
}
|
||||
$this->tokens[] = new HTMLPurifier_Token_End($name);
|
||||
if (!empty($this->stack)) array_pop($this->stack);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data event handler, interface is defined by PEAR package.
|
||||
*/
|
||||
public function dataHandler(&$parser, $data) {
|
||||
$this->last_token_was_empty = false;
|
||||
$this->tokens[] = new HTMLPurifier_Token_Text($data);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escaped text handler, interface is defined by PEAR package.
|
||||
*/
|
||||
public function escapeHandler(&$parser, $data) {
|
||||
if (strpos($data, '--') === 0) {
|
||||
// remove trailing and leading double-dashes
|
||||
$data = substr($data, 2);
|
||||
if (strlen($data) >= 2 && substr($data, -2) == "--") {
|
||||
$data = substr($data, 0, -2);
|
||||
}
|
||||
if (isset($this->stack[sizeof($this->stack) - 1]) &&
|
||||
$this->stack[sizeof($this->stack) - 1] == "style") {
|
||||
$this->tokens[] = new HTMLPurifier_Token_Text($data);
|
||||
} else {
|
||||
$this->tokens[] = new HTMLPurifier_Token_Comment($data);
|
||||
}
|
||||
$this->last_token_was_empty = false;
|
||||
}
|
||||
// CDATA is handled elsewhere, but if it was handled here:
|
||||
//if (strpos($data, '[CDATA[') === 0) {
|
||||
// $this->tokens[] = new HTMLPurifier_Token_Text(
|
||||
// substr($data, 7, strlen($data) - 9) );
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* An error handler that mutes strict errors
|
||||
*/
|
||||
public function muteStrictErrorHandler($errno, $errstr, $errfile=null, $errline=null, $errcontext=null) {
|
||||
if ($errno == E_STRICT) return;
|
||||
return call_user_func($this->parent_handler, $errno, $errstr, $errfile, $errline, $errcontext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements safety checks for safe iframes.
|
||||
*
|
||||
* @warning This filter is *critical* for ensuring that %HTML.SafeIframe
|
||||
* works safely.
|
||||
*/
|
||||
class HTMLPurifier_URIFilter_SafeIframe extends HTMLPurifier_URIFilter
|
||||
{
|
||||
public $name = 'SafeIframe';
|
||||
public $always_load = true;
|
||||
protected $regexp = NULL;
|
||||
// XXX: The not so good bit about how this is all setup now is we
|
||||
// can't check HTML.SafeIframe in the 'prepare' step: we have to
|
||||
// defer till the actual filtering.
|
||||
public function prepare($config) {
|
||||
$this->regexp = $config->get('URI.SafeIframeRegexp');
|
||||
return true;
|
||||
}
|
||||
public function filter(&$uri, $config, $context) {
|
||||
// check if filter not applicable
|
||||
if (!$config->get('HTML.SafeIframe')) return true;
|
||||
// check if the filter should actually trigger
|
||||
if (!$context->get('EmbeddedURI', true)) return true;
|
||||
$token = $context->get('CurrentToken', true);
|
||||
if (!($token && $token->name == 'iframe')) return true;
|
||||
// check if we actually have some whitelists enabled
|
||||
if ($this->regexp === null) return false;
|
||||
// actually check the whitelists
|
||||
return preg_match($this->regexp, $uri->toString());
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
Loading…
Reference in New Issue