MDL-14898 upgraded html purifier to 3.1.0 in HEAD
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is a stub include that automatically configures the include path.
|
||||
*/
|
||||
|
||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
||||
require_once 'HTMLPurifier.php';
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Function wrapper for HTML Purifier for quick use.
|
||||
* @note This function only includes the library when it is called. While
|
||||
* this is efficient for instances when you only use HTML Purifier
|
||||
* on a few of your pages, it murders bytecode caching. You still
|
||||
* need to add HTML Purifier to your path.
|
||||
* @note ''HTMLPurifier()'' is NOT the same as ''new HTMLPurifier()''
|
||||
*/
|
||||
|
||||
function HTMLPurifier($html, $config = null) {
|
||||
static $purifier = false;
|
||||
if (!$purifier) {
|
||||
require_once 'HTMLPurifier.php';
|
||||
$purifier = new HTMLPurifier();
|
||||
}
|
||||
return $purifier->purify($html, $config);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
/*!
|
||||
* @mainpage
|
||||
/*! @mainpage
|
||||
*
|
||||
* HTML Purifier is an HTML filter that will take an arbitrary snippet of
|
||||
* HTML and rigorously test, validate and filter it into a version that
|
||||
@@ -16,14 +15,12 @@
|
||||
* -# Generating HTML from the purified tokens.
|
||||
*
|
||||
* However, most users will only need to interface with the HTMLPurifier
|
||||
* class, so this massive amount of infrastructure is usually concealed.
|
||||
* If you plan on working with the internals, be sure to include
|
||||
* HTMLPurifier_ConfigSchema and HTMLPurifier_Config.
|
||||
* and HTMLPurifier_Config.
|
||||
*/
|
||||
|
||||
/*
|
||||
HTML Purifier 2.1.4 - Standards Compliant HTML Filtering
|
||||
Copyright (C) 2006-2007 Edward Z. Yang
|
||||
HTML Purifier 3.1.0 - Standards Compliant HTML Filtering
|
||||
Copyright (C) 2006-2008 Edward Z. Yang
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@@ -40,32 +37,6 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// constants are slow, but we'll make one exception
|
||||
define('HTMLPURIFIER_PREFIX', dirname(__FILE__));
|
||||
|
||||
// every class has an undocumented dependency to these, must be included!
|
||||
require_once 'HTMLPurifier/ConfigSchema.php'; // fatal errors if not included
|
||||
require_once 'HTMLPurifier/Config.php';
|
||||
require_once 'HTMLPurifier/Context.php';
|
||||
|
||||
require_once 'HTMLPurifier/Lexer.php';
|
||||
require_once 'HTMLPurifier/Generator.php';
|
||||
require_once 'HTMLPurifier/Strategy/Core.php';
|
||||
require_once 'HTMLPurifier/Encoder.php';
|
||||
|
||||
require_once 'HTMLPurifier/ErrorCollector.php';
|
||||
require_once 'HTMLPurifier/LanguageFactory.php';
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Core', 'CollectErrors', false, 'bool', '
|
||||
Whether or not to collect errors found while filtering the document. This
|
||||
is a useful way to give feedback to your users. <strong>Warning:</strong>
|
||||
Currently this feature is very patchy and experimental, with lots of
|
||||
possible error messages not yet implemented. It will not cause any problems,
|
||||
but it may not help your users either. This directive has been available
|
||||
since 2.0.0.
|
||||
');
|
||||
|
||||
/**
|
||||
* Facade that coordinates HTML Purifier's subsystems in order to purify HTML.
|
||||
*
|
||||
@@ -75,27 +46,36 @@ since 2.0.0.
|
||||
* -# Instance: new HTMLPurifier($config)
|
||||
* -# Invocation: purify($html, $config)
|
||||
* These configurations are entirely independent of each other and
|
||||
* are *not* merged.
|
||||
* are *not* merged (this behavior may change in the future).
|
||||
*
|
||||
* @todo We need an easier way to inject strategies, it'll probably end
|
||||
* up getting done through config though.
|
||||
* @todo We need an easier way to inject strategies using the configuration
|
||||
* object.
|
||||
*/
|
||||
class HTMLPurifier
|
||||
{
|
||||
|
||||
var $version = '2.1.4';
|
||||
/** Version of HTML Purifier */
|
||||
public $version = '3.1.0';
|
||||
|
||||
var $config;
|
||||
var $filters = array();
|
||||
/** Constant with version of HTML Purifier */
|
||||
const VERSION = '3.1.0';
|
||||
|
||||
var $strategy, $generator;
|
||||
/** Global configuration object */
|
||||
public $config;
|
||||
|
||||
/** Array of extra HTMLPurifier_Filter objects to run on HTML, for backwards compatibility */
|
||||
private $filters = array();
|
||||
|
||||
/** Single instance of HTML Purifier */
|
||||
private static $instance;
|
||||
|
||||
protected $strategy, $generator;
|
||||
|
||||
/**
|
||||
* Resultant HTMLPurifier_Context of last run purification. Is an array
|
||||
* of contexts if the last called method was purifyArray().
|
||||
* @public
|
||||
*/
|
||||
var $context;
|
||||
public $context;
|
||||
|
||||
/**
|
||||
* Initializes the purifier.
|
||||
@@ -105,12 +85,11 @@ class HTMLPurifier
|
||||
* The parameter can also be any type that
|
||||
* HTMLPurifier_Config::create() supports.
|
||||
*/
|
||||
function HTMLPurifier($config = null) {
|
||||
public function __construct($config = null) {
|
||||
|
||||
$this->config = HTMLPurifier_Config::create($config);
|
||||
|
||||
$this->strategy = new HTMLPurifier_Strategy_Core();
|
||||
$this->generator = new HTMLPurifier_Generator();
|
||||
|
||||
}
|
||||
|
||||
@@ -118,7 +97,8 @@ class HTMLPurifier
|
||||
* Adds a filter to process the output. First come first serve
|
||||
* @param $filter HTMLPurifier_Filter object
|
||||
*/
|
||||
function addFilter($filter) {
|
||||
public function addFilter($filter) {
|
||||
trigger_error('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom', E_USER_WARNING);
|
||||
$this->filters[] = $filter;
|
||||
}
|
||||
|
||||
@@ -132,8 +112,9 @@ class HTMLPurifier
|
||||
* that HTMLPurifier_Config::create() supports.
|
||||
* @return Purified HTML
|
||||
*/
|
||||
function purify($html, $config = null) {
|
||||
public function purify($html, $config = null) {
|
||||
|
||||
// :TODO: make the config merge in, instead of replace
|
||||
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
|
||||
|
||||
// implementation is partially environment dependant, partially
|
||||
@@ -142,8 +123,8 @@ class HTMLPurifier
|
||||
|
||||
$context = new HTMLPurifier_Context();
|
||||
|
||||
// our friendly neighborhood generator, all primed with configuration too!
|
||||
$this->generator->generateFromTokens(array(), $config, $context);
|
||||
// setup HTML generator
|
||||
$this->generator = new HTMLPurifier_Generator($config, $context);
|
||||
$context->register('Generator', $this->generator);
|
||||
|
||||
// set up global context variables
|
||||
@@ -164,8 +145,25 @@ class HTMLPurifier
|
||||
|
||||
$html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context);
|
||||
|
||||
for ($i = 0, $size = count($this->filters); $i < $size; $i++) {
|
||||
$html = $this->filters[$i]->preFilter($html, $config, $context);
|
||||
// setup filters
|
||||
$filter_flags = $config->getBatch('Filter');
|
||||
$custom_filters = $filter_flags['Custom'];
|
||||
unset($filter_flags['Custom']);
|
||||
$filters = array();
|
||||
foreach ($filter_flags as $filter => $flag) {
|
||||
if (!$flag) continue;
|
||||
$class = "HTMLPurifier_Filter_$filter";
|
||||
$filters[] = new $class;
|
||||
}
|
||||
foreach ($custom_filters as $filter) {
|
||||
// maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat
|
||||
$filters[] = $filter;
|
||||
}
|
||||
$filters = array_merge($filters, $this->filters);
|
||||
// maybe prepare(), but later
|
||||
|
||||
for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) {
|
||||
$html = $filters[$i]->preFilter($html, $config, $context);
|
||||
}
|
||||
|
||||
// purified HTML
|
||||
@@ -179,12 +177,11 @@ class HTMLPurifier
|
||||
$html, $config, $context
|
||||
),
|
||||
$config, $context
|
||||
),
|
||||
$config, $context
|
||||
)
|
||||
);
|
||||
|
||||
for ($i = $size - 1; $i >= 0; $i--) {
|
||||
$html = $this->filters[$i]->postFilter($html, $config, $context);
|
||||
for ($i = $filter_size - 1; $i >= 0; $i--) {
|
||||
$html = $filters[$i]->postFilter($html, $config, $context);
|
||||
}
|
||||
|
||||
$html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context);
|
||||
@@ -198,7 +195,7 @@ class HTMLPurifier
|
||||
* See HTMLPurifier::purify() for more details.
|
||||
* @return Array of purified HTML
|
||||
*/
|
||||
function purifyArray($array_of_html, $config = null) {
|
||||
public function purifyArray($array_of_html, $config = null) {
|
||||
$context_array = array();
|
||||
foreach ($array_of_html as $key => $html) {
|
||||
$array_of_html[$key] = $this->purify($html, $config);
|
||||
@@ -211,25 +208,27 @@ class HTMLPurifier
|
||||
/**
|
||||
* Singleton for enforcing just one HTML Purifier in your system
|
||||
* @param $prototype Optional prototype HTMLPurifier instance to
|
||||
* overload singleton with.
|
||||
* overload singleton with, or HTMLPurifier_Config
|
||||
* instance to configure the generated version with.
|
||||
*/
|
||||
function &instance($prototype = null) {
|
||||
static $htmlpurifier;
|
||||
if (!$htmlpurifier || $prototype) {
|
||||
if (is_a($prototype, 'HTMLPurifier')) {
|
||||
$htmlpurifier = $prototype;
|
||||
public static function instance($prototype = null) {
|
||||
if (!self::$instance || $prototype) {
|
||||
if ($prototype instanceof HTMLPurifier) {
|
||||
self::$instance = $prototype;
|
||||
} elseif ($prototype) {
|
||||
$htmlpurifier = new HTMLPurifier($prototype);
|
||||
self::$instance = new HTMLPurifier($prototype);
|
||||
} else {
|
||||
$htmlpurifier = new HTMLPurifier();
|
||||
self::$instance = new HTMLPurifier();
|
||||
}
|
||||
}
|
||||
return $htmlpurifier;
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
function &getInstance($prototype = null) {
|
||||
/**
|
||||
* @note Backwards compatibility, see instance()
|
||||
*/
|
||||
public static function getInstance($prototype = null) {
|
||||
return HTMLPurifier::instance($prototype);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file was auto-generated by generate-includes.php and includes all of
|
||||
* the core files required by HTML Purifier. This is a convenience stub that
|
||||
* includes all files using dirname(__FILE__) and require_once. PLEASE DO NOT
|
||||
* EDIT THIS FILE, changes will be overwritten the next time the script is run.
|
||||
*
|
||||
* Changes to include_path are not necessary.
|
||||
*/
|
||||
|
||||
$__dir = dirname(__FILE__);
|
||||
|
||||
require_once $__dir . '/HTMLPurifier.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrCollections.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTypes.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrValidator.php';
|
||||
require_once $__dir . '/HTMLPurifier/Bootstrap.php';
|
||||
require_once $__dir . '/HTMLPurifier/Definition.php';
|
||||
require_once $__dir . '/HTMLPurifier/CSSDefinition.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/Config.php';
|
||||
require_once $__dir . '/HTMLPurifier/ConfigDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/ConfigSchema.php';
|
||||
require_once $__dir . '/HTMLPurifier/ContentSets.php';
|
||||
require_once $__dir . '/HTMLPurifier/Context.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCacheFactory.php';
|
||||
require_once $__dir . '/HTMLPurifier/Doctype.php';
|
||||
require_once $__dir . '/HTMLPurifier/DoctypeRegistry.php';
|
||||
require_once $__dir . '/HTMLPurifier/ElementDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/Encoder.php';
|
||||
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
|
||||
require_once $__dir . '/HTMLPurifier/EntityParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
|
||||
require_once $__dir . '/HTMLPurifier/Exception.php';
|
||||
require_once $__dir . '/HTMLPurifier/Filter.php';
|
||||
require_once $__dir . '/HTMLPurifier/Generator.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLDefinition.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModuleManager.php';
|
||||
require_once $__dir . '/HTMLPurifier/IDAccumulator.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector.php';
|
||||
require_once $__dir . '/HTMLPurifier/Language.php';
|
||||
require_once $__dir . '/HTMLPurifier/LanguageFactory.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer.php';
|
||||
require_once $__dir . '/HTMLPurifier/PercentEncoder.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy.php';
|
||||
require_once $__dir . '/HTMLPurifier/StringHash.php';
|
||||
require_once $__dir . '/HTMLPurifier/StringHashParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/TagTransform.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token.php';
|
||||
require_once $__dir . '/HTMLPurifier/TokenFactory.php';
|
||||
require_once $__dir . '/HTMLPurifier/URI.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIDefinition.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme.php';
|
||||
require_once $__dir . '/HTMLPurifier/URISchemeRegistry.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParserException.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Enum.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Integer.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Lang.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Number.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/AlphaValue.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Background.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Border.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Color.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Composite.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Filter.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Font.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/LinkTypes.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/MultiLength.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Host.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv6.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BdoDir.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BgColor.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BoolToCSS.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Border.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/EnumToCSS.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgRequired.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgSpace.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Required.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Optional.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/StrictBlockquote.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Table.php';
|
||||
require_once $__dir . '/HTMLPurifier/ConfigDef/Directive.php';
|
||||
require_once $__dir . '/HTMLPurifier/ConfigDef/DirectiveAlias.php';
|
||||
require_once $__dir . '/HTMLPurifier/ConfigDef/Namespace.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Null.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Serializer.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Bdo.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/CommonAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Edit.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Hypertext.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Proprietary.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Ruby.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Scripting.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/AutoParagraph.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/Composite.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/Core.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/FixNesting.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/MakeWellFormed.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/RemoveForeignElements.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/ValidateAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/TagTransform/Font.php';
|
||||
require_once $__dir . '/HTMLPurifier/TagTransform/Simple.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Comment.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Tag.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Empty.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/End.php';
|
||||
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/HostBlacklist.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/mailto.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/news.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/nntp.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser/Flexible.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser/Native.php';
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTypes.php';
|
||||
|
||||
/**
|
||||
* Defines common attribute collections that modules reference
|
||||
*/
|
||||
@@ -12,7 +10,7 @@ class HTMLPurifier_AttrCollections
|
||||
/**
|
||||
* Associative array of attribute collections, indexed by name
|
||||
*/
|
||||
var $info = array();
|
||||
public $info = array();
|
||||
|
||||
/**
|
||||
* Performs all expansions on internal data for use by other inclusions
|
||||
@@ -21,7 +19,7 @@ class HTMLPurifier_AttrCollections
|
||||
* @param $attr_types HTMLPurifier_AttrTypes instance
|
||||
* @param $modules Hash array of HTMLPurifier_HTMLModule members
|
||||
*/
|
||||
function HTMLPurifier_AttrCollections($attr_types, $modules) {
|
||||
public function __construct($attr_types, $modules) {
|
||||
// load extensions from the modules
|
||||
foreach ($modules as $module) {
|
||||
foreach ($module->attr_collections as $coll_i => $coll) {
|
||||
@@ -53,7 +51,7 @@ class HTMLPurifier_AttrCollections
|
||||
* all inclusions specified by the zero index.
|
||||
* @param &$attr Reference to attribute array
|
||||
*/
|
||||
function performInclusions(&$attr) {
|
||||
public function performInclusions(&$attr) {
|
||||
if (!isset($attr[0])) return;
|
||||
$merge = $attr[0];
|
||||
$seen = array(); // recursion guard
|
||||
@@ -81,7 +79,7 @@ class HTMLPurifier_AttrCollections
|
||||
* @param &$attr Reference to attribute array
|
||||
* @param $attr_types HTMLPurifier_AttrTypes instance
|
||||
*/
|
||||
function expandIdentifiers(&$attr, $attr_types) {
|
||||
public function expandIdentifiers(&$attr, $attr_types) {
|
||||
|
||||
// because foreach will process new elements we add, make sure we
|
||||
// skip duplicates
|
||||
|
||||
@@ -10,32 +10,29 @@
|
||||
* subclasses are also responsible for cleaning the code if possible.
|
||||
*/
|
||||
|
||||
class HTMLPurifier_AttrDef
|
||||
abstract class HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Tells us whether or not an HTML attribute is minimized. Has no
|
||||
* meaning in other contexts.
|
||||
*/
|
||||
var $minimized = false;
|
||||
public $minimized = false;
|
||||
|
||||
/**
|
||||
* Tells us whether or not an HTML attribute is required. Has no
|
||||
* meaning in other contexts
|
||||
*/
|
||||
var $required = false;
|
||||
public $required = false;
|
||||
|
||||
/**
|
||||
* Validates and cleans passed string according to a definition.
|
||||
*
|
||||
* @public
|
||||
* @param $string String to be validated and cleaned.
|
||||
* @param $config Mandatory HTMLPurifier_Config object.
|
||||
* @param $context Mandatory HTMLPurifier_AttrContext object.
|
||||
*/
|
||||
function validate($string, $config, &$context) {
|
||||
trigger_error('Cannot call abstract function', E_USER_ERROR);
|
||||
}
|
||||
abstract public function validate($string, $config, $context);
|
||||
|
||||
/**
|
||||
* Convenience method that parses a string as if it were CDATA.
|
||||
@@ -59,10 +56,8 @@ class HTMLPurifier_AttrDef
|
||||
* function. Trim and whitespace collapsing are supposed to only
|
||||
* occur in NMTOKENs. However, note that we are NOT necessarily
|
||||
* parsing XML, thus, this behavior may still be correct.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function parseCDATA($string) {
|
||||
public function parseCDATA($string) {
|
||||
$string = trim($string);
|
||||
$string = str_replace("\n", '', $string);
|
||||
$string = str_replace(array("\r", "\t"), ' ', $string);
|
||||
@@ -73,12 +68,12 @@ class HTMLPurifier_AttrDef
|
||||
* Factory method for creating this class from a string.
|
||||
* @param $string String construction info
|
||||
* @return Created AttrDef object corresponding to $string
|
||||
* @public
|
||||
*/
|
||||
function make($string) {
|
||||
// default implementation, return flyweight of this object
|
||||
// if overloaded, it is *necessary* for you to clone the
|
||||
// object (usually by instantiating a new copy) and return that
|
||||
public function make($string) {
|
||||
// default implementation, return a flyweight of this object.
|
||||
// If $string has an effect on the returned object (i.e. you
|
||||
// need to overload this method), it is best
|
||||
// to clone or instantiate new copies. (Instantiation is safer.)
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -86,7 +81,7 @@ class HTMLPurifier_AttrDef
|
||||
* Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work
|
||||
* properly. THIS IS A HACK!
|
||||
*/
|
||||
function mungeRgb($string) {
|
||||
protected function mungeRgb($string) {
|
||||
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/CSSDefinition.php';
|
||||
|
||||
/**
|
||||
* Validates the HTML attribute style, otherwise known as CSS.
|
||||
* @note We don't implement the whole CSS specification, so it might be
|
||||
@@ -17,7 +14,7 @@ require_once 'HTMLPurifier/CSSDefinition.php';
|
||||
class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($css, $config, &$context) {
|
||||
public function validate($css, $config, $context) {
|
||||
|
||||
$css = $this->parseCDATA($css);
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number
|
||||
{
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(false); // opacity is non-negative, but we will clamp it
|
||||
}
|
||||
|
||||
public function validate($number, $config, $context) {
|
||||
$result = parent::validate($number, $config, $context);
|
||||
if ($result === false) return $result;
|
||||
$float = (float) $result;
|
||||
if ($float < 0.0) $result = '0';
|
||||
if ($float > 1.0) $result = '1';
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/CSSDefinition.php';
|
||||
|
||||
/**
|
||||
* Validates shorthand CSS property background.
|
||||
* @warning Does not support url tokens that have internal spaces.
|
||||
@@ -14,9 +11,9 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
* Local copy of component validators.
|
||||
* @note See HTMLPurifier_AttrDef_Font::$info for a similar impl.
|
||||
*/
|
||||
var $info;
|
||||
protected $info;
|
||||
|
||||
function HTMLPurifier_AttrDef_CSS_Background($config) {
|
||||
public function __construct($config) {
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['background-color'] = $def->info['background-color'];
|
||||
$this->info['background-image'] = $def->info['background-image'];
|
||||
@@ -25,7 +22,7 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
$this->info['background-position'] = $def->info['background-position'];
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
// regular pre-processing
|
||||
$string = $this->parseCDATA($string);
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Length.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||
|
||||
/* W3C says:
|
||||
[ // adjective and number must be in correct order, even if
|
||||
// you could switch them without introducing ambiguity.
|
||||
@@ -48,15 +44,15 @@ require_once 'HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||
class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
var $length;
|
||||
var $percentage;
|
||||
protected $length;
|
||||
protected $percentage;
|
||||
|
||||
function HTMLPurifier_AttrDef_CSS_BackgroundPosition() {
|
||||
public function __construct() {
|
||||
$this->length = new HTMLPurifier_AttrDef_CSS_Length();
|
||||
$this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
$string = $this->parseCDATA($string);
|
||||
$bits = explode(' ', $string);
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates the border property as defined by CSS.
|
||||
*/
|
||||
@@ -11,16 +9,16 @@ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
|
||||
/**
|
||||
* Local copy of properties this property is shorthand for.
|
||||
*/
|
||||
var $info = array();
|
||||
protected $info = array();
|
||||
|
||||
function HTMLPurifier_AttrDef_CSS_Border($config) {
|
||||
public function __construct($config) {
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['border-width'] = $def->info['border-width'];
|
||||
$this->info['border-style'] = $def->info['border-style'];
|
||||
$this->info['border-top-color'] = $def->info['border-top-color'];
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
$string = $this->parseCDATA($string);
|
||||
$string = $this->mungeRgb($string);
|
||||
$bits = explode(' ', $string);
|
||||
|
||||
@@ -1,39 +1,12 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Core', 'ColorKeywords', array(
|
||||
'maroon' => '#800000',
|
||||
'red' => '#FF0000',
|
||||
'orange' => '#FFA500',
|
||||
'yellow' => '#FFFF00',
|
||||
'olive' => '#808000',
|
||||
'purple' => '#800080',
|
||||
'fuchsia' => '#FF00FF',
|
||||
'white' => '#FFFFFF',
|
||||
'lime' => '#00FF00',
|
||||
'green' => '#008000',
|
||||
'navy' => '#000080',
|
||||
'blue' => '#0000FF',
|
||||
'aqua' => '#00FFFF',
|
||||
'teal' => '#008080',
|
||||
'black' => '#000000',
|
||||
'silver' => '#C0C0C0',
|
||||
'gray' => '#808080'
|
||||
), 'hash', '
|
||||
Lookup array of color names to six digit hexadecimal number corresponding
|
||||
to color, with preceding hash mark. Used when parsing colors.
|
||||
This directive has been available since 2.0.0.
|
||||
');
|
||||
|
||||
/**
|
||||
* Validates Color as defined by CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($color, $config, &$context) {
|
||||
public function validate($color, $config, $context) {
|
||||
|
||||
static $colors = null;
|
||||
if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
|
||||
|
||||
@@ -14,18 +14,18 @@ class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef
|
||||
|
||||
/**
|
||||
* List of HTMLPurifier_AttrDef objects that may process strings
|
||||
* @protected
|
||||
* @todo Make protected
|
||||
*/
|
||||
var $defs;
|
||||
public $defs;
|
||||
|
||||
/**
|
||||
* @param $defs List of HTMLPurifier_AttrDef objects
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_CSS_Composite($defs) {
|
||||
public function __construct($defs) {
|
||||
$this->defs = $defs;
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
foreach ($this->defs as $i => $def) {
|
||||
$result = $this->defs[$i]->validate($string, $config, $context);
|
||||
if ($result !== false) return $result;
|
||||
|
||||
@@ -5,20 +5,20 @@
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
|
||||
{
|
||||
var $def, $element;
|
||||
protected $def, $element;
|
||||
|
||||
/**
|
||||
* @param $def Definition to wrap
|
||||
* @param $element Element to deny
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_CSS_DenyElementDecorator(&$def, $element) {
|
||||
$this->def =& $def;
|
||||
public function __construct($def, $element) {
|
||||
$this->def = $def;
|
||||
$this->element = $element;
|
||||
}
|
||||
/**
|
||||
* Checks if CurrentToken is set and equal to $this->element
|
||||
*/
|
||||
function validate($string, $config, $context) {
|
||||
public function validate($string, $config, $context) {
|
||||
$token = $context->get('CurrentToken', true);
|
||||
if ($token && $token->name == $this->element) return false;
|
||||
return $this->def->validate($string, $config, $context);
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Microsoft's proprietary filter: CSS property
|
||||
* @note Currently supports the alpha filter. In the future, this will
|
||||
* probably need an extensible framework
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
protected $intValidator;
|
||||
|
||||
public function __construct() {
|
||||
$this->intValidator = new HTMLPurifier_AttrDef_Integer();
|
||||
}
|
||||
|
||||
public function validate($value, $config, $context) {
|
||||
$value = $this->parseCDATA($value);
|
||||
if ($value === 'none') return $value;
|
||||
// if we looped this we could support multiple filters
|
||||
$function_length = strcspn($value, '(');
|
||||
$function = trim(substr($value, 0, $function_length));
|
||||
if ($function !== 'alpha' &&
|
||||
$function !== 'Alpha' &&
|
||||
$function !== 'progid:DXImageTransform.Microsoft.Alpha'
|
||||
) return false;
|
||||
$cursor = $function_length + 1;
|
||||
$parameters_length = strcspn($value, ')', $cursor);
|
||||
$parameters = substr($value, $cursor, $parameters_length);
|
||||
$params = explode(',', $parameters);
|
||||
$ret_params = array();
|
||||
$lookup = array();
|
||||
foreach ($params as $param) {
|
||||
list($key, $value) = explode('=', $param);
|
||||
$key = trim($key);
|
||||
$value = trim($value);
|
||||
if (isset($lookup[$key])) continue;
|
||||
if ($key !== 'opacity') continue;
|
||||
$value = $this->intValidator->validate($value, $config, $context);
|
||||
if ($value === false) continue;
|
||||
$int = (int) $value;
|
||||
if ($int > 100) $value = '100';
|
||||
if ($int < 0) $value = '0';
|
||||
$ret_params[] = "$key=$value";
|
||||
$lookup[$key] = true;
|
||||
}
|
||||
$ret_parameters = implode(',', $ret_params);
|
||||
$ret_function = "$function($ret_parameters)";
|
||||
return $ret_function;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates shorthand CSS property font.
|
||||
*/
|
||||
@@ -16,9 +14,9 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
* CSSDefinition, this wouldn't be necessary. We'd instantiate
|
||||
* our own copies.
|
||||
*/
|
||||
var $info = array();
|
||||
protected $info = array();
|
||||
|
||||
function HTMLPurifier_AttrDef_CSS_Font($config) {
|
||||
public function __construct($config) {
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['font-style'] = $def->info['font-style'];
|
||||
$this->info['font-variant'] = $def->info['font-variant'];
|
||||
@@ -28,7 +26,7 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
$this->info['font-family'] = $def->info['font-family'];
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
static $system_fonts = array(
|
||||
'caption' => true,
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
// whitelisting allowed fonts would be nice
|
||||
|
||||
/**
|
||||
* Validates a font family list according to CSS spec
|
||||
* @todo whitelisting allowed fonts would be nice
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
static $generic_names = array(
|
||||
'serif' => true,
|
||||
'sans-serif' => true,
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Decorator which enables !important to be used in CSS values.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef
|
||||
{
|
||||
protected $def, $allow;
|
||||
|
||||
/**
|
||||
* @param $def Definition to wrap
|
||||
* @param $allow Whether or not to allow !important
|
||||
*/
|
||||
public function __construct($def, $allow = false) {
|
||||
$this->def = $def;
|
||||
$this->allow = $allow;
|
||||
}
|
||||
/**
|
||||
* Intercepts and removes !important if necessary
|
||||
*/
|
||||
public function validate($string, $config, $context) {
|
||||
// test for ! and important tokens
|
||||
$string = trim($string);
|
||||
$is_important = false;
|
||||
// :TODO: optimization: test directly for !important and ! important
|
||||
if (strlen($string) >= 9 && substr($string, -9) === 'important') {
|
||||
$temp = rtrim(substr($string, 0, -9));
|
||||
// use a temp, because we might want to restore important
|
||||
if (strlen($temp) >= 1 && substr($temp, -1) === '!') {
|
||||
$string = rtrim(substr($temp, 0, -1));
|
||||
$is_important = true;
|
||||
}
|
||||
}
|
||||
$string = $this->def->validate($string, $config, $context);
|
||||
if ($this->allow && $is_important) $string .= ' !important';
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Number.php';
|
||||
|
||||
/**
|
||||
* Represents a Length as defined by CSS.
|
||||
*/
|
||||
@@ -14,22 +11,22 @@ class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
|
||||
* @warning The code assumes all units are two characters long. Be careful
|
||||
* if we have to change this behavior!
|
||||
*/
|
||||
var $units = array('em' => true, 'ex' => true, 'px' => true, 'in' => true,
|
||||
protected $units = array('em' => true, 'ex' => true, 'px' => true, 'in' => true,
|
||||
'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true);
|
||||
/**
|
||||
* Instance of HTMLPurifier_AttrDef_Number to defer number validation to
|
||||
*/
|
||||
var $number_def;
|
||||
protected $number_def;
|
||||
|
||||
/**
|
||||
* @param $non_negative Bool indication whether or not negative values are
|
||||
* allowed.
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_CSS_Length($non_negative = false) {
|
||||
public function __construct($non_negative = false) {
|
||||
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
|
||||
}
|
||||
|
||||
function validate($length, $config, &$context) {
|
||||
public function validate($length, $config, $context) {
|
||||
|
||||
$length = $this->parseCDATA($length);
|
||||
if ($length === '') return false;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates shorthand CSS property list-style.
|
||||
* @warning Does not support url tokens that have internal spaces.
|
||||
@@ -13,16 +11,16 @@ class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
|
||||
* Local copy of component validators.
|
||||
* @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl.
|
||||
*/
|
||||
var $info;
|
||||
protected $info;
|
||||
|
||||
function HTMLPurifier_AttrDef_CSS_ListStyle($config) {
|
||||
public function __construct($config) {
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['list-style-type'] = $def->info['list-style-type'];
|
||||
$this->info['list-style-position'] = $def->info['list-style-position'];
|
||||
$this->info['list-style-image'] = $def->info['list-style-image'];
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
// regular pre-processing
|
||||
$string = $this->parseCDATA($string);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Framework class for strings that involve multiple values.
|
||||
*
|
||||
@@ -18,24 +16,26 @@ class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef
|
||||
|
||||
/**
|
||||
* Instance of component definition to defer validation to.
|
||||
* @todo Make protected
|
||||
*/
|
||||
var $single;
|
||||
public $single;
|
||||
|
||||
/**
|
||||
* Max number of values allowed.
|
||||
* @todo Make protected
|
||||
*/
|
||||
var $max;
|
||||
public $max;
|
||||
|
||||
/**
|
||||
* @param $single HTMLPurifier_AttrDef to multiply
|
||||
* @param $max Max number of values allowed (usually four)
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_CSS_Multiple($single, $max = 4) {
|
||||
public function __construct($single, $max = 4) {
|
||||
$this->single = $single;
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
$string = $this->parseCDATA($string);
|
||||
if ($string === '') return false;
|
||||
$parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n
|
||||
|
||||
@@ -9,20 +9,21 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
|
||||
/**
|
||||
* Bool indicating whether or not only positive values allowed.
|
||||
*/
|
||||
var $non_negative = false;
|
||||
protected $non_negative = false;
|
||||
|
||||
/**
|
||||
* @param $non_negative Bool indicating whether negatives are forbidden
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_CSS_Number($non_negative = false) {
|
||||
public function __construct($non_negative = false) {
|
||||
$this->non_negative = $non_negative;
|
||||
}
|
||||
|
||||
function validate($number, $config, &$context) {
|
||||
public function validate($number, $config, $context) {
|
||||
|
||||
$number = $this->parseCDATA($number);
|
||||
|
||||
if ($number === '') return false;
|
||||
if ($number === '0') return '0';
|
||||
|
||||
$sign = '';
|
||||
switch ($number[0]) {
|
||||
@@ -37,13 +38,16 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
|
||||
$number = ltrim($number, '0');
|
||||
return $number ? $sign . $number : '0';
|
||||
}
|
||||
if (!strpos($number, '.')) return false;
|
||||
|
||||
// Period is the only non-numeric character allowed
|
||||
if (strpos($number, '.') === false) return false;
|
||||
|
||||
list($left, $right) = explode('.', $number, 2);
|
||||
|
||||
if (!ctype_digit($left)) return false;
|
||||
$left = ltrim($left, '0');
|
||||
if ($left === '' && $right === '') return false;
|
||||
if ($left !== '' && !ctype_digit($left)) return false;
|
||||
|
||||
$left = ltrim($left, '0');
|
||||
$right = rtrim($right, '0');
|
||||
|
||||
if ($right === '') {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Number.php';
|
||||
|
||||
/**
|
||||
* Validates a Percentage as defined by the CSS spec.
|
||||
*/
|
||||
@@ -12,16 +9,16 @@ class HTMLPurifier_AttrDef_CSS_Percentage extends HTMLPurifier_AttrDef
|
||||
/**
|
||||
* Instance of HTMLPurifier_AttrDef_CSS_Number to defer number validation
|
||||
*/
|
||||
var $number_def;
|
||||
protected $number_def;
|
||||
|
||||
/**
|
||||
* @param Bool indicating whether to forbid negative values
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_CSS_Percentage($non_negative = false) {
|
||||
public function __construct($non_negative = false) {
|
||||
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
$string = $this->parseCDATA($string);
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates the value for the CSS property text-decoration
|
||||
* @note This class could be generalized into a version that acts sort of
|
||||
@@ -10,7 +8,7 @@ require_once 'HTMLPurifier/AttrDef.php';
|
||||
class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
static $allowed_values = array(
|
||||
'line-through' => true,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef/URI.php';
|
||||
|
||||
/**
|
||||
* Validates a URI in CSS syntax, which uses url('http://example.com')
|
||||
* @note While theoretically speaking a URI in a CSS document could
|
||||
@@ -14,11 +12,11 @@ require_once 'HTMLPurifier/AttrDef/URI.php';
|
||||
class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI
|
||||
{
|
||||
|
||||
function HTMLPurifier_AttrDef_CSS_URI() {
|
||||
parent::HTMLPurifier_AttrDef_URI(true); // always embedded
|
||||
public function __construct() {
|
||||
parent::__construct(true); // always embedded
|
||||
}
|
||||
|
||||
function validate($uri_string, $config, &$context) {
|
||||
public function validate($uri_string, $config, $context) {
|
||||
// parse the URI out of the string and then pass it onto
|
||||
// the parent object
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
// Enum = Enumerated
|
||||
/**
|
||||
* Validates a keyword against a list of valid values.
|
||||
@@ -14,27 +12,28 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef
|
||||
|
||||
/**
|
||||
* Lookup table of valid values.
|
||||
* @todo Make protected
|
||||
*/
|
||||
var $valid_values = array();
|
||||
public $valid_values = array();
|
||||
|
||||
/**
|
||||
* Bool indicating whether or not enumeration is case sensitive.
|
||||
* @note In general this is always case insensitive.
|
||||
*/
|
||||
var $case_sensitive = false; // values according to W3C spec
|
||||
protected $case_sensitive = false; // values according to W3C spec
|
||||
|
||||
/**
|
||||
* @param $valid_values List of valid values
|
||||
* @param $case_sensitive Bool indicating whether or not case sensitive
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_Enum(
|
||||
public function __construct(
|
||||
$valid_values = array(), $case_sensitive = false
|
||||
) {
|
||||
$this->valid_values = array_flip($valid_values);
|
||||
$this->case_sensitive = $case_sensitive;
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
$string = trim($string);
|
||||
if (!$this->case_sensitive) {
|
||||
// we may want to do full case-insensitive libraries
|
||||
@@ -50,7 +49,7 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef
|
||||
* valid values. Example: "foo,bar,baz". Prepend "s:" to make
|
||||
* case sensitive
|
||||
*/
|
||||
function make($string) {
|
||||
public function make($string) {
|
||||
if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') {
|
||||
$string = substr($string, 2);
|
||||
$sensitive = true;
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates a boolean attribute
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
var $name;
|
||||
var $minimized = true;
|
||||
protected $name;
|
||||
public $minimized = true;
|
||||
|
||||
function HTMLPurifier_AttrDef_HTML_Bool($name = false) {$this->name = $name;}
|
||||
public function __construct($name = false) {$this->name = $name;}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
if (empty($string)) return false;
|
||||
return $this->name;
|
||||
}
|
||||
@@ -21,7 +19,7 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
|
||||
/**
|
||||
* @param $string Name of attribute
|
||||
*/
|
||||
function make($string) {
|
||||
public function make($string) {
|
||||
return new HTMLPurifier_AttrDef_HTML_Bool($string);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Color.php'; // for %Core.ColorKeywords
|
||||
|
||||
/**
|
||||
* Validates a color according to the HTML spec.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
static $colors = null;
|
||||
if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
|
||||
|
||||
@@ -1,30 +1,17 @@
|
||||
<?php
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'AllowedFrameTargets', array(), 'lookup',
|
||||
'Lookup table of all allowed link frame targets. Some commonly used '.
|
||||
'link targets include _blank, _self, _parent and _top. Values should '.
|
||||
'be lowercase, as validation will be done in a case-sensitive manner '.
|
||||
'despite W3C\'s recommendation. XHTML 1.0 Strict does not permit '.
|
||||
'the target attribute so this directive will have no effect in that '.
|
||||
'doctype. XHTML 1.1 does not enable the Target module by default, you '.
|
||||
'will have to manually enable it (see the module documentation for more details.)'
|
||||
);
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef/Enum.php';
|
||||
|
||||
/**
|
||||
* Special-case enum attribute definition that lazy loads allowed frame targets
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum
|
||||
{
|
||||
|
||||
var $valid_values = false; // uninitialized value
|
||||
var $case_sensitive = false;
|
||||
public $valid_values = false; // uninitialized value
|
||||
protected $case_sensitive = false;
|
||||
|
||||
function HTMLPurifier_AttrDef_HTML_FrameTarget() {}
|
||||
public function __construct() {}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
if ($this->valid_values === false) $this->valid_values = $config->get('Attr', 'AllowedFrameTargets');
|
||||
return parent::validate($string, $config, $context);
|
||||
}
|
||||
|
||||
@@ -1,56 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/IDAccumulator.php';
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'EnableID', false, 'bool',
|
||||
'Allows the ID attribute in HTML. This is disabled by default '.
|
||||
'due to the fact that without proper configuration user input can '.
|
||||
'easily break the validation of a webpage by specifying an ID that is '.
|
||||
'already on the surrounding HTML. If you don\'t mind throwing caution to '.
|
||||
'the wind, enable this directive, but I strongly recommend you also '.
|
||||
'consider blacklisting IDs you use (%Attr.IDBlacklist) or prefixing all '.
|
||||
'user supplied IDs (%Attr.IDPrefix). This directive has been available '.
|
||||
'since 1.2.0, and when set to true reverts to the behavior of pre-1.2.0 '.
|
||||
'versions.'
|
||||
);
|
||||
HTMLPurifier_ConfigSchema::defineAlias(
|
||||
'HTML', 'EnableAttrID', 'Attr', 'EnableID'
|
||||
);
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'IDPrefix', '', 'string',
|
||||
'String to prefix to IDs. If you have no idea what IDs your pages '.
|
||||
'may use, you may opt to simply add a prefix to all user-submitted ID '.
|
||||
'attributes so that they are still usable, but will not conflict with '.
|
||||
'core page IDs. Example: setting the directive to \'user_\' will result in '.
|
||||
'a user submitted \'foo\' to become \'user_foo\' Be sure to set '.
|
||||
'%HTML.EnableAttrID to true before using '.
|
||||
'this. This directive was available since 1.2.0.'
|
||||
);
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'IDPrefixLocal', '', 'string',
|
||||
'Temporary prefix for IDs used in conjunction with %Attr.IDPrefix. If '.
|
||||
'you need to allow multiple sets of '.
|
||||
'user content on web page, you may need to have a seperate prefix that '.
|
||||
'changes with each iteration. This way, seperately submitted user content '.
|
||||
'displayed on the same page doesn\'t clobber each other. Ideal values '.
|
||||
'are unique identifiers for the content it represents (i.e. the id of '.
|
||||
'the row in the database). Be sure to add a seperator (like an underscore) '.
|
||||
'at the end. Warning: this directive will not work unless %Attr.IDPrefix '.
|
||||
'is set to a non-empty value! This directive was available since 1.2.0.'
|
||||
);
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'IDBlacklistRegexp', null, 'string/null',
|
||||
'PCRE regular expression to be matched against all IDs. If the expression '.
|
||||
'is matches, the ID is rejected. Use this with care: may cause '.
|
||||
'significant degradation. ID matching is done after all other '.
|
||||
'validation. This directive was available since 1.6.0.'
|
||||
);
|
||||
|
||||
/**
|
||||
* Validates the HTML attribute ID.
|
||||
* @warning Even though this is the id processor, it
|
||||
@@ -66,7 +15,7 @@ class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef
|
||||
// ref functionality disabled, since we also have to verify
|
||||
// whether or not the ID it refers to exists
|
||||
|
||||
function validate($id, $config, &$context) {
|
||||
public function validate($id, $config, $context) {
|
||||
|
||||
if (!$config->get('Attr', 'EnableID')) return false;
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||
|
||||
/**
|
||||
* Validates the HTML type length (not to be confused with CSS's length).
|
||||
*
|
||||
@@ -13,7 +10,7 @@ require_once 'HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||
class HTMLPurifier_AttrDef_HTML_Length extends HTMLPurifier_AttrDef_HTML_Pixels
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
$string = trim($string);
|
||||
if ($string === '') return false;
|
||||
|
||||
@@ -1,22 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'AllowedRel', array(), 'lookup',
|
||||
'List of allowed forward document relationships in the rel attribute. '.
|
||||
'Common values may be nofollow or print. By default, this is empty, '.
|
||||
'meaning that no document relationships are allowed. This directive '.
|
||||
'was available since 1.6.0.'
|
||||
);
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'AllowedRev', array(), 'lookup',
|
||||
'List of allowed reverse document relationships in the rev attribute. '.
|
||||
'This attribute is a bit of an edge-case; if you don\'t know what it '.
|
||||
'is for, stay away. This directive was available since 1.6.0.'
|
||||
);
|
||||
|
||||
/**
|
||||
* Validates a rel/rev link attribute against a directive of allowed values
|
||||
* @note We cannot use Enum because link types allow multiple
|
||||
@@ -27,9 +10,9 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/** Name config attribute to pull. */
|
||||
var $name;
|
||||
protected $name;
|
||||
|
||||
function HTMLPurifier_AttrDef_HTML_LinkTypes($name) {
|
||||
public function __construct($name) {
|
||||
$configLookup = array(
|
||||
'rel' => 'AllowedRel',
|
||||
'rev' => 'AllowedRev'
|
||||
@@ -42,7 +25,7 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
|
||||
$this->name = $configLookup[$name];
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
$allowed = $config->get('Attr', $this->name);
|
||||
if (empty($allowed)) return false;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/Length.php';
|
||||
|
||||
/**
|
||||
* Validates a MultiLength as defined by the HTML spec.
|
||||
*
|
||||
@@ -12,7 +9,7 @@ require_once 'HTMLPurifier/AttrDef/HTML/Length.php';
|
||||
class HTMLPurifier_AttrDef_HTML_MultiLength extends HTMLPurifier_AttrDef_HTML_Length
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
$string = trim($string);
|
||||
if ($string === '') return false;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/Config.php';
|
||||
|
||||
/**
|
||||
* Validates contents based on NMTOKENS attribute type.
|
||||
* @note The only current use for this is the class attribute in HTML
|
||||
@@ -13,7 +10,7 @@ require_once 'HTMLPurifier/Config.php';
|
||||
class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
$string = trim($string);
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates an integer representation of pixels according to the HTML spec.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
$string = trim($string);
|
||||
if ($string === '0') return $string;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates an integer.
|
||||
* @note While this class was modeled off the CSS definition, no currently
|
||||
@@ -15,24 +13,24 @@ class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef
|
||||
/**
|
||||
* Bool indicating whether or not negative values are allowed
|
||||
*/
|
||||
var $negative = true;
|
||||
protected $negative = true;
|
||||
|
||||
/**
|
||||
* Bool indicating whether or not zero is allowed
|
||||
*/
|
||||
var $zero = true;
|
||||
protected $zero = true;
|
||||
|
||||
/**
|
||||
* Bool indicating whether or not positive values are allowed
|
||||
*/
|
||||
var $positive = true;
|
||||
protected $positive = true;
|
||||
|
||||
/**
|
||||
* @param $negative Bool indicating whether or not negative values are allowed
|
||||
* @param $zero Bool indicating whether or not zero is allowed
|
||||
* @param $positive Bool indicating whether or not positive values are allowed
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_Integer(
|
||||
public function __construct(
|
||||
$negative = true, $zero = true, $positive = true
|
||||
) {
|
||||
$this->negative = $negative;
|
||||
@@ -40,7 +38,7 @@ class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef
|
||||
$this->positive = $positive;
|
||||
}
|
||||
|
||||
function validate($integer, $config, &$context) {
|
||||
public function validate($integer, $config, $context) {
|
||||
|
||||
$integer = $this->parseCDATA($integer);
|
||||
if ($integer === '') return false;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates the HTML attribute lang, effectively a language code.
|
||||
* @note Built according to RFC 3066, which obsoleted RFC 1766
|
||||
@@ -9,7 +7,7 @@ require_once 'HTMLPurifier/AttrDef.php';
|
||||
class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
|
||||
// moodle change - we use special lang strings unfortunatelly
|
||||
return ereg_replace('[^0-9a-zA-Z_-]', '', $string);
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates arbitrary text according to the HTML spec.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_Text extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
return $this->parseCDATA($string);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,66 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/URIParser.php';
|
||||
require_once 'HTMLPurifier/URIScheme.php';
|
||||
require_once 'HTMLPurifier/URISchemeRegistry.php';
|
||||
require_once 'HTMLPurifier/AttrDef/URI/Host.php';
|
||||
require_once 'HTMLPurifier/PercentEncoder.php';
|
||||
require_once 'HTMLPurifier/AttrDef/URI/Email.php';
|
||||
|
||||
// special case filtering directives
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'URI', 'Munge', null, 'string/null', '
|
||||
<p>
|
||||
Munges all browsable (usually http, https and ftp)
|
||||
absolute URI\'s into another URI, usually a URI redirection service.
|
||||
This directive accepts a URI, formatted with a <code>%s</code> where
|
||||
the url-encoded original URI should be inserted (sample:
|
||||
<code>http://www.google.com/url?q=%s</code>).
|
||||
</p>
|
||||
<p>
|
||||
Uses for this directive:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Prevent PageRank leaks, while being fairly transparent
|
||||
to users (you may also want to add some client side JavaScript to
|
||||
override the text in the statusbar). <strong>Notice</strong>:
|
||||
Many security experts believe that this form of protection does not deter spam-bots.
|
||||
</li>
|
||||
<li>
|
||||
Redirect users to a splash page telling them they are leaving your
|
||||
website. While this is poor usability practice, it is often mandated
|
||||
in corporate environments.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
This directive has been available since 1.3.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
// disabling directives
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'URI', 'Disable', false, 'bool', '
|
||||
<p>
|
||||
Disables all URIs in all forms. Not sure why you\'d want to do that
|
||||
(after all, the Internet\'s founded on the notion of a hyperlink).
|
||||
This directive has been available since 1.3.0.
|
||||
</p>
|
||||
');
|
||||
HTMLPurifier_ConfigSchema::defineAlias('Attr', 'DisableURI', 'URI', 'Disable');
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'URI', 'DisableResources', false, 'bool', '
|
||||
<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. This directive has been available since 1.3.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
/**
|
||||
* Validates a URI as defined by RFC 3986.
|
||||
* @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme
|
||||
@@ -68,18 +7,18 @@ HTMLPurifier_ConfigSchema::define(
|
||||
class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
var $parser;
|
||||
var $embedsResource;
|
||||
protected $parser;
|
||||
protected $embedsResource;
|
||||
|
||||
/**
|
||||
* @param $embeds_resource_resource Does the URI here result in an extra HTTP request?
|
||||
*/
|
||||
function HTMLPurifier_AttrDef_URI($embeds_resource = false) {
|
||||
public function __construct($embeds_resource = false) {
|
||||
$this->parser = new HTMLPurifier_URIParser();
|
||||
$this->embedsResource = (bool) $embeds_resource;
|
||||
}
|
||||
|
||||
function validate($uri, $config, &$context) {
|
||||
public function validate($uri, $config, $context) {
|
||||
|
||||
if ($config->get('URI', 'Disable')) return false;
|
||||
|
||||
@@ -100,7 +39,7 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||
if (!$result) break;
|
||||
|
||||
// chained filtering
|
||||
$uri_def =& $config->getDefinition('URI');
|
||||
$uri_def = $config->getDefinition('URI');
|
||||
$result = $uri_def->filter($uri, $config, $context);
|
||||
if (!$result) break;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
|
||||
abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -15,4 +13,3 @@ class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
|
||||
}
|
||||
|
||||
// sub-implementations
|
||||
//moodlefix require_once 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Primitive email validation class based on the regexp found at
|
||||
* http://www.regular-expressions.info/email.html
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_URI_Email_SimpleCheck extends HTMLPurifier_AttrDef_URI_Email
|
||||
{
|
||||
|
||||
public function validate($string, $config, $context) {
|
||||
// no support for named mailboxes i.e. "Bob <[email protected]>"
|
||||
// that needs more percent encoding to be done
|
||||
if ($string == '') return false;
|
||||
$string = trim($string);
|
||||
$result = preg_match('/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i', $string);
|
||||
return $result ? $string : false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
require_once 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||
require_once 'HTMLPurifier/AttrDef/URI/IPv6.php';
|
||||
|
||||
/**
|
||||
* Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
|
||||
*/
|
||||
@@ -13,19 +9,19 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
|
||||
/**
|
||||
* Instance of HTMLPurifier_AttrDef_URI_IPv4 sub-validator
|
||||
*/
|
||||
var $ipv4;
|
||||
protected $ipv4;
|
||||
|
||||
/**
|
||||
* Instance of HTMLPurifier_AttrDef_URI_IPv6 sub-validator
|
||||
*/
|
||||
var $ipv6;
|
||||
protected $ipv6;
|
||||
|
||||
function HTMLPurifier_AttrDef_URI_Host() {
|
||||
public function __construct() {
|
||||
$this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4();
|
||||
$this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6();
|
||||
}
|
||||
|
||||
function validate($string, $config, &$context) {
|
||||
public function validate($string, $config, $context) {
|
||||
$length = strlen($string);
|
||||
if ($string === '') return '';
|
||||
if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef.php';
|
||||
|
||||
/**
|
||||
* Validates an IPv4 address
|
||||
* @author Feyd @ forums.devnetwork.net (public domain)
|
||||
@@ -11,11 +9,10 @@ class HTMLPurifier_AttrDef_URI_IPv4 extends HTMLPurifier_AttrDef
|
||||
|
||||
/**
|
||||
* IPv4 regex, protected so that IPv6 can reuse it
|
||||
* @protected
|
||||
*/
|
||||
var $ip4;
|
||||
protected $ip4;
|
||||
|
||||
function validate($aIP, $config, &$context) {
|
||||
public function validate($aIP, $config, $context) {
|
||||
|
||||
if (!$this->ip4) $this->_loadRegex();
|
||||
|
||||
@@ -32,7 +29,7 @@ class HTMLPurifier_AttrDef_URI_IPv4 extends HTMLPurifier_AttrDef
|
||||
* Lazy load function to prevent regex from being stuffed in
|
||||
* cache.
|
||||
*/
|
||||
function _loadRegex() {
|
||||
protected function _loadRegex() {
|
||||
$oct = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])'; // 0-255
|
||||
$this->ip4 = "(?:{$oct}\\.{$oct}\\.{$oct}\\.{$oct})";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||
|
||||
/**
|
||||
* Validates an IPv6 address.
|
||||
* @author Feyd @ forums.devnetwork.net (public domain)
|
||||
@@ -11,7 +9,7 @@ require_once 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||
class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4
|
||||
{
|
||||
|
||||
function validate($aIP, $config, &$context) {
|
||||
public function validate($aIP, $config, $context) {
|
||||
|
||||
if (!$this->ip4) $this->_loadRegex();
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* more details.
|
||||
*/
|
||||
|
||||
class HTMLPurifier_AttrTransform
|
||||
abstract class HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -26,9 +26,7 @@ class HTMLPurifier_AttrTransform
|
||||
* @param $context Mandatory HTMLPurifier_Context object
|
||||
* @returns Processed attribute array.
|
||||
*/
|
||||
function transform($attr, $config, &$context) {
|
||||
trigger_error('Cannot call abstract function', E_USER_ERROR);
|
||||
}
|
||||
abstract public function transform($attr, $config, $context);
|
||||
|
||||
/**
|
||||
* Prepends CSS properties to the style attribute, creating the
|
||||
@@ -36,7 +34,7 @@ class HTMLPurifier_AttrTransform
|
||||
* @param $attr Attribute array to process (passed by reference)
|
||||
* @param $css CSS to prepend
|
||||
*/
|
||||
function prependCSS(&$attr, $css) {
|
||||
public function prependCSS(&$attr, $css) {
|
||||
$attr['style'] = isset($attr['style']) ? $attr['style'] : '';
|
||||
$attr['style'] = $css . $attr['style'];
|
||||
}
|
||||
@@ -46,7 +44,7 @@ class HTMLPurifier_AttrTransform
|
||||
* @param $attr Attribute array to process (passed by reference)
|
||||
* @param $key Key of attribute to confiscate
|
||||
*/
|
||||
function confiscateAttr(&$attr, $key) {
|
||||
public function confiscateAttr(&$attr, $key) {
|
||||
if (!isset($attr[$key])) return null;
|
||||
$value = $attr[$key];
|
||||
unset($attr[$key]);
|
||||
|
||||
@@ -1,26 +1,14 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
// this MUST be placed in post, as it assumes that any value in dir is valid
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'DefaultTextDir', 'ltr', 'string',
|
||||
'Defines the default text direction (ltr or rtl) of the document '.
|
||||
'being parsed. This generally is the same as the value of the dir '.
|
||||
'attribute in HTML, or ltr if that is not specified.'
|
||||
);
|
||||
HTMLPurifier_ConfigSchema::defineAllowedValues(
|
||||
'Attr', 'DefaultTextDir', array( 'ltr', 'rtl' )
|
||||
);
|
||||
|
||||
/**
|
||||
* Post-trasnform that ensures that bdo tags have the dir attribute set.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
if (isset($attr['dir'])) return $attr;
|
||||
$attr['dir'] = $config->get('Attr', 'DefaultTextDir');
|
||||
return $attr;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
/**
|
||||
* Pre-transform that changes deprecated bgcolor attribute to CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_BgColor
|
||||
extends HTMLPurifier_AttrTransform {
|
||||
class HTMLPurifier_AttrTransform_BgColor extends HTMLPurifier_AttrTransform {
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
|
||||
if (!isset($attr['bgcolor'])) return $attr;
|
||||
|
||||
|
||||
@@ -1,33 +1,30 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
/**
|
||||
* Pre-transform that changes converts a boolean attribute to fixed CSS
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_BoolToCSS
|
||||
extends HTMLPurifier_AttrTransform {
|
||||
class HTMLPurifier_AttrTransform_BoolToCSS extends HTMLPurifier_AttrTransform {
|
||||
|
||||
/**
|
||||
* Name of boolean attribute that is trigger
|
||||
*/
|
||||
var $attr;
|
||||
protected $attr;
|
||||
|
||||
/**
|
||||
* CSS declarations to add to style, needs trailing semicolon
|
||||
*/
|
||||
var $css;
|
||||
protected $css;
|
||||
|
||||
/**
|
||||
* @param $attr string attribute name to convert from
|
||||
* @param $css string CSS declarations to add to style (needs semicolon)
|
||||
*/
|
||||
function HTMLPurifier_AttrTransform_BoolToCSS($attr, $css) {
|
||||
public function __construct($attr, $css) {
|
||||
$this->attr = $attr;
|
||||
$this->css = $css;
|
||||
}
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
if (!isset($attr[$this->attr])) return $attr;
|
||||
unset($attr[$this->attr]);
|
||||
$this->prependCSS($attr, $this->css);
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
/**
|
||||
* Pre-transform that changes deprecated border attribute to CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_Border extends HTMLPurifier_AttrTransform {
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
if (!isset($attr['border'])) return $attr;
|
||||
$border_width = $this->confiscateAttr($attr, 'border');
|
||||
// some validation should happen here
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
/**
|
||||
* Generic pre-transform that converts an attribute with a fixed number of
|
||||
* values (enumerated) to CSS.
|
||||
@@ -11,32 +9,32 @@ class HTMLPurifier_AttrTransform_EnumToCSS extends HTMLPurifier_AttrTransform {
|
||||
/**
|
||||
* Name of attribute to transform from
|
||||
*/
|
||||
var $attr;
|
||||
protected $attr;
|
||||
|
||||
/**
|
||||
* Lookup array of attribute values to CSS
|
||||
*/
|
||||
var $enumToCSS = array();
|
||||
protected $enumToCSS = array();
|
||||
|
||||
/**
|
||||
* Case sensitivity of the matching
|
||||
* @warning Currently can only be guaranteed to work with ASCII
|
||||
* values.
|
||||
*/
|
||||
var $caseSensitive = false;
|
||||
protected $caseSensitive = false;
|
||||
|
||||
/**
|
||||
* @param $attr String attribute name to transform from
|
||||
* @param $enumToCSS Lookup array of attribute values to CSS
|
||||
* @param $case_sensitive Boolean case sensitivity indicator, default false
|
||||
*/
|
||||
function HTMLPurifier_AttrTransform_EnumToCSS($attr, $enum_to_css, $case_sensitive = false) {
|
||||
public function __construct($attr, $enum_to_css, $case_sensitive = false) {
|
||||
$this->attr = $attr;
|
||||
$this->enumToCSS = $enum_to_css;
|
||||
$this->caseSensitive = (bool) $case_sensitive;
|
||||
}
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
|
||||
if (!isset($attr[$this->attr])) return $attr;
|
||||
|
||||
|
||||
@@ -1,24 +1,7 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
// must be called POST validation
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'DefaultInvalidImage', '', 'string',
|
||||
'This is the default image an img tag will be pointed to if it does '.
|
||||
'not have a valid src attribute. In future versions, we may allow the '.
|
||||
'image tag to be removed completely, but due to design issues, this is '.
|
||||
'not possible right now.'
|
||||
);
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Attr', 'DefaultInvalidImageAlt', 'Invalid image', 'string',
|
||||
'This is the content of the alt tag of an invalid image if the user '.
|
||||
'had not previously specified an alt attribute. It has no effect when the '.
|
||||
'image is valid but there was no alt attribute present.'
|
||||
);
|
||||
|
||||
/**
|
||||
* Transform that supplies default values for the src and alt attributes
|
||||
* in img tags, as well as prevents the img tag from being removed
|
||||
@@ -28,7 +11,7 @@ HTMLPurifier_ConfigSchema::define(
|
||||
class HTMLPurifier_AttrTransform_ImgRequired extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
|
||||
$src = true;
|
||||
if (!isset($attr['src'])) {
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
/**
|
||||
* Pre-transform that changes deprecated hspace and vspace attributes to CSS
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_ImgSpace
|
||||
extends HTMLPurifier_AttrTransform {
|
||||
class HTMLPurifier_AttrTransform_ImgSpace extends HTMLPurifier_AttrTransform {
|
||||
|
||||
var $attr;
|
||||
var $css = array(
|
||||
protected $attr;
|
||||
protected $css = array(
|
||||
'hspace' => array('left', 'right'),
|
||||
'vspace' => array('top', 'bottom')
|
||||
);
|
||||
|
||||
function HTMLPurifier_AttrTransform_ImgSpace($attr) {
|
||||
public function __construct($attr) {
|
||||
$this->attr = $attr;
|
||||
if (!isset($this->css[$attr])) {
|
||||
trigger_error(htmlspecialchars($attr) . ' is not valid space attribute');
|
||||
}
|
||||
}
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
|
||||
if (!isset($attr[$this->attr])) return $attr;
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
/**
|
||||
* Post-transform that copies lang's value to xml:lang (and vice-versa)
|
||||
* @note Theoretically speaking, this could be a pre-transform, but putting
|
||||
@@ -10,7 +8,7 @@ require_once 'HTMLPurifier/AttrTransform.php';
|
||||
class HTMLPurifier_AttrTransform_Lang extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
|
||||
$lang = isset($attr['lang']) ? $attr['lang'] : false;
|
||||
$xml_lang = isset($attr['xml:lang']) ? $attr['xml:lang'] : false;
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
/**
|
||||
* Class for handling width/height length attribute transformations to CSS
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_Length extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
var $name;
|
||||
var $cssName;
|
||||
protected $name;
|
||||
protected $cssName;
|
||||
|
||||
function HTMLPurifier_AttrTransform_Length($name, $css_name = null) {
|
||||
public function __construct($name, $css_name = null) {
|
||||
$this->name = $name;
|
||||
$this->cssName = $css_name ? $css_name : $name;
|
||||
}
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
if (!isset($attr[$this->name])) return $attr;
|
||||
$length = $this->confiscateAttr($attr, $this->name);
|
||||
if(ctype_digit($length)) $length .= 'px';
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrTransform.php';
|
||||
|
||||
/**
|
||||
* Pre-transform that changes deprecated name attribute to ID if necessary
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_Name extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
function transform($attr, $config, &$context) {
|
||||
public function transform($attr, $config, $context) {
|
||||
if (!isset($attr['name'])) return $attr;
|
||||
$id = $this->confiscateAttr($attr, 'name');
|
||||
if ( isset($attr['id'])) return $attr;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements required attribute stipulation for <script>
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_ScriptRequired extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
public function transform($attr, $config, $context) {
|
||||
if (!isset($attr['type'])) {
|
||||
$attr['type'] = 'text/javascript';
|
||||
}
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef/Lang.php';
|
||||
require_once 'HTMLPurifier/AttrDef/Enum.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/Bool.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/ID.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/Length.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/MultiLength.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||
require_once 'HTMLPurifier/AttrDef/HTML/Color.php';
|
||||
require_once 'HTMLPurifier/AttrDef/Integer.php';
|
||||
require_once 'HTMLPurifier/AttrDef/Text.php';
|
||||
require_once 'HTMLPurifier/AttrDef/URI.php';
|
||||
|
||||
/**
|
||||
* Provides lookup array of attribute types to HTMLPurifier_AttrDef objects
|
||||
*/
|
||||
@@ -20,15 +7,14 @@ class HTMLPurifier_AttrTypes
|
||||
{
|
||||
/**
|
||||
* Lookup array of attribute string identifiers to concrete implementations
|
||||
* @protected
|
||||
*/
|
||||
var $info = array();
|
||||
protected $info = array();
|
||||
|
||||
/**
|
||||
* Constructs the info array, supplying default implementations for attribute
|
||||
* types.
|
||||
*/
|
||||
function HTMLPurifier_AttrTypes() {
|
||||
public function __construct() {
|
||||
// pseudo-types, must be instantiated via shorthand
|
||||
$this->info['Enum'] = new HTMLPurifier_AttrDef_Enum();
|
||||
$this->info['Bool'] = new HTMLPurifier_AttrDef_HTML_Bool();
|
||||
@@ -57,7 +43,7 @@ class HTMLPurifier_AttrTypes
|
||||
* @param $type String type name
|
||||
* @return Object AttrDef for type
|
||||
*/
|
||||
function get($type) {
|
||||
public function get($type) {
|
||||
|
||||
// determine if there is any extra info tacked on
|
||||
if (strpos($type, '#') !== false) list($type, $string) = explode('#', $type, 2);
|
||||
@@ -77,7 +63,7 @@ class HTMLPurifier_AttrTypes
|
||||
* @param $type String type name
|
||||
* @param $impl Object AttrDef for type
|
||||
*/
|
||||
function set($type, $impl) {
|
||||
public function set($type, $impl) {
|
||||
$this->info[$type] = $impl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class HTMLPurifier_AttrValidator
|
||||
* @param $config Instance of HTMLPurifier_Config
|
||||
* @param $context Instance of HTMLPurifier_Context
|
||||
*/
|
||||
function validateToken(&$token, &$config, &$context) {
|
||||
public function validateToken(&$token, &$config, $context) {
|
||||
|
||||
$definition = $config->getHTMLDefinition();
|
||||
$e =& $context->get('ErrorCollector', true);
|
||||
@@ -34,7 +34,10 @@ class HTMLPurifier_AttrValidator
|
||||
$current_token =& $context->get('CurrentToken', true);
|
||||
if (!$current_token) $context->register('CurrentToken', $token);
|
||||
|
||||
if ($token->type !== 'start' && $token->type !== 'empty') return $token;
|
||||
if (
|
||||
!$token instanceof HTMLPurifier_Token_Start &&
|
||||
!$token instanceof HTMLPurifier_Token_Empty
|
||||
) return $token;
|
||||
|
||||
// create alias to global definition array, see also $defs
|
||||
// DEFINITION CALL
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
// constants are slow, so we use as few as possible
|
||||
if (!defined('HTMLPURIFIER_PREFIX')) {
|
||||
define('HTMLPURIFIER_PREFIX', realpath(dirname(__FILE__) . '/..'));
|
||||
}
|
||||
|
||||
// accomodations for versions earlier than 5.0.2
|
||||
// borrowed from PHP_Compat, LGPL licensed, by Aidan Lister <[email protected]>
|
||||
if (!defined('PHP_EOL')) {
|
||||
switch (strtoupper(substr(PHP_OS, 0, 3))) {
|
||||
case 'WIN':
|
||||
define('PHP_EOL', "\r\n");
|
||||
break;
|
||||
case 'DAR':
|
||||
define('PHP_EOL', "\r");
|
||||
break;
|
||||
default:
|
||||
define('PHP_EOL', "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap class that contains meta-functionality for HTML Purifier such as
|
||||
* the autoload function.
|
||||
*
|
||||
* @note
|
||||
* This class may be used without any other files from HTML Purifier.
|
||||
*/
|
||||
class HTMLPurifier_Bootstrap
|
||||
{
|
||||
|
||||
/**
|
||||
* Autoload function for HTML Purifier
|
||||
* @param $class Class to load
|
||||
*/
|
||||
public static function autoload($class) {
|
||||
$file = HTMLPurifier_Bootstrap::getPath($class);
|
||||
if (!$file) return false;
|
||||
require HTMLPURIFIER_PREFIX . '/' . $file;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path for a specific class.
|
||||
*/
|
||||
public static function getPath($class) {
|
||||
if (strncmp('HTMLPurifier', $class, 12) !== 0) return false;
|
||||
// Custom implementations
|
||||
if (strncmp('HTMLPurifier_Language_', $class, 22) === 0) {
|
||||
$code = str_replace('_', '-', substr($class, 22));
|
||||
$file = 'HTMLPurifier/Language/classes/' . $code . '.php';
|
||||
} else {
|
||||
$file = str_replace('_', '/', $class) . '.php';
|
||||
}
|
||||
if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) return false;
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Pre-registers" our autoloader on the SPL stack.
|
||||
*/
|
||||
public static function registerAutoload() {
|
||||
$autoload = array('HTMLPurifier_Bootstrap', 'autoload');
|
||||
if ( ($funcs = spl_autoload_functions()) === false ) {
|
||||
spl_autoload_register($autoload);
|
||||
} elseif (function_exists('spl_autoload_unregister')) {
|
||||
$compat = version_compare(PHP_VERSION, '5.1.2', '<=') &&
|
||||
version_compare(PHP_VERSION, '5.1.0', '>=');
|
||||
foreach ($funcs as $func) {
|
||||
if (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);
|
||||
}
|
||||
spl_autoload_unregister($func);
|
||||
}
|
||||
spl_autoload_register($autoload);
|
||||
foreach ($funcs as $func) spl_autoload_register($func);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/Definition.php';
|
||||
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Background.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Border.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Color.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Composite.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Font.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Length.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Multiple.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
|
||||
require_once 'HTMLPurifier/AttrDef/CSS/URI.php';
|
||||
require_once 'HTMLPurifier/AttrDef/Enum.php';
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'CSS', 'DefinitionRev', 1, 'int', '
|
||||
<p>
|
||||
Revision identifier for your custom definition. See
|
||||
%HTML.DefinitionRev for details. This directive has been available
|
||||
since 2.0.0.
|
||||
</p>
|
||||
');
|
||||
|
||||
/**
|
||||
* Defines allowed CSS attributes and what their values are.
|
||||
* @see HTMLPurifier_HTMLDefinition
|
||||
@@ -34,17 +7,17 @@ HTMLPurifier_ConfigSchema::define(
|
||||
class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
||||
{
|
||||
|
||||
var $type = 'CSS';
|
||||
public $type = 'CSS';
|
||||
|
||||
/**
|
||||
* Assoc array of attribute name to definition object.
|
||||
*/
|
||||
var $info = array();
|
||||
public $info = array();
|
||||
|
||||
/**
|
||||
* Constructs the info array. The meat of this class.
|
||||
*/
|
||||
function doSetup($config) {
|
||||
protected function doSetup($config) {
|
||||
|
||||
$this->info['text-align'] = new HTMLPurifier_AttrDef_Enum(
|
||||
array('left', 'right', 'center', 'justify'), false);
|
||||
@@ -226,7 +199,80 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
||||
// partial support
|
||||
$this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(array('nowrap'));
|
||||
|
||||
if ($config->get('CSS', 'Proprietary')) {
|
||||
$this->doSetupProprietary($config);
|
||||
}
|
||||
|
||||
if ($config->get('CSS', 'AllowTricky')) {
|
||||
$this->doSetupTricky($config);
|
||||
}
|
||||
|
||||
$allow_important = $config->get('CSS', 'AllowImportant');
|
||||
// wrap all attr-defs with decorator that handles !important
|
||||
foreach ($this->info as $k => $v) {
|
||||
$this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important);
|
||||
}
|
||||
|
||||
$this->setupConfigStuff($config);
|
||||
}
|
||||
|
||||
protected function doSetupProprietary($config) {
|
||||
// Internet Explorer only scrollbar colors
|
||||
$this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
|
||||
$this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color();
|
||||
$this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
|
||||
$this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color();
|
||||
$this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color();
|
||||
$this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
|
||||
|
||||
// technically not proprietary, but CSS3, and no one supports it
|
||||
$this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
|
||||
$this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
|
||||
$this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
|
||||
|
||||
// only opacity, for now
|
||||
$this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter();
|
||||
|
||||
}
|
||||
|
||||
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',
|
||||
'table-header-group', 'table-footer-group', 'table-row',
|
||||
'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none'
|
||||
));
|
||||
$this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(array(
|
||||
'visible', 'hidden', 'collapse'
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs extra config-based processing. Based off of
|
||||
* HTMLPurifier_HTMLDefinition.
|
||||
* @todo Refactor duplicate elements into common class (probably using
|
||||
* composition, not inheritance).
|
||||
*/
|
||||
protected function setupConfigStuff($config) {
|
||||
|
||||
// setup allowed elements
|
||||
$support = "(for information on implementing this, see the ".
|
||||
"support forums) ";
|
||||
$allowed_attributes = $config->get('CSS', 'AllowedProperties');
|
||||
if ($allowed_attributes !== null) {
|
||||
foreach ($this->info as $name => $d) {
|
||||
if(!isset($allowed_attributes[$name])) unset($this->info[$name]);
|
||||
unset($allowed_attributes[$name]);
|
||||
}
|
||||
// emit errors
|
||||
foreach ($allowed_attributes 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +1,32 @@
|
||||
<?php
|
||||
|
||||
// HTMLPurifier_ChildDef and inheritance have three types of output:
|
||||
// true = leave nodes as is
|
||||
// false = delete parent node and all children
|
||||
// array(...) = replace children nodes with these
|
||||
|
||||
HTMLPurifier_ConfigSchema::define(
|
||||
'Core', 'EscapeInvalidChildren', false, 'bool',
|
||||
'When true, a child is found that is not allowed in the context of the '.
|
||||
'parent element will be transformed into text as if it were ASCII. When '.
|
||||
'false, that element and all internal tags will be dropped, though text '.
|
||||
'will be preserved. There is no option for dropping the element but '.
|
||||
'preserving child nodes.'
|
||||
);
|
||||
|
||||
/**
|
||||
* Defines allowed child nodes and validates tokens against it.
|
||||
*/
|
||||
class HTMLPurifier_ChildDef
|
||||
abstract class HTMLPurifier_ChildDef
|
||||
{
|
||||
/**
|
||||
* Type of child definition, usually right-most part of class name lowercase.
|
||||
* Used occasionally in terms of context.
|
||||
* @public
|
||||
*/
|
||||
var $type;
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* Bool that indicates whether or not an empty array of children is okay
|
||||
*
|
||||
* This is necessary for redundant checking when changes affecting
|
||||
* a child node may cause a parent node to now be disallowed.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
var $allow_empty;
|
||||
public $allow_empty;
|
||||
|
||||
/**
|
||||
* Lookup array of all elements that this definition could possibly allow
|
||||
*/
|
||||
var $elements = array();
|
||||
public $elements = array();
|
||||
|
||||
/**
|
||||
* Validates nodes according to definition and returns modification.
|
||||
*
|
||||
* @public
|
||||
* @param $tokens_of_children Array of HTMLPurifier_Token
|
||||
* @param $config HTMLPurifier_Config object
|
||||
* @param $context HTMLPurifier_Context object
|
||||
@@ -52,9 +34,7 @@ class HTMLPurifier_ChildDef
|
||||
* @return bool false to remove parent node
|
||||
* @return array of replacement child tokens
|
||||
*/
|
||||
function validateChildren($tokens_of_children, $config, &$context) {
|
||||
trigger_error('Call to abstract function', E_USER_ERROR);
|
||||
}
|
||||
abstract public function validateChildren($tokens_of_children, $config, $context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ChildDef.php';
|
||||
|
||||
/**
|
||||
* Definition that uses different definitions depending on context.
|
||||
*
|
||||
@@ -16,29 +14,27 @@ class HTMLPurifier_ChildDef_Chameleon extends HTMLPurifier_ChildDef
|
||||
|
||||
/**
|
||||
* Instance of the definition object to use when inline. Usually stricter.
|
||||
* @public
|
||||
*/
|
||||
var $inline;
|
||||
public $inline;
|
||||
|
||||
/**
|
||||
* Instance of the definition object to use when block.
|
||||
* @public
|
||||
*/
|
||||
var $block;
|
||||
public $block;
|
||||
|
||||
var $type = 'chameleon';
|
||||
public $type = 'chameleon';
|
||||
|
||||
/**
|
||||
* @param $inline List of elements to allow when inline.
|
||||
* @param $block List of elements to allow when block.
|
||||
*/
|
||||
function HTMLPurifier_ChildDef_Chameleon($inline, $block) {
|
||||
public function __construct($inline, $block) {
|
||||
$this->inline = new HTMLPurifier_ChildDef_Optional($inline);
|
||||
$this->block = new HTMLPurifier_ChildDef_Optional($block);
|
||||
$this->elements = $this->block->elements;
|
||||
}
|
||||
|
||||
function validateChildren($tokens_of_children, $config, &$context) {
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
if ($context->get('IsInline') === false) {
|
||||
return $this->block->validateChildren(
|
||||
$tokens_of_children, $config, $context);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ChildDef.php';
|
||||
|
||||
/**
|
||||
* Custom validation class, accepts DTD child definitions
|
||||
*
|
||||
@@ -12,28 +10,28 @@ require_once 'HTMLPurifier/ChildDef.php';
|
||||
*/
|
||||
class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef
|
||||
{
|
||||
var $type = 'custom';
|
||||
var $allow_empty = false;
|
||||
public $type = 'custom';
|
||||
public $allow_empty = false;
|
||||
/**
|
||||
* Allowed child pattern as defined by the DTD
|
||||
*/
|
||||
var $dtd_regex;
|
||||
public $dtd_regex;
|
||||
/**
|
||||
* PCRE regex derived from $dtd_regex
|
||||
* @private
|
||||
*/
|
||||
var $_pcre_regex;
|
||||
private $_pcre_regex;
|
||||
/**
|
||||
* @param $dtd_regex Allowed child pattern from the DTD
|
||||
*/
|
||||
function HTMLPurifier_ChildDef_Custom($dtd_regex) {
|
||||
public function __construct($dtd_regex) {
|
||||
$this->dtd_regex = $dtd_regex;
|
||||
$this->_compileRegex();
|
||||
}
|
||||
/**
|
||||
* Compiles the PCRE regex from a DTD regex ($dtd_regex to $_pcre_regex)
|
||||
*/
|
||||
function _compileRegex() {
|
||||
protected function _compileRegex() {
|
||||
$raw = str_replace(' ', '', $this->dtd_regex);
|
||||
if ($raw{0} != '(') {
|
||||
$raw = "($raw)";
|
||||
@@ -61,7 +59,7 @@ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef
|
||||
|
||||
$this->_pcre_regex = $reg;
|
||||
}
|
||||
function validateChildren($tokens_of_children, $config, &$context) {
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
$list_of_children = '';
|
||||
$nesting = 0; // depth into the nest
|
||||
foreach ($tokens_of_children as $token) {
|
||||
@@ -69,9 +67,9 @@ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef
|
||||
|
||||
$is_child = ($nesting == 0); // direct
|
||||
|
||||
if ($token->type == 'start') {
|
||||
if ($token instanceof HTMLPurifier_Token_Start) {
|
||||
$nesting++;
|
||||
} elseif ($token->type == 'end') {
|
||||
} elseif ($token instanceof HTMLPurifier_Token_End) {
|
||||
$nesting--;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ChildDef.php';
|
||||
|
||||
/**
|
||||
* Definition that disallows all elements.
|
||||
* @warning validateChildren() in this class is actually never called, because
|
||||
@@ -11,10 +9,10 @@ require_once 'HTMLPurifier/ChildDef.php';
|
||||
*/
|
||||
class HTMLPurifier_ChildDef_Empty extends HTMLPurifier_ChildDef
|
||||
{
|
||||
var $allow_empty = true;
|
||||
var $type = 'empty';
|
||||
function HTMLPurifier_ChildDef_Empty() {}
|
||||
function validateChildren($tokens_of_children, $config, &$context) {
|
||||
public $allow_empty = true;
|
||||
public $type = 'empty';
|
||||
public function __construct() {}
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ChildDef/Required.php';
|
||||
|
||||
/**
|
||||
* Definition that allows a set of elements, and allows no children.
|
||||
* @note This is a hack to reuse code from HTMLPurifier_ChildDef_Required,
|
||||
@@ -11,9 +9,9 @@ require_once 'HTMLPurifier/ChildDef/Required.php';
|
||||
*/
|
||||
class HTMLPurifier_ChildDef_Optional extends HTMLPurifier_ChildDef_Required
|
||||
{
|
||||
var $allow_empty = true;
|
||||
var $type = 'optional';
|
||||
function validateChildren($tokens_of_children, $config, &$context) {
|
||||
public $allow_empty = true;
|
||||
public $type = 'optional';
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
$result = parent::validateChildren($tokens_of_children, $config, $context);
|
||||
if ($result === false) {
|
||||
if (empty($tokens_of_children)) return true;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ChildDef.php';
|
||||
|
||||
/**
|
||||
* Definition that allows a set of elements, but disallows empty children.
|
||||
*/
|
||||
@@ -11,11 +9,11 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
||||
* Lookup table of allowed elements.
|
||||
* @public
|
||||
*/
|
||||
var $elements = array();
|
||||
public $elements = array();
|
||||
/**
|
||||
* @param $elements List of allowed element names (lowercase).
|
||||
*/
|
||||
function HTMLPurifier_ChildDef_Required($elements) {
|
||||
public function __construct($elements) {
|
||||
if (is_string($elements)) {
|
||||
$elements = str_replace(' ', '', $elements);
|
||||
$elements = explode('|', $elements);
|
||||
@@ -30,9 +28,9 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
||||
}
|
||||
$this->elements = $elements;
|
||||
}
|
||||
var $allow_empty = false;
|
||||
var $type = 'required';
|
||||
function validateChildren($tokens_of_children, $config, &$context) {
|
||||
public $allow_empty = false;
|
||||
public $type = 'required';
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
// if there are no tokens, delete parent node
|
||||
if (empty($tokens_of_children)) return false;
|
||||
|
||||
@@ -59,7 +57,7 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
||||
// generator
|
||||
static $gen = null;
|
||||
if ($gen === null) {
|
||||
$gen = new HTMLPurifier_Generator();
|
||||
$gen = new HTMLPurifier_Generator($config, $context);
|
||||
}
|
||||
|
||||
foreach ($tokens_of_children as $token) {
|
||||
@@ -71,9 +69,9 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
||||
|
||||
$is_child = ($nesting == 0);
|
||||
|
||||
if ($token->type == 'start') {
|
||||
if ($token instanceof HTMLPurifier_Token_Start) {
|
||||
$nesting++;
|
||||
} elseif ($token->type == 'end') {
|
||||
} elseif ($token instanceof HTMLPurifier_Token_End) {
|
||||
$nesting--;
|
||||
}
|
||||
|
||||
@@ -81,7 +79,7 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
||||
$is_deleting = false;
|
||||
if (!isset($this->elements[$token->name])) {
|
||||
$is_deleting = true;
|
||||
if ($pcdata_allowed && $token->type == 'text') {
|
||||
if ($pcdata_allowed && $token instanceof HTMLPurifier_Token_Text) {
|
||||
$result[] = $token;
|
||||
} elseif ($pcdata_allowed && $escape_invalid_children) {
|
||||
$result[] = new HTMLPurifier_Token_Text(
|
||||
@@ -91,7 +89,7 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!$is_deleting || ($pcdata_allowed && $token->type == 'text')) {
|
||||
if (!$is_deleting || ($pcdata_allowed && $token instanceof HTMLPurifier_Token_Text)) {
|
||||
$result[] = $token;
|
||||
} elseif ($pcdata_allowed && $escape_invalid_children) {
|
||||
$result[] =
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ChildDef/Required.php';
|
||||
|
||||
/**
|
||||
* Takes the contents of blockquote when in strict and reformats for validation.
|
||||
*/
|
||||
class HTMLPurifier_ChildDef_StrictBlockquote
|
||||
extends HTMLPurifier_ChildDef_Required
|
||||
class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Required
|
||||
{
|
||||
var $real_elements;
|
||||
var $fake_elements;
|
||||
var $allow_empty = true;
|
||||
var $type = 'strictblockquote';
|
||||
var $init = false;
|
||||
function validateChildren($tokens_of_children, $config, &$context) {
|
||||
protected $real_elements;
|
||||
protected $fake_elements;
|
||||
public $allow_empty = true;
|
||||
public $type = 'strictblockquote';
|
||||
protected $init = false;
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
|
||||
$def = $config->getHTMLDefinition();
|
||||
if (!$this->init) {
|
||||
@@ -45,8 +42,8 @@ extends HTMLPurifier_ChildDef_Required
|
||||
if (!$is_inline) {
|
||||
if (!$depth) {
|
||||
if (
|
||||
($token->type == 'text' && !$token->is_whitespace) ||
|
||||
($token->type != 'text' && !isset($this->elements[$token->name]))
|
||||
($token instanceof HTMLPurifier_Token_Text && !$token->is_whitespace) ||
|
||||
(!$token instanceof HTMLPurifier_Token_Text && !isset($this->elements[$token->name]))
|
||||
) {
|
||||
$is_inline = true;
|
||||
$ret[] = $block_wrap_start;
|
||||
@@ -55,7 +52,7 @@ extends HTMLPurifier_ChildDef_Required
|
||||
} else {
|
||||
if (!$depth) {
|
||||
// starting tokens have been inline text / empty
|
||||
if ($token->type == 'start' || $token->type == 'empty') {
|
||||
if ($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) {
|
||||
if (isset($this->elements[$token->name])) {
|
||||
// ended
|
||||
$ret[] = $block_wrap_end;
|
||||
@@ -65,8 +62,8 @@ extends HTMLPurifier_ChildDef_Required
|
||||
}
|
||||
}
|
||||
$ret[] = $token;
|
||||
if ($token->type == 'start') $depth++;
|
||||
if ($token->type == 'end') $depth--;
|
||||
if ($token instanceof HTMLPurifier_Token_Start) $depth++;
|
||||
if ($token instanceof HTMLPurifier_Token_End) $depth--;
|
||||
}
|
||||
if ($is_inline) $ret[] = $block_wrap_end;
|
||||
return $ret;
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ChildDef.php';
|
||||
|
||||
/**
|
||||
* Definition for tables
|
||||
*/
|
||||
class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
|
||||
{
|
||||
var $allow_empty = false;
|
||||
var $type = 'table';
|
||||
var $elements = array('tr' => true, 'tbody' => true, 'thead' => true,
|
||||
public $allow_empty = false;
|
||||
public $type = 'table';
|
||||
public $elements = array('tr' => true, 'tbody' => true, 'thead' => true,
|
||||
'tfoot' => true, 'caption' => true, 'colgroup' => true, 'col' => true);
|
||||
function HTMLPurifier_ChildDef_Table() {}
|
||||
function validateChildren($tokens_of_children, $config, &$context) {
|
||||
public function __construct() {}
|
||||
public function validateChildren($tokens_of_children, $config, $context) {
|
||||
if (empty($tokens_of_children)) return false;
|
||||
|
||||
// this ensures that the loop gets run one last time before closing
|
||||
@@ -41,9 +39,9 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
|
||||
|
||||
if ($token === false) {
|
||||
// terminating sequence started
|
||||
} elseif ($token->type == 'start') {
|
||||
} elseif ($token instanceof HTMLPurifier_Token_Start) {
|
||||
$nesting++;
|
||||
} elseif ($token->type == 'end') {
|
||||
} elseif ($token instanceof HTMLPurifier_Token_End) {
|
||||
$nesting--;
|
||||
}
|
||||
|
||||
@@ -112,7 +110,7 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
|
||||
$collection[] = $token;
|
||||
continue;
|
||||
default:
|
||||
if ($token->type == 'text' && $token->is_whitespace) {
|
||||
if ($token instanceof HTMLPurifier_Token_Text && $token->is_whitespace) {
|
||||
$collection[] = $token;
|
||||
$tag_index++;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ConfigSchema.php';
|
||||
|
||||
// member variables
|
||||
require_once 'HTMLPurifier/HTMLDefinition.php';
|
||||
require_once 'HTMLPurifier/CSSDefinition.php';
|
||||
require_once 'HTMLPurifier/URIDefinition.php';
|
||||
require_once 'HTMLPurifier/Doctype.php';
|
||||
require_once 'HTMLPurifier/DefinitionCacheFactory.php';
|
||||
|
||||
// accomodations for versions earlier than 4.3.10 and 5.0.2
|
||||
// borrowed from PHP_Compat, LGPL licensed, by Aidan Lister <[email protected]>
|
||||
if (!defined('PHP_EOL')) {
|
||||
switch (strtoupper(substr(PHP_OS, 0, 3))) {
|
||||
case 'WIN':
|
||||
define('PHP_EOL', "\r\n");
|
||||
break;
|
||||
case 'DAR':
|
||||
define('PHP_EOL', "\r");
|
||||
break;
|
||||
default:
|
||||
define('PHP_EOL', "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration object that triggers customizable behavior.
|
||||
*
|
||||
@@ -35,6 +11,8 @@ if (!defined('PHP_EOL')) {
|
||||
* because a configuration object should always be forwarded,
|
||||
* otherwise, you run the risk of missing a parameter and then
|
||||
* being stumped when a configuration directive doesn't work.
|
||||
*
|
||||
* @todo Reconsider some of the public member variables
|
||||
*/
|
||||
class HTMLPurifier_Config
|
||||
{
|
||||
@@ -42,69 +20,83 @@ class HTMLPurifier_Config
|
||||
/**
|
||||
* HTML Purifier's version
|
||||
*/
|
||||
var $version = '2.1.4';
|
||||
|
||||
/**
|
||||
* Two-level associative array of configuration directives
|
||||
*/
|
||||
var $conf;
|
||||
|
||||
/**
|
||||
* Reference HTMLPurifier_ConfigSchema for value checking
|
||||
*/
|
||||
var $def;
|
||||
|
||||
/**
|
||||
* Indexed array of definitions
|
||||
*/
|
||||
var $definitions;
|
||||
|
||||
/**
|
||||
* Bool indicator whether or not config is finalized
|
||||
*/
|
||||
var $finalized = false;
|
||||
public $version = '3.1.0';
|
||||
|
||||
/**
|
||||
* Bool indicator whether or not to automatically finalize
|
||||
* the object if a read operation is done
|
||||
*/
|
||||
var $autoFinalize = true;
|
||||
public $autoFinalize = true;
|
||||
|
||||
// protected member variables
|
||||
|
||||
/**
|
||||
* Namespace indexed array of serials for specific namespaces (see
|
||||
* getSerial for more info).
|
||||
* getSerial() for more info).
|
||||
*/
|
||||
var $serials = array();
|
||||
protected $serials = array();
|
||||
|
||||
/**
|
||||
* Serial for entire configuration object
|
||||
*/
|
||||
var $serial;
|
||||
protected $serial;
|
||||
|
||||
/**
|
||||
* Two-level associative array of configuration directives
|
||||
*/
|
||||
protected $conf;
|
||||
|
||||
/**
|
||||
* Parser for variables
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* Reference HTMLPurifier_ConfigSchema for value checking
|
||||
* @note This is public for introspective purposes. Please don't
|
||||
* abuse!
|
||||
*/
|
||||
public $def;
|
||||
|
||||
/**
|
||||
* Indexed array of definitions
|
||||
*/
|
||||
protected $definitions;
|
||||
|
||||
/**
|
||||
* Bool indicator whether or not config is finalized
|
||||
*/
|
||||
protected $finalized = false;
|
||||
|
||||
/**
|
||||
* @param $definition HTMLPurifier_ConfigSchema that defines what directives
|
||||
* are allowed.
|
||||
*/
|
||||
function HTMLPurifier_Config(&$definition) {
|
||||
public function __construct($definition) {
|
||||
$this->conf = $definition->defaults; // set up, copy in defaults
|
||||
$this->def = $definition; // keep a copy around for checking
|
||||
$this->parser = new HTMLPurifier_VarParser_Flexible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor that creates a config object based on a mixed var
|
||||
* @static
|
||||
* @param mixed $config Variable that defines the state of the config
|
||||
* object. Can be: a HTMLPurifier_Config() object,
|
||||
* an array of directives based on loadArray(),
|
||||
* or a string filename of an ini file.
|
||||
* @param HTMLPurifier_ConfigSchema Schema object
|
||||
* @return Configured HTMLPurifier_Config object
|
||||
*/
|
||||
function create($config) {
|
||||
if (is_a($config, 'HTMLPurifier_Config')) {
|
||||
public static function create($config, $schema = null) {
|
||||
if ($config instanceof HTMLPurifier_Config) {
|
||||
// pass-through
|
||||
return $config;
|
||||
}
|
||||
$ret = HTMLPurifier_Config::createDefault();
|
||||
if (!$schema) {
|
||||
$ret = HTMLPurifier_Config::createDefault();
|
||||
} else {
|
||||
$ret = new HTMLPurifier_Config($schema);
|
||||
}
|
||||
if (is_string($config)) $ret->loadIni($config);
|
||||
elseif (is_array($config)) $ret->loadArray($config);
|
||||
return $ret;
|
||||
@@ -112,11 +104,10 @@ class HTMLPurifier_Config
|
||||
|
||||
/**
|
||||
* Convenience constructor that creates a default configuration object.
|
||||
* @static
|
||||
* @return Default HTMLPurifier_Config object.
|
||||
*/
|
||||
function createDefault() {
|
||||
$definition =& HTMLPurifier_ConfigSchema::instance();
|
||||
public static function createDefault() {
|
||||
$definition = HTMLPurifier_ConfigSchema::instance();
|
||||
$config = new HTMLPurifier_Config($definition);
|
||||
return $config;
|
||||
}
|
||||
@@ -126,7 +117,7 @@ class HTMLPurifier_Config
|
||||
* @param $namespace String namespace
|
||||
* @param $key String key
|
||||
*/
|
||||
function get($namespace, $key, $from_alias = false) {
|
||||
public function get($namespace, $key) {
|
||||
if (!$this->finalized && $this->autoFinalize) $this->finalize();
|
||||
if (!isset($this->def->info[$namespace][$key])) {
|
||||
// can't add % due to SimpleTest bug
|
||||
@@ -147,7 +138,7 @@ class HTMLPurifier_Config
|
||||
* Retreives an array of directives to values from a given namespace
|
||||
* @param $namespace String namespace
|
||||
*/
|
||||
function getBatch($namespace) {
|
||||
public function getBatch($namespace) {
|
||||
if (!$this->finalized && $this->autoFinalize) $this->finalize();
|
||||
if (!isset($this->def->info[$namespace])) {
|
||||
trigger_error('Cannot retrieve undefined namespace ' . htmlspecialchars($namespace),
|
||||
@@ -164,7 +155,7 @@ class HTMLPurifier_Config
|
||||
* before processing!
|
||||
* @param $namespace Namespace to get serial for
|
||||
*/
|
||||
function getBatchSerial($namespace) {
|
||||
public function getBatchSerial($namespace) {
|
||||
if (empty($this->serials[$namespace])) {
|
||||
$batch = $this->getBatch($namespace);
|
||||
unset($batch['DefinitionRev']);
|
||||
@@ -177,7 +168,7 @@ class HTMLPurifier_Config
|
||||
* Returns a md5 signature for the entire configuration object
|
||||
* that uniquely identifies that particular configuration
|
||||
*/
|
||||
function getSerial() {
|
||||
public function getSerial() {
|
||||
if (empty($this->serial)) {
|
||||
$this->serial = md5(serialize($this->getAll()));
|
||||
}
|
||||
@@ -187,7 +178,7 @@ class HTMLPurifier_Config
|
||||
/**
|
||||
* Retrieves all directives, organized by namespace
|
||||
*/
|
||||
function getAll() {
|
||||
public function getAll() {
|
||||
if (!$this->finalized && $this->autoFinalize) $this->finalize();
|
||||
return $this->conf;
|
||||
}
|
||||
@@ -198,7 +189,7 @@ class HTMLPurifier_Config
|
||||
* @param $key String key
|
||||
* @param $value Mixed value
|
||||
*/
|
||||
function set($namespace, $key, $value, $from_alias = false) {
|
||||
public function set($namespace, $key, $value, $from_alias = false) {
|
||||
if ($this->isFinalized('Cannot set directive after finalization')) return;
|
||||
if (!isset($this->def->info[$namespace][$key])) {
|
||||
trigger_error('Cannot set undefined directive ' . htmlspecialchars("$namespace.$key") . ' to value',
|
||||
@@ -208,18 +199,25 @@ class HTMLPurifier_Config
|
||||
if ($this->def->info[$namespace][$key]->class == 'alias') {
|
||||
if ($from_alias) {
|
||||
trigger_error('Double-aliases not allowed, please fix '.
|
||||
'ConfigSchema bug with' . "$namespace.$key");
|
||||
'ConfigSchema bug with' . "$namespace.$key", E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
$this->set($this->def->info[$namespace][$key]->namespace,
|
||||
$this->def->info[$namespace][$key]->name,
|
||||
$this->set($new_ns = $this->def->info[$namespace][$key]->namespace,
|
||||
$new_dir = $this->def->info[$namespace][$key]->name,
|
||||
$value, true);
|
||||
trigger_error("$namespace.$key is an alias, preferred directive name is $new_ns.$new_dir", E_USER_NOTICE);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$value = $this->parser->parse(
|
||||
$value,
|
||||
$type = $this->def->info[$namespace][$key]->type,
|
||||
$this->def->info[$namespace][$key]->allow_null
|
||||
);
|
||||
} catch (HTMLPurifier_VarParserException $e) {
|
||||
trigger_error('Value for ' . "$namespace.$key" . ' is of invalid type, should be ' . $type, E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
$value = $this->def->validate(
|
||||
$value,
|
||||
$type = $this->def->info[$namespace][$key]->type,
|
||||
$this->def->info[$namespace][$key]->allow_null
|
||||
);
|
||||
if (is_string($value)) {
|
||||
// resolve value alias if defined
|
||||
if (isset($this->def->info[$namespace][$key]->aliases[$value])) {
|
||||
@@ -234,10 +232,6 @@ class HTMLPurifier_Config
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->def->isError($value)) {
|
||||
trigger_error('Value for ' . "$namespace.$key" . ' is of invalid type, should be ' . $type, E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
$this->conf[$namespace][$key] = $value;
|
||||
|
||||
// reset definitions if the directives they depend on changed
|
||||
@@ -252,30 +246,29 @@ class HTMLPurifier_Config
|
||||
|
||||
/**
|
||||
* Convenience function for error reporting
|
||||
* @private
|
||||
*/
|
||||
function _listify($lookup) {
|
||||
private function _listify($lookup) {
|
||||
$list = array();
|
||||
foreach ($lookup as $name => $b) $list[] = $name;
|
||||
return implode(', ', $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves reference to the HTML definition.
|
||||
* Retrieves object reference to the HTML definition.
|
||||
* @param $raw Return a copy that has not been setup yet. Must be
|
||||
* called before it's been setup, otherwise won't work.
|
||||
*/
|
||||
function &getHTMLDefinition($raw = false) {
|
||||
$def =& $this->getDefinition('HTML', $raw);
|
||||
return $def; // prevent PHP 4.4.0 from complaining
|
||||
public function getHTMLDefinition($raw = false) {
|
||||
return $this->getDefinition('HTML', $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves reference to the CSS definition
|
||||
* Retrieves object reference to the CSS definition
|
||||
* @param $raw Return a copy that has not been setup yet. Must be
|
||||
* called before it's been setup, otherwise won't work.
|
||||
*/
|
||||
function &getCSSDefinition($raw = false) {
|
||||
$def =& $this->getDefinition('CSS', $raw);
|
||||
return $def;
|
||||
public function getCSSDefinition($raw = false) {
|
||||
return $this->getDefinition('CSS', $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,7 +276,7 @@ class HTMLPurifier_Config
|
||||
* @param $type Type of definition: HTML, CSS, etc
|
||||
* @param $raw Whether or not definition should be returned raw
|
||||
*/
|
||||
function &getDefinition($type, $raw = false) {
|
||||
public function getDefinition($type, $raw = false) {
|
||||
if (!$this->finalized && $this->autoFinalize) $this->finalize();
|
||||
$factory = HTMLPurifier_DefinitionCacheFactory::instance();
|
||||
$cache = $factory->create($type, $this);
|
||||
@@ -317,17 +310,13 @@ class HTMLPurifier_Config
|
||||
} elseif ($type == 'URI') {
|
||||
$this->definitions[$type] = new HTMLPurifier_URIDefinition();
|
||||
} else {
|
||||
trigger_error("Definition of $type type not supported");
|
||||
$false = false;
|
||||
return $false;
|
||||
throw new HTMLPurifier_Exception("Definition of $type type not supported");
|
||||
}
|
||||
// quick abort if raw
|
||||
if ($raw) {
|
||||
if (is_null($this->get($type, 'DefinitionID'))) {
|
||||
// fatally error out if definition ID not set
|
||||
trigger_error("Cannot retrieve raw version without specifying %$type.DefinitionID", E_USER_ERROR);
|
||||
$false = new HTMLPurifier_Error();
|
||||
return $false;
|
||||
throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID");
|
||||
}
|
||||
return $this->definitions[$type];
|
||||
}
|
||||
@@ -343,7 +332,7 @@ class HTMLPurifier_Config
|
||||
* Namespace.Directive => Value
|
||||
* @param $config_array Configuration associative array
|
||||
*/
|
||||
function loadArray($config_array) {
|
||||
public function loadArray($config_array) {
|
||||
if ($this->isFinalized('Cannot load directives after finalization')) return;
|
||||
foreach ($config_array as $key => $value) {
|
||||
$key = str_replace('_', '.', $key);
|
||||
@@ -366,10 +355,11 @@ class HTMLPurifier_Config
|
||||
* that are allowed in a web-form context as per an allowed
|
||||
* namespaces/directives list.
|
||||
* @param $allowed List of allowed namespaces/directives
|
||||
* @static
|
||||
*/
|
||||
function getAllowedDirectivesForForm($allowed) {
|
||||
$schema = HTMLPurifier_ConfigSchema::instance();
|
||||
public static function getAllowedDirectivesForForm($allowed, $schema = null) {
|
||||
if (!$schema) {
|
||||
$schema = HTMLPurifier_ConfigSchema::instance();
|
||||
}
|
||||
if ($allowed !== true) {
|
||||
if (is_string($allowed)) $allowed = array($allowed);
|
||||
$allowed_ns = array();
|
||||
@@ -411,11 +401,11 @@ class HTMLPurifier_Config
|
||||
* @param $index Index/name that the config variables are in
|
||||
* @param $allowed List of allowed namespaces/directives
|
||||
* @param $mq_fix Boolean whether or not to enable magic quotes fix
|
||||
* @static
|
||||
* @param $schema Instance of HTMLPurifier_ConfigSchema to use, if not global copy
|
||||
*/
|
||||
function loadArrayFromForm($array, $index, $allowed = true, $mq_fix = true) {
|
||||
$ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix);
|
||||
$config = HTMLPurifier_Config::create($ret);
|
||||
public static function loadArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) {
|
||||
$ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema);
|
||||
$config = HTMLPurifier_Config::create($ret, $schema);
|
||||
return $config;
|
||||
}
|
||||
|
||||
@@ -423,21 +413,20 @@ class HTMLPurifier_Config
|
||||
* Merges in configuration values from $_GET/$_POST to object. NOT STATIC.
|
||||
* @note Same parameters as loadArrayFromForm
|
||||
*/
|
||||
function mergeArrayFromForm($array, $index, $allowed = true, $mq_fix = true) {
|
||||
$ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix);
|
||||
public function mergeArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true) {
|
||||
$ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def);
|
||||
$this->loadArray($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares an array from a form into something usable for the more
|
||||
* strict parts of HTMLPurifier_Config
|
||||
* @static
|
||||
*/
|
||||
function prepareArrayFromForm($array, $index, $allowed = true, $mq_fix = true) {
|
||||
$array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array();
|
||||
$mq = get_magic_quotes_gpc() && $mq_fix;
|
||||
public static function prepareArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) {
|
||||
if ($index !== false) $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array();
|
||||
$mq = $mq_fix && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc();
|
||||
|
||||
$allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed);
|
||||
$allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema);
|
||||
$ret = array();
|
||||
foreach ($allowed as $key) {
|
||||
list($ns, $directive) = $key;
|
||||
@@ -457,7 +446,7 @@ class HTMLPurifier_Config
|
||||
* Loads configuration values from an ini file
|
||||
* @param $filename Name of ini file
|
||||
*/
|
||||
function loadIni($filename) {
|
||||
public function loadIni($filename) {
|
||||
if ($this->isFinalized('Cannot load directives after finalization')) return;
|
||||
$array = parse_ini_file($filename, true);
|
||||
$this->loadArray($array);
|
||||
@@ -467,7 +456,7 @@ class HTMLPurifier_Config
|
||||
* Checks whether or not the configuration object is finalized.
|
||||
* @param $error String error message, or false for no error
|
||||
*/
|
||||
function isFinalized($error = false) {
|
||||
public function isFinalized($error = false) {
|
||||
if ($this->finalized && $error) {
|
||||
trigger_error($error, E_USER_ERROR);
|
||||
}
|
||||
@@ -478,17 +467,18 @@ class HTMLPurifier_Config
|
||||
* Finalizes configuration only if auto finalize is on and not
|
||||
* already finalized
|
||||
*/
|
||||
function autoFinalize() {
|
||||
public function autoFinalize() {
|
||||
if (!$this->finalized && $this->autoFinalize) $this->finalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes a configuration object, prohibiting further change
|
||||
*/
|
||||
function finalize() {
|
||||
public function finalize() {
|
||||
$this->finalized = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Base class for configuration entity
|
||||
*/
|
||||
class HTMLPurifier_ConfigDef {
|
||||
var $class = false;
|
||||
abstract class HTMLPurifier_ConfigDef {
|
||||
public $class = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ConfigDef.php';
|
||||
|
||||
/**
|
||||
* Structure object containing definition of a directive.
|
||||
* @note This structure does not contain default values
|
||||
@@ -9,20 +7,18 @@ require_once 'HTMLPurifier/ConfigDef.php';
|
||||
class HTMLPurifier_ConfigDef_Directive extends HTMLPurifier_ConfigDef
|
||||
{
|
||||
|
||||
var $class = 'directive';
|
||||
public $class = 'directive';
|
||||
|
||||
function HTMLPurifier_ConfigDef_Directive(
|
||||
public function __construct(
|
||||
$type = null,
|
||||
$descriptions = null,
|
||||
$allow_null = null,
|
||||
$allowed = null,
|
||||
$aliases = null
|
||||
) {
|
||||
if ( $type !== null) $this->type = $type;
|
||||
if ($descriptions !== null) $this->descriptions = $descriptions;
|
||||
if ( $allow_null !== null) $this->allow_null = $allow_null;
|
||||
if ( $allowed !== null) $this->allowed = $allowed;
|
||||
if ( $aliases !== null) $this->aliases = $aliases;
|
||||
if ( $type !== null) $this->type = $type;
|
||||
if ( $allow_null !== null) $this->allow_null = $allow_null;
|
||||
if ( $allowed !== null) $this->allowed = $allowed;
|
||||
if ( $aliases !== null) $this->aliases = $aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,43 +33,23 @@ class HTMLPurifier_ConfigDef_Directive extends HTMLPurifier_ConfigDef
|
||||
* - hash (array of key => value)
|
||||
* - mixed (anything goes)
|
||||
*/
|
||||
var $type = 'mixed';
|
||||
|
||||
/**
|
||||
* Plaintext descriptions of the configuration entity is. Organized by
|
||||
* file and line number, so multiple descriptions are allowed.
|
||||
*/
|
||||
var $descriptions = array();
|
||||
public $type = 'mixed';
|
||||
|
||||
/**
|
||||
* Is null allowed? Has no effect for mixed type.
|
||||
* @bool
|
||||
*/
|
||||
var $allow_null = false;
|
||||
public $allow_null = false;
|
||||
|
||||
/**
|
||||
* Lookup table of allowed values of the element, bool true if all allowed.
|
||||
*/
|
||||
var $allowed = true;
|
||||
public $allowed = true;
|
||||
|
||||
/**
|
||||
* Hash of value aliases, i.e. values that are equivalent.
|
||||
*/
|
||||
var $aliases = array();
|
||||
|
||||
/**
|
||||
* Advisory list of directive aliases, i.e. other directives that
|
||||
* redirect here
|
||||
*/
|
||||
var $directiveAliases = array();
|
||||
|
||||
/**
|
||||
* Adds a description to the array
|
||||
*/
|
||||
function addDescription($file, $line, $description) {
|
||||
if (!isset($this->descriptions[$file])) $this->descriptions[$file] = array();
|
||||
$this->descriptions[$file][$line] = $description;
|
||||
}
|
||||
public $aliases = array();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ConfigDef.php';
|
||||
|
||||
/**
|
||||
* Structure object describing a directive alias
|
||||
*/
|
||||
class HTMLPurifier_ConfigDef_DirectiveAlias extends HTMLPurifier_ConfigDef
|
||||
{
|
||||
var $class = 'alias';
|
||||
public $class = 'alias';
|
||||
|
||||
/**
|
||||
* Namespace being aliased to
|
||||
*/
|
||||
var $namespace;
|
||||
public $namespace;
|
||||
/**
|
||||
* Directive being aliased to
|
||||
*/
|
||||
var $name;
|
||||
public $name;
|
||||
|
||||
function HTMLPurifier_ConfigDef_DirectiveAlias($namespace, $name) {
|
||||
public function __construct($namespace, $name) {
|
||||
$this->namespace = $namespace;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,10 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/ConfigDef.php';
|
||||
|
||||
/**
|
||||
* Structure object describing of a namespace
|
||||
*/
|
||||
class HTMLPurifier_ConfigDef_Namespace extends HTMLPurifier_ConfigDef {
|
||||
|
||||
function HTMLPurifier_ConfigDef_Namespace($description = null) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
var $class = 'namespace';
|
||||
|
||||
/**
|
||||
* String description of what kinds of directives go in this namespace.
|
||||
*/
|
||||
var $description;
|
||||
|
||||
class HTMLPurifier_ConfigDef_Namespace extends HTMLPurifier_ConfigDef
|
||||
{
|
||||
public $class = 'namespace';
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,7 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/Error.php';
|
||||
require_once 'HTMLPurifier/ConfigDef.php';
|
||||
require_once 'HTMLPurifier/ConfigDef/Namespace.php';
|
||||
require_once 'HTMLPurifier/ConfigDef/Directive.php';
|
||||
require_once 'HTMLPurifier/ConfigDef/DirectiveAlias.php';
|
||||
|
||||
if (!defined('HTMLPURIFIER_SCHEMA_STRICT')) define('HTMLPURIFIER_SCHEMA_STRICT', false);
|
||||
|
||||
/**
|
||||
* Configuration definition, defines directives and their defaults.
|
||||
* @note If you update this, please update Printer_ConfigForm
|
||||
* @todo The ability to define things multiple times is confusing and should
|
||||
* be factored out to its own function named registerDependency() or
|
||||
* addNote(), where only the namespace.name and an extra descriptions
|
||||
* documenting the nature of the dependency are needed. Since it's
|
||||
* possible that the dependency is registered before the configuration
|
||||
* is defined, deferring it to some sort of cache until it actually
|
||||
* gets defined would be wise, keeping it opaque until it does get
|
||||
* defined. We could add a finalize() method which would cause it to
|
||||
* error out if we get a dangling dependency. It's difficult, however,
|
||||
* to know whether or not it's a dependency, or a codependency, that is
|
||||
* neither of them fully depends on it. Where does the configuration go
|
||||
* then? This could be partially resolved by allowing blanket definitions
|
||||
* and then splitting them up into finer-grained versions, however, there
|
||||
* might be implementation difficulties in ini files regarding order of
|
||||
* execution.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema {
|
||||
|
||||
@@ -33,172 +9,75 @@ class HTMLPurifier_ConfigSchema {
|
||||
* Defaults of the directives and namespaces.
|
||||
* @note This shares the exact same structure as HTMLPurifier_Config::$conf
|
||||
*/
|
||||
var $defaults = array();
|
||||
public $defaults = array();
|
||||
|
||||
/**
|
||||
* Definition of the directives.
|
||||
*/
|
||||
var $info = array();
|
||||
public $info = array();
|
||||
|
||||
/**
|
||||
* Definition of namespaces.
|
||||
* Application-wide singleton
|
||||
*/
|
||||
var $info_namespace = array();
|
||||
static protected $singleton;
|
||||
|
||||
/**
|
||||
* Lookup table of allowed types.
|
||||
* Variable parser.
|
||||
*/
|
||||
var $types = array(
|
||||
'string' => 'String',
|
||||
'istring' => 'Case-insensitive string',
|
||||
'text' => 'Text',
|
||||
'itext' => 'Case-insensitive text',
|
||||
'int' => 'Integer',
|
||||
'float' => 'Float',
|
||||
'bool' => 'Boolean',
|
||||
'lookup' => 'Lookup array',
|
||||
'list' => 'Array list',
|
||||
'hash' => 'Associative array',
|
||||
'mixed' => 'Mixed'
|
||||
);
|
||||
protected $parser;
|
||||
|
||||
public function __construct() {
|
||||
$this->parser = new HTMLPurifier_VarParser_Flexible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the default namespaces.
|
||||
* Unserializes the default ConfigSchema.
|
||||
*/
|
||||
function initialize() {
|
||||
$this->defineNamespace('Core', 'Core features that are always available.');
|
||||
$this->defineNamespace('Attr', 'Features regarding attribute validation.');
|
||||
$this->defineNamespace('URI', 'Features regarding Uniform Resource Identifiers.');
|
||||
$this->defineNamespace('HTML', 'Configuration regarding allowed HTML.');
|
||||
$this->defineNamespace('CSS', 'Configuration regarding allowed CSS.');
|
||||
$this->defineNamespace('AutoFormat', 'Configuration for activating auto-formatting functionality (also known as <code>Injector</code>s)');
|
||||
$this->defineNamespace('AutoFormatParam', 'Configuration for customizing auto-formatting functionality');
|
||||
$this->defineNamespace('Output', 'Configuration relating to the generation of (X)HTML.');
|
||||
$this->defineNamespace('Cache', 'Configuration for DefinitionCache and related subclasses.');
|
||||
$this->defineNamespace('Test', 'Developer testing configuration for our unit tests.');
|
||||
public static function makeFromSerial() {
|
||||
return unserialize(file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an instance of the application-wide configuration definition.
|
||||
* @static
|
||||
*/
|
||||
function &instance($prototype = null) {
|
||||
static $instance;
|
||||
public static function instance($prototype = null) {
|
||||
if ($prototype !== null) {
|
||||
$instance = $prototype;
|
||||
} elseif ($instance === null || $prototype === true) {
|
||||
$instance = new HTMLPurifier_ConfigSchema();
|
||||
$instance->initialize();
|
||||
HTMLPurifier_ConfigSchema::$singleton = $prototype;
|
||||
} elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) {
|
||||
HTMLPurifier_ConfigSchema::$singleton = HTMLPurifier_ConfigSchema::makeFromSerial();
|
||||
}
|
||||
return $instance;
|
||||
return HTMLPurifier_ConfigSchema::$singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a directive for configuration
|
||||
* @static
|
||||
* @warning Will fail of directive's namespace is defined
|
||||
* @warning Will fail of directive's namespace is defined.
|
||||
* @warning This method's signature is slightly different from the legacy
|
||||
* define() static method! Beware!
|
||||
* @param $namespace Namespace the directive is in
|
||||
* @param $name Key of directive
|
||||
* @param $default Default value of directive
|
||||
* @param $type Allowed type of the directive. See
|
||||
* HTMLPurifier_DirectiveDef::$type for allowed values
|
||||
* @param $description Description of directive for documentation
|
||||
* @param $allow_null Whether or not to allow null values
|
||||
*/
|
||||
function define($namespace, $name, $default, $type, $description) {
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
|
||||
// basic sanity checks
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (!isset($def->info[$namespace])) {
|
||||
trigger_error('Cannot define directive for undefined namespace',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (!ctype_alnum($name)) {
|
||||
trigger_error('Directive name must be alphanumeric',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (empty($description)) {
|
||||
trigger_error('Description must be non-empty',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($def->info[$namespace][$name])) {
|
||||
// already defined
|
||||
if (
|
||||
$def->info[$namespace][$name]->type !== $type ||
|
||||
$def->defaults[$namespace][$name] !== $default
|
||||
) {
|
||||
trigger_error('Inconsistent default or type, cannot redefine');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// needs defining
|
||||
|
||||
// process modifiers (OPTIMIZE!)
|
||||
$type_values = explode('/', $type, 2);
|
||||
$type = $type_values[0];
|
||||
$modifier = isset($type_values[1]) ? $type_values[1] : false;
|
||||
$allow_null = ($modifier === 'null');
|
||||
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (!isset($def->types[$type])) {
|
||||
trigger_error('Invalid type for configuration directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
$default = $def->validate($default, $type, $allow_null);
|
||||
if ($def->isError($default)) {
|
||||
trigger_error('Default value does not match directive type',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$def->info[$namespace][$name] =
|
||||
new HTMLPurifier_ConfigDef_Directive();
|
||||
$def->info[$namespace][$name]->type = $type;
|
||||
$def->info[$namespace][$name]->allow_null = $allow_null;
|
||||
$def->defaults[$namespace][$name] = $default;
|
||||
}
|
||||
if (!HTMLPURIFIER_SCHEMA_STRICT) return;
|
||||
$backtrace = debug_backtrace();
|
||||
$file = $def->mungeFilename($backtrace[0]['file']);
|
||||
$line = $backtrace[0]['line'];
|
||||
$def->info[$namespace][$name]->addDescription($file,$line,$description);
|
||||
public function add($namespace, $name, $default, $type, $allow_null) {
|
||||
$default = $this->parser->parse($default, $type, $allow_null);
|
||||
$this->info[$namespace][$name] = new HTMLPurifier_ConfigDef_Directive();
|
||||
$this->info[$namespace][$name]->type = $type;
|
||||
$this->info[$namespace][$name]->allow_null = $allow_null;
|
||||
$this->defaults[$namespace][$name] = $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a namespace for directives to be put into.
|
||||
* @static
|
||||
* @warning This is slightly different from the corresponding static
|
||||
* method.
|
||||
* @param $namespace Namespace's name
|
||||
* @param $description Description of the namespace
|
||||
*/
|
||||
function defineNamespace($namespace, $description) {
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (isset($def->info[$namespace])) {
|
||||
trigger_error('Cannot redefine namespace', E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (!ctype_alnum($namespace)) {
|
||||
trigger_error('Namespace name must be alphanumeric',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (empty($description)) {
|
||||
trigger_error('Description must be non-empty',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$def->info[$namespace] = array();
|
||||
$def->info_namespace[$namespace] = new HTMLPurifier_ConfigDef_Namespace();
|
||||
$def->info_namespace[$namespace]->description = $description;
|
||||
$def->defaults[$namespace] = array();
|
||||
public function addNamespace($namespace) {
|
||||
$this->info[$namespace] = array();
|
||||
$this->defaults[$namespace] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,231 +85,99 @@ class HTMLPurifier_ConfigSchema {
|
||||
*
|
||||
* Directive value aliases are convenient for developers because it lets
|
||||
* them set a directive to several values and get the same result.
|
||||
* @static
|
||||
* @param $namespace Directive's namespace
|
||||
* @param $name Name of Directive
|
||||
* @param $alias Name of aliased value
|
||||
* @param $real Value aliased value will be converted into
|
||||
* @param $aliases Hash of aliased values to the real alias
|
||||
*/
|
||||
function defineValueAliases($namespace, $name, $aliases) {
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT && !isset($def->info[$namespace][$name])) {
|
||||
trigger_error('Cannot set value alias for non-existant directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
public function addValueAliases($namespace, $name, $aliases) {
|
||||
foreach ($aliases as $alias => $real) {
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (!$def->info[$namespace][$name] !== true &&
|
||||
!isset($def->info[$namespace][$name]->allowed[$real])
|
||||
) {
|
||||
trigger_error('Cannot define alias to value that is not allowed',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (isset($def->info[$namespace][$name]->allowed[$alias])) {
|
||||
trigger_error('Cannot define alias over allowed value',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$def->info[$namespace][$name]->aliases[$alias] = $real;
|
||||
$this->info[$namespace][$name]->aliases[$alias] = $real;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a set of allowed values for a directive.
|
||||
* @static
|
||||
* @warning This is slightly different from the corresponding static
|
||||
* method definition.
|
||||
* @param $namespace Namespace of directive
|
||||
* @param $name Name of directive
|
||||
* @param $allowed_values Arraylist of allowed values
|
||||
* @param $allowed Lookup array of allowed values
|
||||
*/
|
||||
function defineAllowedValues($namespace, $name, $allowed_values) {
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT && !isset($def->info[$namespace][$name])) {
|
||||
trigger_error('Cannot define allowed values for undefined directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
$directive =& $def->info[$namespace][$name];
|
||||
$type = $directive->type;
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT && $type != 'string' && $type != 'istring') {
|
||||
trigger_error('Cannot define allowed values for directive whose type is not string',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if ($directive->allowed === true) {
|
||||
$directive->allowed = array();
|
||||
}
|
||||
foreach ($allowed_values as $value) {
|
||||
$directive->allowed[$value] = true;
|
||||
}
|
||||
if (
|
||||
HTMLPURIFIER_SCHEMA_STRICT &&
|
||||
$def->defaults[$namespace][$name] !== null &&
|
||||
!isset($directive->allowed[$def->defaults[$namespace][$name]])
|
||||
) {
|
||||
trigger_error('Default value must be in allowed range of variables',
|
||||
E_USER_ERROR);
|
||||
$directive->allowed = true; // undo undo!
|
||||
return;
|
||||
}
|
||||
public function addAllowedValues($namespace, $name, $allowed) {
|
||||
$type = $this->info[$namespace][$name]->type;
|
||||
$this->info[$namespace][$name]->allowed = $allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a directive alias for backwards compatibility
|
||||
* @static
|
||||
* @param $namespace
|
||||
* @param $name Directive that will be aliased
|
||||
* @param $new_namespace
|
||||
* @param $new_name Directive that the alias will be to
|
||||
*/
|
||||
function defineAlias($namespace, $name, $new_namespace, $new_name) {
|
||||
$def =& HTMLPurifier_ConfigSchema::instance();
|
||||
if (HTMLPURIFIER_SCHEMA_STRICT) {
|
||||
if (!isset($def->info[$namespace])) {
|
||||
trigger_error('Cannot define directive alias in undefined namespace',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (!ctype_alnum($name)) {
|
||||
trigger_error('Directive name must be alphanumeric',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (isset($def->info[$namespace][$name])) {
|
||||
trigger_error('Cannot define alias over directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if (!isset($def->info[$new_namespace][$new_name])) {
|
||||
trigger_error('Cannot define alias to undefined directive',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if ($def->info[$new_namespace][$new_name]->class == 'alias') {
|
||||
trigger_error('Cannot define alias to alias',
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
public function addAlias($namespace, $name, $new_namespace, $new_name) {
|
||||
$this->info[$namespace][$name] = new HTMLPurifier_ConfigDef_DirectiveAlias($new_namespace, $new_name);
|
||||
}
|
||||
|
||||
// DEPRECATED METHODS
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->set() */
|
||||
public static function define($namespace, $name, $default, $type, $description) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
// process modifiers (OPTIMIZE!)
|
||||
$type_values = explode('/', $type, 2);
|
||||
$type = $type_values[0];
|
||||
$modifier = isset($type_values[1]) ? $type_values[1] : false;
|
||||
$allow_null = ($modifier === 'null');
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->add($namespace, $name, $default, $type, $allow_null);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addNamespace() */
|
||||
public static function defineNamespace($namespace, $description) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addNamespace($namespace);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addValueAliases() */
|
||||
public static function defineValueAliases($namespace, $name, $aliases) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addValueAliases($namespace, $name, $aliases);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addAllowedValues() */
|
||||
public static function defineAllowedValues($namespace, $name, $allowed_values) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$allowed = array();
|
||||
foreach ($allowed_values as $value) {
|
||||
$allowed[$value] = true;
|
||||
}
|
||||
$def->info[$namespace][$name] =
|
||||
new HTMLPurifier_ConfigDef_DirectiveAlias(
|
||||
$new_namespace, $new_name);
|
||||
$def->info[$new_namespace][$new_name]->directiveAliases[] = "$namespace.$name";
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addAllowedValues($namespace, $name, $allowed);
|
||||
}
|
||||
|
||||
/** @see HTMLPurifier_ConfigSchema->addAlias() */
|
||||
public static function defineAlias($namespace, $name, $new_namespace, $new_name) {
|
||||
HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
|
||||
$def = HTMLPurifier_ConfigSchema::instance();
|
||||
$def->addAlias($namespace, $name, $new_namespace, $new_name);
|
||||
}
|
||||
|
||||
/** @deprecated, use HTMLPurifier_VarParser->parse() */
|
||||
public function validate($a, $b, $c = false) {
|
||||
trigger_error("HTMLPurifier_ConfigSchema->validate deprecated, use HTMLPurifier_VarParser->parse instead", E_USER_NOTICE);
|
||||
return $this->parser->parse($a, $b, $c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a variable according to type. Return null if invalid.
|
||||
* Throws an E_USER_NOTICE stating that a method is deprecated.
|
||||
*/
|
||||
function validate($var, $type, $allow_null = false) {
|
||||
if (!isset($this->types[$type])) {
|
||||
trigger_error('Invalid type', E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
if ($allow_null && $var === null) return null;
|
||||
switch ($type) {
|
||||
case 'mixed':
|
||||
//if (is_string($var)) $var = unserialize($var);
|
||||
return $var;
|
||||
case 'istring':
|
||||
case 'string':
|
||||
case 'text': // no difference, just is longer/multiple line string
|
||||
case 'itext':
|
||||
if (!is_string($var)) break;
|
||||
if ($type === 'istring' || $type === 'itext') $var = strtolower($var);
|
||||
return $var;
|
||||
case 'int':
|
||||
if (is_string($var) && ctype_digit($var)) $var = (int) $var;
|
||||
elseif (!is_int($var)) break;
|
||||
return $var;
|
||||
case 'float':
|
||||
if (is_string($var) && is_numeric($var)) $var = (float) $var;
|
||||
elseif (!is_float($var)) break;
|
||||
return $var;
|
||||
case 'bool':
|
||||
if (is_int($var) && ($var === 0 || $var === 1)) {
|
||||
$var = (bool) $var;
|
||||
} elseif (is_string($var)) {
|
||||
if ($var == 'on' || $var == 'true' || $var == '1') {
|
||||
$var = true;
|
||||
} elseif ($var == 'off' || $var == 'false' || $var == '0') {
|
||||
$var = false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} elseif (!is_bool($var)) break;
|
||||
return $var;
|
||||
case 'list':
|
||||
case 'hash':
|
||||
case 'lookup':
|
||||
if (is_string($var)) {
|
||||
// special case: technically, this is an array with
|
||||
// a single empty string item, but having an empty
|
||||
// array is more intuitive
|
||||
if ($var == '') return array();
|
||||
if (strpos($var, "\n") === false && strpos($var, "\r") === false) {
|
||||
// simplistic string to array method that only works
|
||||
// for simple lists of tag names or alphanumeric characters
|
||||
$var = explode(',',$var);
|
||||
} else {
|
||||
$var = preg_split('/(,|[\n\r]+)/', $var);
|
||||
}
|
||||
// remove spaces
|
||||
foreach ($var as $i => $j) $var[$i] = trim($j);
|
||||
if ($type === 'hash') {
|
||||
// key:value,key2:value2
|
||||
$nvar = array();
|
||||
foreach ($var as $keypair) {
|
||||
$c = explode(':', $keypair, 2);
|
||||
if (!isset($c[1])) continue;
|
||||
$nvar[$c[0]] = $c[1];
|
||||
}
|
||||
$var = $nvar;
|
||||
}
|
||||
}
|
||||
if (!is_array($var)) break;
|
||||
$keys = array_keys($var);
|
||||
if ($keys === array_keys($keys)) {
|
||||
if ($type == 'list') return $var;
|
||||
elseif ($type == 'lookup') {
|
||||
$new = array();
|
||||
foreach ($var as $key) {
|
||||
$new[$key] = true;
|
||||
}
|
||||
return $new;
|
||||
} else break;
|
||||
}
|
||||
if ($type === 'lookup') {
|
||||
foreach ($var as $key => $value) {
|
||||
$var[$key] = true;
|
||||
}
|
||||
}
|
||||
return $var;
|
||||
}
|
||||
$error = new HTMLPurifier_Error();
|
||||
return $error;
|
||||
private static function deprecated($method) {
|
||||
trigger_error("Static HTMLPurifier_ConfigSchema::$method deprecated, use add*() method instead", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an absolute path and munges it into a more manageable relative path
|
||||
*/
|
||||
function mungeFilename($filename) {
|
||||
if (!HTMLPURIFIER_SCHEMA_STRICT) return $filename;
|
||||
$offset = strrpos($filename, 'HTMLPurifier');
|
||||
$filename = substr($filename, $offset);
|
||||
$filename = str_replace('\\', '/', $filename);
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if var is an HTMLPurifier_Error object
|
||||
*/
|
||||
function isError($var) {
|
||||
if (!is_object($var)) return false;
|
||||
if (!is_a($var, 'HTMLPurifier_Error')) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Converts HTMLPurifier_ConfigSchema_Interchange to our runtime
|
||||
* representation used to perform checks on user configuration.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Builder_ConfigSchema
|
||||
{
|
||||
|
||||
public function build($interchange) {
|
||||
$schema = new HTMLPurifier_ConfigSchema();
|
||||
foreach ($interchange->namespaces as $n) {
|
||||
$schema->addNamespace($n->namespace);
|
||||
}
|
||||
foreach ($interchange->directives as $d) {
|
||||
$schema->add(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->default,
|
||||
$d->type,
|
||||
$d->typeAllowsNull
|
||||
);
|
||||
if ($d->allowed !== null) {
|
||||
$schema->addAllowedValues(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->allowed
|
||||
);
|
||||
}
|
||||
foreach ($d->aliases as $alias) {
|
||||
$schema->addAlias(
|
||||
$alias->namespace,
|
||||
$alias->directive,
|
||||
$d->id->namespace,
|
||||
$d->id->directive
|
||||
);
|
||||
}
|
||||
if ($d->valueAliases !== null) {
|
||||
$schema->addValueAliases(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->valueAliases
|
||||
);
|
||||
}
|
||||
}
|
||||
return $schema;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Converts HTMLPurifier_ConfigSchema_Interchange to an XML format,
|
||||
* which can be further processed to generate documentation.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
|
||||
{
|
||||
|
||||
protected $interchange;
|
||||
|
||||
protected function writeHTMLDiv($html) {
|
||||
$this->startElement('div');
|
||||
|
||||
$purifier = HTMLPurifier::getInstance();
|
||||
$html = $purifier->purify($html);
|
||||
$this->writeAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
|
||||
$this->writeRaw($html);
|
||||
|
||||
$this->endElement(); // div
|
||||
}
|
||||
|
||||
protected function export($var) {
|
||||
if ($var === array()) return 'array()';
|
||||
return var_export($var, true);
|
||||
}
|
||||
|
||||
public function build($interchange) {
|
||||
// global access, only use as last resort
|
||||
$this->interchange = $interchange;
|
||||
|
||||
$this->setIndent(true);
|
||||
$this->startDocument('1.0', 'UTF-8');
|
||||
$this->startElement('configdoc');
|
||||
$this->writeElement('title', $interchange->name);
|
||||
|
||||
foreach ($interchange->namespaces as $namespace) {
|
||||
$this->buildNamespace($namespace);
|
||||
}
|
||||
|
||||
$this->endElement(); // configdoc
|
||||
$this->flush();
|
||||
}
|
||||
|
||||
public function buildNamespace($namespace) {
|
||||
$this->startElement('namespace');
|
||||
$this->writeAttribute('id', $namespace->namespace);
|
||||
|
||||
$this->writeElement('name', $namespace->namespace);
|
||||
$this->startElement('description');
|
||||
$this->writeHTMLDiv($namespace->description);
|
||||
$this->endElement(); // description
|
||||
|
||||
foreach ($this->interchange->directives as $directive) {
|
||||
if ($directive->id->namespace !== $namespace->namespace) continue;
|
||||
$this->buildDirective($directive);
|
||||
}
|
||||
|
||||
$this->endElement(); // namespace
|
||||
}
|
||||
|
||||
public function buildDirective($directive) {
|
||||
$this->startElement('directive');
|
||||
$this->writeAttribute('id', $directive->id->toString());
|
||||
|
||||
$this->writeElement('name', $directive->id->directive);
|
||||
|
||||
$this->startElement('aliases');
|
||||
foreach ($directive->aliases as $alias) $this->writeElement('alias', $alias->toString());
|
||||
$this->endElement(); // aliases
|
||||
|
||||
$this->startElement('constraints');
|
||||
if ($directive->version) $this->writeElement('version', $directive->version);
|
||||
$this->startElement('type');
|
||||
if ($directive->typeAllowsNull) $this->writeAttribute('allow-null', 'yes');
|
||||
$this->text($directive->type);
|
||||
$this->endElement(); // type
|
||||
if ($directive->allowed) {
|
||||
$this->startElement('allowed');
|
||||
foreach ($directive->allowed as $value => $x) $this->writeElement('value', $value);
|
||||
$this->endElement(); // allowed
|
||||
}
|
||||
$this->writeElement('default', $this->export($directive->default));
|
||||
$this->writeAttribute('xml:space', 'preserve');
|
||||
if ($directive->external) {
|
||||
$this->startElement('external');
|
||||
foreach ($directive->external as $project) $this->writeElement('project', $project);
|
||||
$this->endElement();
|
||||
}
|
||||
$this->endElement(); // constraints
|
||||
|
||||
if ($directive->deprecatedVersion) {
|
||||
$this->startElement('deprecated');
|
||||
$this->writeElement('version', $directive->deprecatedVersion);
|
||||
$this->writeElement('use', $directive->deprecatedUse->toString());
|
||||
$this->endElement(); // deprecated
|
||||
}
|
||||
|
||||
$this->startElement('description');
|
||||
$this->writeHTMLDiv($directive->description);
|
||||
$this->endElement(); // description
|
||||
|
||||
$this->endElement(); // directive
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Exceptions related to configuration schema
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Exception extends HTMLPurifier_Exception
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Generic schema interchange format that can be converted to a runtime
|
||||
* representation (HTMLPurifier_ConfigSchema) or HTML documentation. Members
|
||||
* are completely validated.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange
|
||||
{
|
||||
|
||||
/**
|
||||
* Name of the application this schema is describing.
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Array of Namespace ID => array(namespace info)
|
||||
*/
|
||||
public $namespaces = array();
|
||||
|
||||
/**
|
||||
* Array of Directive ID => array(directive info)
|
||||
*/
|
||||
public $directives = array();
|
||||
|
||||
/**
|
||||
* Adds a namespace array to $namespaces
|
||||
*/
|
||||
public function addNamespace($namespace) {
|
||||
if (isset($this->namespaces[$i = $namespace->namespace])) {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine namespace '$i'");
|
||||
}
|
||||
$this->namespaces[$i] = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a directive array to $directives
|
||||
*/
|
||||
public function addDirective($directive) {
|
||||
if (isset($this->directives[$i = $directive->id->toString()])) {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine directive '$i'");
|
||||
}
|
||||
$this->directives[$i] = $directive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to perform standard validation. Throws exception
|
||||
* on failed validation.
|
||||
*/
|
||||
public function validate() {
|
||||
$validator = new HTMLPurifier_ConfigSchema_Validator();
|
||||
return $validator->validate($this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interchange component class describing configuration directives.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Directive
|
||||
{
|
||||
|
||||
/**
|
||||
* ID of directive, instance of HTMLPurifier_ConfigSchema_Interchange_Id.
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* String type, e.g. 'integer' or 'istring'.
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* Default value, e.g. 3 or 'DefaultVal'.
|
||||
*/
|
||||
public $default;
|
||||
|
||||
/**
|
||||
* HTML description.
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* Boolean whether or not null is allowed as a value.
|
||||
*/
|
||||
public $typeAllowsNull = false;
|
||||
|
||||
/**
|
||||
* Lookup table of allowed scalar values, e.g. array('allowed' => true).
|
||||
* Null if all values are allowed.
|
||||
*/
|
||||
public $allowed;
|
||||
|
||||
/**
|
||||
* List of aliases for the directive,
|
||||
* e.g. array(new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir'))).
|
||||
*/
|
||||
public $aliases = array();
|
||||
|
||||
/**
|
||||
* Hash of value aliases, e.g. array('alt' => 'real'). Null if value
|
||||
* aliasing is disabled (necessary for non-scalar types).
|
||||
*/
|
||||
public $valueAliases;
|
||||
|
||||
/**
|
||||
* Version of HTML Purifier the directive was introduced, e.g. '1.3.1'.
|
||||
* Null if the directive has always existed.
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* ID of directive that supercedes this old directive, is an instance
|
||||
* of HTMLPurifier_ConfigSchema_Interchange_Id. Null if not deprecated.
|
||||
*/
|
||||
public $deprecatedUse;
|
||||
|
||||
/**
|
||||
* Version of HTML Purifier this directive was deprecated. Null if not
|
||||
* deprecated.
|
||||
*/
|
||||
public $deprecatedVersion;
|
||||
|
||||
/**
|
||||
* List of external projects this directive depends on, e.g. array('CSSTidy').
|
||||
*/
|
||||
public $external = array();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Represents a directive ID in the interchange format.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Id
|
||||
{
|
||||
|
||||
public $namespace, $directive;
|
||||
|
||||
public function __construct($namespace, $directive) {
|
||||
$this->namespace = $namespace;
|
||||
$this->directive = $directive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning This is NOT magic, to ensure that people don't abuse SPL and
|
||||
* cause problems for PHP 5.0 support.
|
||||
*/
|
||||
public function toString() {
|
||||
return $this->namespace . '.' . $this->directive;
|
||||
}
|
||||
|
||||
public static function make($id) {
|
||||
list($namespace, $directive) = explode('.', $id);
|
||||
return new HTMLPurifier_ConfigSchema_Interchange_Id($namespace, $directive);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interchange component class describing namespaces.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* Name of namespace defined.
|
||||
*/
|
||||
public $namespace;
|
||||
|
||||
/**
|
||||
* HTML description.
|
||||
*/
|
||||
public $description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
class HTMLPurifier_ConfigSchema_InterchangeBuilder
|
||||
{
|
||||
|
||||
/**
|
||||
* Used for processing DEFAULT, nothing else.
|
||||
*/
|
||||
protected $varParser;
|
||||
|
||||
public function __construct($varParser = null) {
|
||||
$this->varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native();
|
||||
}
|
||||
|
||||
public static function buildFromDirectory($dir = null) {
|
||||
$parser = new HTMLPurifier_StringHashParser();
|
||||
$builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder();
|
||||
$interchange = new HTMLPurifier_ConfigSchema_Interchange();
|
||||
|
||||
if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema/';
|
||||
$info = parse_ini_file($dir . 'info.ini');
|
||||
$interchange->name = $info['name'];
|
||||
|
||||
$files = array();
|
||||
$dh = opendir($dir);
|
||||
while (false !== ($file = readdir($dh))) {
|
||||
if (!$file || $file[0] == '.' || strrchr($file, '.') !== '.txt') {
|
||||
continue;
|
||||
}
|
||||
$files[] = $file;
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
sort($files);
|
||||
foreach ($files as $file) {
|
||||
$builder->build(
|
||||
$interchange,
|
||||
new HTMLPurifier_StringHash( $parser->parseFile($dir . $file) )
|
||||
);
|
||||
}
|
||||
|
||||
return $interchange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an interchange object based on a hash.
|
||||
* @param $interchange HTMLPurifier_ConfigSchema_Interchange object to build
|
||||
* @param $hash HTMLPurifier_ConfigSchema_StringHash source data
|
||||
*/
|
||||
public function build($interchange, $hash) {
|
||||
if (!$hash instanceof HTMLPurifier_StringHash) {
|
||||
$hash = new HTMLPurifier_StringHash($hash);
|
||||
}
|
||||
if (!isset($hash['ID'])) {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID');
|
||||
}
|
||||
if (strpos($hash['ID'], '.') === false) {
|
||||
$this->buildNamespace($interchange, $hash);
|
||||
} else {
|
||||
$this->buildDirective($interchange, $hash);
|
||||
}
|
||||
$this->_findUnused($hash);
|
||||
}
|
||||
|
||||
public function buildNamespace($interchange, $hash) {
|
||||
$namespace = new HTMLPurifier_ConfigSchema_Interchange_Namespace();
|
||||
$namespace->namespace = $hash->offsetGet('ID');
|
||||
if (isset($hash['DESCRIPTION'])) {
|
||||
$namespace->description = $hash->offsetGet('DESCRIPTION');
|
||||
}
|
||||
$interchange->addNamespace($namespace);
|
||||
}
|
||||
|
||||
public function buildDirective($interchange, $hash) {
|
||||
$directive = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
||||
|
||||
// These are required elements:
|
||||
$directive->id = $this->id($hash->offsetGet('ID'));
|
||||
$id = $directive->id->toString(); // convenience
|
||||
|
||||
if (isset($hash['TYPE'])) {
|
||||
$type = explode('/', $hash->offsetGet('TYPE'));
|
||||
if (isset($type[1])) $directive->typeAllowsNull = true;
|
||||
$directive->type = $type[0];
|
||||
} else {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined");
|
||||
}
|
||||
|
||||
if (isset($hash['DEFAULT'])) {
|
||||
try {
|
||||
$directive->default = $this->varParser->parse($hash->offsetGet('DEFAULT'), $directive->type, $directive->typeAllowsNull);
|
||||
} catch (HTMLPurifier_VarParserException $e) {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'");
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($hash['DESCRIPTION'])) {
|
||||
$directive->description = $hash->offsetGet('DESCRIPTION');
|
||||
}
|
||||
|
||||
if (isset($hash['ALLOWED'])) {
|
||||
$directive->allowed = $this->lookup($this->evalArray($hash->offsetGet('ALLOWED')));
|
||||
}
|
||||
|
||||
if (isset($hash['VALUE-ALIASES'])) {
|
||||
$directive->valueAliases = $this->evalArray($hash->offsetGet('VALUE-ALIASES'));
|
||||
}
|
||||
|
||||
if (isset($hash['ALIASES'])) {
|
||||
$raw_aliases = trim($hash->offsetGet('ALIASES'));
|
||||
$aliases = preg_split('/\s*,\s*/', $raw_aliases);
|
||||
foreach ($aliases as $alias) {
|
||||
$directive->aliases[] = $this->id($alias);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($hash['VERSION'])) {
|
||||
$directive->version = $hash->offsetGet('VERSION');
|
||||
}
|
||||
|
||||
if (isset($hash['DEPRECATED-USE'])) {
|
||||
$directive->deprecatedUse = $this->id($hash->offsetGet('DEPRECATED-USE'));
|
||||
}
|
||||
|
||||
if (isset($hash['DEPRECATED-VERSION'])) {
|
||||
$directive->deprecatedVersion = $hash->offsetGet('DEPRECATED-VERSION');
|
||||
}
|
||||
|
||||
if (isset($hash['EXTERNAL'])) {
|
||||
$directive->external = preg_split('/\s*,\s*/', trim($hash->offsetGet('EXTERNAL')));
|
||||
}
|
||||
|
||||
$interchange->addDirective($directive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates an array PHP code string without array() wrapper
|
||||
*/
|
||||
protected function evalArray($contents) {
|
||||
return eval('return array('. $contents .');');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array list into a lookup array.
|
||||
*/
|
||||
protected function lookup($array) {
|
||||
$ret = array();
|
||||
foreach ($array as $val) $ret[$val] = true;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function that creates an HTMLPurifier_ConfigSchema_Interchange_Id
|
||||
* object based on a string Id.
|
||||
*/
|
||||
protected function id($id) {
|
||||
return HTMLPurifier_ConfigSchema_Interchange_Id::make($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers errors for any unused keys passed in the hash; such keys
|
||||
* may indicate typos, missing values, etc.
|
||||
* @param $hash Instance of ConfigSchema_StringHash to check.
|
||||
*/
|
||||
protected function _findUnused($hash) {
|
||||
$accessed = $hash->getAccessed();
|
||||
foreach ($hash as $k => $v) {
|
||||
if (!isset($accessed[$k])) {
|
||||
trigger_error("String hash key '$k' not used by builder", E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Performs validations on HTMLPurifier_ConfigSchema_Interchange
|
||||
*
|
||||
* @note If you see '// handled by InterchangeBuilder', that means a
|
||||
* design decision in that class would prevent this validation from
|
||||
* ever being necessary. We have them anyway, however, for
|
||||
* redundancy.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Validator
|
||||
{
|
||||
|
||||
/**
|
||||
* Easy to access global objects.
|
||||
*/
|
||||
protected $interchange, $aliases;
|
||||
|
||||
/**
|
||||
* Context-stack to provide easy to read error messages.
|
||||
*/
|
||||
protected $context = array();
|
||||
|
||||
/**
|
||||
* HTMLPurifier_VarParser to test default's type.
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
public function __construct() {
|
||||
$this->parser = new HTMLPurifier_VarParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a fully-formed interchange object. Throws an
|
||||
* HTMLPurifier_ConfigSchema_Exception if there's a problem.
|
||||
*/
|
||||
public function validate($interchange) {
|
||||
$this->interchange = $interchange;
|
||||
$this->aliases = array();
|
||||
// PHP is a bit lax with integer <=> string conversions in
|
||||
// arrays, so we don't use the identical !== comparison
|
||||
foreach ($interchange->namespaces as $i => $namespace) {
|
||||
if ($i != $namespace->namespace) $this->error(false, "Integrity violation: key '$i' does not match internal id '{$namespace->namespace}'");
|
||||
$this->validateNamespace($namespace);
|
||||
}
|
||||
foreach ($interchange->directives as $i => $directive) {
|
||||
$id = $directive->id->toString();
|
||||
if ($i != $id) $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'");
|
||||
$this->validateDirective($directive);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a HTMLPurifier_ConfigSchema_Interchange_Namespace object.
|
||||
*/
|
||||
public function validateNamespace($n) {
|
||||
$this->context[] = "namespace '{$n->namespace}'";
|
||||
$this->with($n, 'namespace')
|
||||
->assertNotEmpty()
|
||||
->assertAlnum(); // implicit assertIsString handled by InterchangeBuilder
|
||||
$this->with($n, 'description')
|
||||
->assertNotEmpty()
|
||||
->assertIsString(); // handled by InterchangeBuilder
|
||||
array_pop($this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a HTMLPurifier_ConfigSchema_Interchange_Id object.
|
||||
*/
|
||||
public function validateId($id) {
|
||||
$id_string = $id->toString();
|
||||
$this->context[] = "id '$id_string'";
|
||||
if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) {
|
||||
// handled by InterchangeBuilder
|
||||
$this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id');
|
||||
}
|
||||
if (!isset($this->interchange->namespaces[$id->namespace])) {
|
||||
$this->error('namespace', 'does not exist'); // assumes that the namespace was validated already
|
||||
}
|
||||
$this->with($id, 'directive')
|
||||
->assertNotEmpty()
|
||||
->assertAlnum(); // implicit assertIsString handled by InterchangeBuilder
|
||||
array_pop($this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a HTMLPurifier_ConfigSchema_Interchange_Directive object.
|
||||
*/
|
||||
public function validateDirective($d) {
|
||||
$id = $d->id->toString();
|
||||
$this->context[] = "directive '$id'";
|
||||
$this->validateId($d->id);
|
||||
|
||||
$this->with($d, 'description')
|
||||
->assertNotEmpty();
|
||||
|
||||
// BEGIN - handled by InterchangeBuilder
|
||||
$this->with($d, 'type')
|
||||
->assertNotEmpty();
|
||||
$this->with($d, 'typeAllowsNull')
|
||||
->assertIsBool();
|
||||
try {
|
||||
// This also tests validity of $d->type
|
||||
$this->parser->parse($d->default, $d->type, $d->typeAllowsNull);
|
||||
} catch (HTMLPurifier_VarParserException $e) {
|
||||
$this->error('default', 'had error: ' . $e->getMessage());
|
||||
}
|
||||
// END - handled by InterchangeBuilder
|
||||
|
||||
if (!is_null($d->allowed) || !empty($d->valueAliases)) {
|
||||
// allowed and valueAliases require that we be dealing with
|
||||
// strings, so check for that early.
|
||||
if (!isset(HTMLPurifier_VarParser::$stringTypes[$d->type])) {
|
||||
$this->error('type', 'must be a string type when used with allowed or value aliases');
|
||||
}
|
||||
}
|
||||
|
||||
$this->validateDirectiveAllowed($d);
|
||||
$this->validateDirectiveValueAliases($d);
|
||||
$this->validateDirectiveAliases($d);
|
||||
|
||||
array_pop($this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra validation if $allowed member variable of
|
||||
* HTMLPurifier_ConfigSchema_Interchange_Directive is defined.
|
||||
*/
|
||||
public function validateDirectiveAllowed($d) {
|
||||
if (is_null($d->allowed)) return;
|
||||
$this->with($d, 'allowed')
|
||||
->assertNotEmpty()
|
||||
->assertIsLookup(); // handled by InterchangeBuilder
|
||||
if (is_string($d->default) && !isset($d->allowed[$d->default])) {
|
||||
$this->error('default', 'must be an allowed value');
|
||||
}
|
||||
$this->context[] = 'allowed';
|
||||
foreach ($d->allowed as $val => $x) {
|
||||
if (!is_string($val)) $this->error("value $val", 'must be a string');
|
||||
}
|
||||
array_pop($this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra validation if $valueAliases member variable of
|
||||
* HTMLPurifier_ConfigSchema_Interchange_Directive is defined.
|
||||
*/
|
||||
public function validateDirectiveValueAliases($d) {
|
||||
if (is_null($d->valueAliases)) return;
|
||||
$this->with($d, 'valueAliases')
|
||||
->assertIsArray(); // handled by InterchangeBuilder
|
||||
$this->context[] = 'valueAliases';
|
||||
foreach ($d->valueAliases as $alias => $real) {
|
||||
if (!is_string($alias)) $this->error("alias $alias", 'must be a string');
|
||||
if (!is_string($real)) $this->error("alias target $real from alias '$alias'", 'must be a string');
|
||||
if ($alias === $real) {
|
||||
$this->error("alias '$alias'", "must not be an alias to itself");
|
||||
}
|
||||
}
|
||||
if (!is_null($d->allowed)) {
|
||||
foreach ($d->valueAliases as $alias => $real) {
|
||||
if (isset($d->allowed[$alias])) {
|
||||
$this->error("alias '$alias'", 'must not be an allowed value');
|
||||
} elseif (!isset($d->allowed[$real])) {
|
||||
$this->error("alias '$alias'", 'must be an alias to an allowed value');
|
||||
}
|
||||
}
|
||||
}
|
||||
array_pop($this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra validation if $aliases member variable of
|
||||
* HTMLPurifier_ConfigSchema_Interchange_Directive is defined.
|
||||
*/
|
||||
public function validateDirectiveAliases($d) {
|
||||
$this->with($d, 'aliases')
|
||||
->assertIsArray(); // handled by InterchangeBuilder
|
||||
$this->context[] = 'aliases';
|
||||
foreach ($d->aliases as $alias) {
|
||||
$this->validateId($alias);
|
||||
$s = $alias->toString();
|
||||
if (isset($this->interchange->directives[$s])) {
|
||||
$this->error("alias '$s'", 'collides with another directive');
|
||||
}
|
||||
if (isset($this->aliases[$s])) {
|
||||
$other_directive = $this->aliases[$s];
|
||||
$this->error("alias '$s'", "collides with alias for directive '$other_directive'");
|
||||
}
|
||||
$this->aliases[$s] = $d->id->toString();
|
||||
}
|
||||
array_pop($this->context);
|
||||
}
|
||||
|
||||
// protected helper functions
|
||||
|
||||
/**
|
||||
* Convenience function for generating HTMLPurifier_ConfigSchema_ValidatorAtom
|
||||
* for validating simple member variables of objects.
|
||||
*/
|
||||
protected function with($obj, $member) {
|
||||
return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an error, providing helpful context.
|
||||
*/
|
||||
protected function error($target, $msg) {
|
||||
if ($target !== false) $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext();
|
||||
else $prefix = ucfirst($this->getFormattedContext());
|
||||
throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted context string.
|
||||
*/
|
||||
protected function getFormattedContext() {
|
||||
return implode(' in ', array_reverse($this->context));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Fluent interface for validating the contents of member variables.
|
||||
* This should be immutable. See HTMLPurifier_ConfigSchema_Validator for
|
||||
* use-cases. We name this an 'atom' because it's ONLY for validations that
|
||||
* are independent and usually scalar.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_ValidatorAtom
|
||||
{
|
||||
|
||||
protected $context, $obj, $member, $contents;
|
||||
|
||||
public function __construct($context, $obj, $member) {
|
||||
$this->context = $context;
|
||||
$this->obj = $obj;
|
||||
$this->member = $member;
|
||||
$this->contents =& $obj->$member;
|
||||
}
|
||||
|
||||
public function assertIsString() {
|
||||
if (!is_string($this->contents)) $this->error('must be a string');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function assertIsBool() {
|
||||
if (!is_bool($this->contents)) $this->error('must be a boolean');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function assertIsArray() {
|
||||
if (!is_array($this->contents)) $this->error('must be an array');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function assertNotNull() {
|
||||
if ($this->contents === null) $this->error('must not be null');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function assertAlnum() {
|
||||
$this->assertIsString();
|
||||
if (!ctype_alnum($this->contents)) $this->error('must be alphanumeric');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function assertNotEmpty() {
|
||||
if (empty($this->contents)) $this->error('must not be empty');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function assertIsLookup() {
|
||||
$this->assertIsArray();
|
||||
foreach ($this->contents as $v) {
|
||||
if ($v !== true) $this->error('must be a lookup array');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function error($msg) {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception(ucfirst($this->member) . ' in ' . $this->context . ' ' . $msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
||||
Attr.AllowedFrameTargets
|
||||
TYPE: lookup
|
||||
DEFAULT: array()
|
||||
--DESCRIPTION--
|
||||
Lookup table of all allowed link frame targets. Some commonly used link
|
||||
targets include _blank, _self, _parent and _top. Values should be
|
||||
lowercase, as validation will be done in a case-sensitive manner despite
|
||||
W3C's recommendation. XHTML 1.0 Strict does not permit the target attribute
|
||||
so this directive will have no effect in that doctype. XHTML 1.1 does not
|
||||
enable the Target module by default, you will have to manually enable it
|
||||
(see the module documentation for more details.)
|
||||
@@ -0,0 +1,8 @@
|
||||
Attr.AllowedRel
|
||||
TYPE: lookup
|
||||
VERSION: 1.6.0
|
||||
DEFAULT: array()
|
||||
--DESCRIPTION--
|
||||
List of allowed forward document relationships in the rel attribute. Common
|
||||
values may be nofollow or print. By default, this is empty, meaning that no
|
||||
document relationships are allowed.
|
||||
@@ -0,0 +1,8 @@
|
||||
Attr.AllowedRev
|
||||
TYPE: lookup
|
||||
VERSION: 1.6.0
|
||||
DEFAULT: array()
|
||||
--DESCRIPTION--
|
||||
List of allowed reverse document relationships in the rev attribute. This
|
||||
attribute is a bit of an edge-case; if you don't know what it is for, stay
|
||||
away.
|
||||
@@ -0,0 +1,8 @@
|
||||
Attr.DefaultInvalidImage
|
||||
TYPE: string
|
||||
DEFAULT: ''
|
||||
--DESCRIPTION--
|
||||
This is the default image an img tag will be pointed to if it does not have
|
||||
a valid src attribute. In future versions, we may allow the image tag to
|
||||
be removed completely, but due to design issues, this is not possible right
|
||||
now.
|
||||
@@ -0,0 +1,7 @@
|
||||
Attr.DefaultInvalidImageAlt
|
||||
TYPE: string
|
||||
DEFAULT: 'Invalid image'
|
||||
--DESCRIPTION--
|
||||
This is the content of the alt tag of an invalid image if the user had not
|
||||
previously specified an alt attribute. It has no effect when the image is
|
||||
valid but there was no alt attribute present.
|
||||
@@ -0,0 +1,9 @@
|
||||
Attr.DefaultTextDir
|
||||
TYPE: string
|
||||
DEFAULT: 'ltr'
|
||||
--DESCRIPTION--
|
||||
Defines the default text direction (ltr or rtl) of the document being
|
||||
parsed. This generally is the same as the value of the dir attribute in
|
||||
HTML, or ltr if that is not specified.
|
||||
--ALLOWED--
|
||||
'ltr', 'rtl'
|
||||
@@ -0,0 +1,15 @@
|
||||
Attr.EnableID
|
||||
TYPE: bool
|
||||
DEFAULT: false
|
||||
VERSION: 1.2.0
|
||||
--DESCRIPTION--
|
||||
Allows the ID attribute in HTML. This is disabled by default due to the
|
||||
fact that without proper configuration user input can easily break the
|
||||
validation of a webpage by specifying an ID that is already on the
|
||||
surrounding HTML. If you don't mind throwing caution to the wind, enable
|
||||
this directive, but I strongly recommend you also consider blacklisting IDs
|
||||
you use (%Attr.IDBlacklist) or prefixing all user supplied IDs
|
||||
(%Attr.IDPrefix). When set to true HTML Purifier reverts to the behavior of
|
||||
pre-1.2.0 versions.
|
||||
--ALIASES--
|
||||
HTML.EnableAttrID
|
||||
@@ -0,0 +1,4 @@
|
||||
Attr.IDBlacklist
|
||||
TYPE: list
|
||||
DEFAULT: array()
|
||||
DESCRIPTION: Array of IDs not allowed in the document.
|
||||
@@ -0,0 +1,8 @@
|
||||
Attr.IDBlacklistRegexp
|
||||
TYPE: string/null
|
||||
VERSION: 1.6.0
|
||||
DEFAULT: NULL
|
||||
--DESCRIPTION--
|
||||
PCRE regular expression to be matched against all IDs. If the expression is
|
||||
matches, the ID is rejected. Use this with care: may cause significant
|
||||
degradation. ID matching is done after all other validation.
|
||||
@@ -0,0 +1,11 @@
|
||||
Attr.IDPrefix
|
||||
TYPE: string
|
||||
VERSION: 1.2.0
|
||||
DEFAULT: ''
|
||||
--DESCRIPTION--
|
||||
String to prefix to IDs. If you have no idea what IDs your pages may use,
|
||||
you may opt to simply add a prefix to all user-submitted ID attributes so
|
||||
that they are still usable, but will not conflict with core page IDs.
|
||||
Example: setting the directive to 'user_' will result in a user submitted
|
||||
'foo' to become 'user_foo' Be sure to set %HTML.EnableAttrID to true
|
||||
before using this.
|
||||
@@ -0,0 +1,13 @@
|
||||
Attr.IDPrefixLocal
|
||||
TYPE: string
|
||||
VERSION: 1.2.0
|
||||
DEFAULT: ''
|
||||
--DESCRIPTION--
|
||||
Temporary prefix for IDs used in conjunction with %Attr.IDPrefix. If you
|
||||
need to allow multiple sets of user content on web page, you may need to
|
||||
have a seperate prefix that changes with each iteration. This way,
|
||||
seperately submitted user content displayed on the same page doesn't
|
||||
clobber each other. Ideal values are unique identifiers for the content it
|
||||
represents (i.e. the id of the row in the database). Be sure to add a
|
||||
seperator (like an underscore) at the end. Warning: this directive will
|
||||
not work unless %Attr.IDPrefix is set to a non-empty value!
|
||||
@@ -0,0 +1,2 @@
|
||||
Attr
|
||||
DESCRIPTION: Features regarding attribute validation.
|
||||
@@ -0,0 +1,30 @@
|
||||
AutoFormat.AutoParagraph
|
||||
TYPE: bool
|
||||
VERSION: 2.0.1
|
||||
DEFAULT: false
|
||||
--DESCRIPTION--
|
||||
|
||||
<p>
|
||||
This directive turns on auto-paragraphing, where double newlines are
|
||||
converted in to paragraphs whenever possible. Auto-paragraphing:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Always applies to inline elements or text in the root node,</li>
|
||||
<li>Applies to inline elements or text with double newlines in nodes
|
||||
that allow paragraph tags,</li>
|
||||
<li>Applies to double newlines in paragraph tags</li>
|
||||
</ul>
|
||||
<p>
|
||||
<code>p</code> tags must be allowed for this directive to take effect.
|
||||
We do not use <code>br</code> tags for paragraphing, as that is
|
||||
semantically incorrect.
|
||||
</p>
|
||||
<p>
|
||||
To prevent auto-paragraphing as a content-producer, refrain from using
|
||||
double-newlines except to specify a new paragraph or in contexts where
|
||||
it has special meaning (whitespace usually has no meaning except in
|
||||
tags like <code>pre</code>, so this should not be difficult.) To prevent
|
||||
the paragraphing of inline text adjacent to block elements, wrap them
|
||||
in <code>div</code> tags (the behavior is slightly different outside of
|
||||
the root node.)
|
||||
</p>
|
||||
@@ -0,0 +1,12 @@
|
||||
AutoFormat.Custom
|
||||
TYPE: list
|
||||
VERSION: 2.0.1
|
||||
DEFAULT: array()
|
||||
--DESCRIPTION--
|
||||
|
||||
<p>
|
||||
This directive can be used to add custom auto-format injectors.
|
||||
Specify an array of injector names (class name minus the prefix)
|
||||
or concrete implementations. Injector class must exist.
|
||||
</p>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
AutoFormat.Linkify
|
||||
TYPE: bool
|
||||
VERSION: 2.0.1
|
||||
DEFAULT: false
|
||||
--DESCRIPTION--
|
||||
|
||||
<p>
|
||||
This directive turns on linkification, auto-linking http, ftp and
|
||||
https URLs. <code>a</code> tags with the <code>href</code> attribute
|
||||
must be allowed.
|
||||
</p>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user