diff --git a/backend.php b/backend.php
index cf80e0e37..9ed250cf5 100644
--- a/backend.php
+++ b/backend.php
@@ -210,6 +210,13 @@
array_push($articles, format_article($link, $id, false));
} else if ($mode == "zoom") {
array_push($articles, format_article($link, $id, false, true, true));
+ } else if ($mode == "raw") {
+ if ($_REQUEST['html']) header("Content-Type: text/html");
+
+ $article = format_article($link, $id, false);
+ print $article['id'] . "\n\n";
+ print $article['content'];
+ return;
} else {
catchupArticleById($link, $id, 0);
}
diff --git a/functions.php b/functions.php
index 8a44e8bee..f8ea2503e 100644
--- a/functions.php
+++ b/functions.php
@@ -114,9 +114,13 @@
$config = HTMLPurifier_Config::createDefault();
- $allowed = "p,a[href],i,em,b,strong,code,pre,blockquote,br,img[src|alt|title],ul,ol,li,h1,h2,h3,h4,s";
+ $allowed = "p,a[href],i,em,b,strong,code,pre,blockquote,br,img[src|alt|title],ul,ol,li,h1,h2,h3,h4,s,object[classid|type|id|name|width|height|codebase],param[name|value]";
+ $config->set('HTML.SafeObject', true);
$config->set('HTML', 'Allowed', $allowed);
+ $config->set('Output.FlashCompat', true);
+ $config->set('Attr.EnableID', true);
+
$purifier = new HTMLPurifier($config);
/**
diff --git a/lib/htmlpurifier/CREDITS b/lib/htmlpurifier/CREDITS
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/LICENSE b/lib/htmlpurifier/LICENSE
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier.auto.php b/lib/htmlpurifier/library/HTMLPurifier.auto.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier.autoload.php b/lib/htmlpurifier/library/HTMLPurifier.autoload.php
old mode 100755
new mode 100644
index 8d4017640..62da5b60d
--- a/lib/htmlpurifier/library/HTMLPurifier.autoload.php
+++ b/lib/htmlpurifier/library/HTMLPurifier.autoload.php
@@ -3,6 +3,7 @@
/**
* @file
* Convenience file that registers autoload handler for HTML Purifier.
+ * It also does some sanity checks.
*/
if (function_exists('spl_autoload_register') && function_exists('spl_autoload_unregister')) {
@@ -18,4 +19,8 @@ if (function_exists('spl_autoload_register') && function_exists('spl_autoload_un
}
}
+if (ini_get('zend.ze1_compatibility_mode')) {
+ trigger_error("HTML Purifier is not compatible with zend.ze1_compatibility_mode; please turn it off", E_USER_ERROR);
+}
+
// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier.func.php b/lib/htmlpurifier/library/HTMLPurifier.func.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier.includes.php b/lib/htmlpurifier/library/HTMLPurifier.includes.php
old mode 100755
new mode 100644
index 944f0893b..b9baf8f0a
--- a/lib/htmlpurifier/library/HTMLPurifier.includes.php
+++ b/lib/htmlpurifier/library/HTMLPurifier.includes.php
@@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
- * @version 3.3.0
+ * @version 4.3.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
@@ -98,6 +98,8 @@ require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require 'HTMLPurifier/AttrDef/CSS/URI.php';
require 'HTMLPurifier/AttrDef/HTML/Bool.php';
+require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
+require 'HTMLPurifier/AttrDef/HTML/Class.php';
require 'HTMLPurifier/AttrDef/HTML/Color.php';
require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require 'HTMLPurifier/AttrDef/HTML/ID.php';
@@ -105,7 +107,6 @@ require 'HTMLPurifier/AttrDef/HTML/Pixels.php';
require 'HTMLPurifier/AttrDef/HTML/Length.php';
require 'HTMLPurifier/AttrDef/HTML/LinkTypes.php';
require 'HTMLPurifier/AttrDef/HTML/MultiLength.php';
-require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require 'HTMLPurifier/AttrDef/URI/Email.php';
require 'HTMLPurifier/AttrDef/URI/Host.php';
require 'HTMLPurifier/AttrDef/URI/IPv4.php';
@@ -123,6 +124,8 @@ require 'HTMLPurifier/AttrTransform/Input.php';
require 'HTMLPurifier/AttrTransform/Lang.php';
require 'HTMLPurifier/AttrTransform/Length.php';
require 'HTMLPurifier/AttrTransform/Name.php';
+require 'HTMLPurifier/AttrTransform/NameSync.php';
+require 'HTMLPurifier/AttrTransform/Nofollow.php';
require 'HTMLPurifier/AttrTransform/SafeEmbed.php';
require 'HTMLPurifier/AttrTransform/SafeObject.php';
require 'HTMLPurifier/AttrTransform/SafeParam.php';
@@ -149,6 +152,7 @@ require 'HTMLPurifier/HTMLModule/Image.php';
require 'HTMLPurifier/HTMLModule/Legacy.php';
require 'HTMLPurifier/HTMLModule/List.php';
require 'HTMLPurifier/HTMLModule/Name.php';
+require 'HTMLPurifier/HTMLModule/Nofollow.php';
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
require 'HTMLPurifier/HTMLModule/Object.php';
require 'HTMLPurifier/HTMLModule/Presentation.php';
@@ -174,6 +178,7 @@ require 'HTMLPurifier/Injector/DisplayLinkURI.php';
require 'HTMLPurifier/Injector/Linkify.php';
require 'HTMLPurifier/Injector/PurifierLinkify.php';
require 'HTMLPurifier/Injector/RemoveEmpty.php';
+require 'HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
require 'HTMLPurifier/Injector/SafeObject.php';
require 'HTMLPurifier/Lexer/DOMLex.php';
require 'HTMLPurifier/Lexer/DirectLex.php';
@@ -193,9 +198,12 @@ require 'HTMLPurifier/Token/Start.php';
require 'HTMLPurifier/Token/Text.php';
require 'HTMLPurifier/URIFilter/DisableExternal.php';
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
+require 'HTMLPurifier/URIFilter/DisableResources.php';
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
require 'HTMLPurifier/URIFilter/Munge.php';
+require 'HTMLPurifier/URIScheme/data.php';
+require 'HTMLPurifier/URIScheme/file.php';
require 'HTMLPurifier/URIScheme/ftp.php';
require 'HTMLPurifier/URIScheme/http.php';
require 'HTMLPurifier/URIScheme/https.php';
diff --git a/lib/htmlpurifier/library/HTMLPurifier.kses.php b/lib/htmlpurifier/library/HTMLPurifier.kses.php
old mode 100755
new mode 100644
index 24bef74a5..3143feb17
--- a/lib/htmlpurifier/library/HTMLPurifier.kses.php
+++ b/lib/htmlpurifier/library/HTMLPurifier.kses.php
@@ -17,11 +17,11 @@ function kses($string, $allowed_html, $allowed_protocols = null) {
$allowed_attributes["$element.$attribute"] = true;
}
}
- $config->set('HTML', 'AllowedElements', $allowed_elements);
- $config->set('HTML', 'AllowedAttributes', $allowed_attributes);
+ $config->set('HTML.AllowedElements', $allowed_elements);
+ $config->set('HTML.AllowedAttributes', $allowed_attributes);
$allowed_schemes = array();
if ($allowed_protocols !== null) {
- $config->set('URI', 'AllowedSchemes', $allowed_protocols);
+ $config->set('URI.AllowedSchemes', $allowed_protocols);
}
$purifier = new HTMLPurifier($config);
return $purifier->purify($string);
diff --git a/lib/htmlpurifier/library/HTMLPurifier.path.php b/lib/htmlpurifier/library/HTMLPurifier.path.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier.php b/lib/htmlpurifier/library/HTMLPurifier.php
old mode 100755
new mode 100644
index 4b1eddecb..914ba25ae
--- a/lib/htmlpurifier/library/HTMLPurifier.php
+++ b/lib/htmlpurifier/library/HTMLPurifier.php
@@ -19,7 +19,7 @@
*/
/*
- HTML Purifier 3.3.0 - Standards Compliant HTML Filtering
+ HTML Purifier 4.3.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@@ -55,10 +55,10 @@ class HTMLPurifier
{
/** Version of HTML Purifier */
- public $version = '3.3.0';
+ public $version = '4.3.0';
/** Constant with version of HTML Purifier */
- const VERSION = '3.3.0';
+ const VERSION = '4.3.0';
/** Global configuration object */
public $config;
@@ -128,7 +128,7 @@ class HTMLPurifier
$context->register('Generator', $this->generator);
// set up global context variables
- if ($config->get('Core', 'CollectErrors')) {
+ if ($config->get('Core.CollectErrors')) {
// may get moved out if other facilities use it
$language_factory = HTMLPurifier_LanguageFactory::instance();
$language = $language_factory->create($config, $context);
@@ -152,6 +152,7 @@ class HTMLPurifier
$filters = array();
foreach ($filter_flags as $filter => $flag) {
if (!$flag) continue;
+ if (strpos($filter, '.') !== false) continue;
$class = "HTMLPurifier_Filter_$filter";
$filters[] = new $class;
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier.safe-includes.php b/lib/htmlpurifier/library/HTMLPurifier.safe-includes.php
old mode 100755
new mode 100644
index 7d393036a..a5c0d5bb8
--- a/lib/htmlpurifier/library/HTMLPurifier.safe-includes.php
+++ b/lib/htmlpurifier/library/HTMLPurifier.safe-includes.php
@@ -92,6 +92,8 @@ require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
+require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
+require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
@@ -99,7 +101,6 @@ 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';
@@ -117,6 +118,8 @@ require_once $__dir . '/HTMLPurifier/AttrTransform/Input.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
+require_once $__dir . '/HTMLPurifier/AttrTransform/NameSync.php';
+require_once $__dir . '/HTMLPurifier/AttrTransform/Nofollow.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeEmbed.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php';
@@ -143,6 +146,7 @@ require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php';
+require_once $__dir . '/HTMLPurifier/HTMLModule/Nofollow.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
@@ -168,6 +172,7 @@ require_once $__dir . '/HTMLPurifier/Injector/DisplayLinkURI.php';
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
+require_once $__dir . '/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
@@ -187,9 +192,12 @@ require_once $__dir . '/HTMLPurifier/Token/Start.php';
require_once $__dir . '/HTMLPurifier/Token/Text.php';
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternal.php';
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
+require_once $__dir . '/HTMLPurifier/URIFilter/DisableResources.php';
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
require_once $__dir . '/HTMLPurifier/URIFilter/Munge.php';
+require_once $__dir . '/HTMLPurifier/URIScheme/data.php';
+require_once $__dir . '/HTMLPurifier/URIScheme/file.php';
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrCollections.php b/lib/htmlpurifier/library/HTMLPurifier/AttrCollections.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef.php
old mode 100755
new mode 100644
index d32fa62d6..b2e4f36c5
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef.php
@@ -82,6 +82,42 @@ abstract class HTMLPurifier_AttrDef
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
}
+ /**
+ * Parses a possibly escaped CSS string and returns the "pure"
+ * version of it.
+ */
+ protected function expandCSSEscape($string) {
+ // flexibly parse it
+ $ret = '';
+ for ($i = 0, $c = strlen($string); $i < $c; $i++) {
+ if ($string[$i] === '\\') {
+ $i++;
+ if ($i >= $c) {
+ $ret .= '\\';
+ break;
+ }
+ if (ctype_xdigit($string[$i])) {
+ $code = $string[$i];
+ for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) {
+ if (!ctype_xdigit($string[$i])) break;
+ $code .= $string[$i];
+ }
+ // We have to be extremely careful when adding
+ // new characters, to make sure we're not breaking
+ // the encoding.
+ $char = HTMLPurifier_Encoder::unichr(hexdec($code));
+ if (HTMLPurifier_Encoder::cleanUTF8($char) === '') continue;
+ $ret .= $char;
+ if ($i < $c && trim($string[$i]) !== '') $i--;
+ continue;
+ }
+ if ($string[$i] === "\n") continue;
+ }
+ $ret .= $string[$i];
+ }
+ return $ret;
+ }
+
}
// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Background.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Background.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
old mode 100755
new mode 100644
index 35df3985e..fae82eaec
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
@@ -59,7 +59,8 @@ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
$keywords = array();
$keywords['h'] = false; // left, right
$keywords['v'] = false; // top, bottom
- $keywords['c'] = false; // center
+ $keywords['ch'] = false; // center (first word)
+ $keywords['cv'] = false; // center (second word)
$measures = array();
$i = 0;
@@ -79,6 +80,13 @@ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
$lbit = ctype_lower($bit) ? $bit : strtolower($bit);
if (isset($lookup[$lbit])) {
$status = $lookup[$lbit];
+ if ($status == 'c') {
+ if ($i == 0) {
+ $status = 'ch';
+ } else {
+ $status = 'cv';
+ }
+ }
$keywords[$status] = $lbit;
$i++;
}
@@ -101,20 +109,19 @@ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
if (!$i) return false; // no valid values were caught
-
$ret = array();
// first keyword
if ($keywords['h']) $ret[] = $keywords['h'];
- elseif (count($measures)) $ret[] = array_shift($measures);
- elseif ($keywords['c']) {
- $ret[] = $keywords['c'];
- $keywords['c'] = false; // prevent re-use: center = center center
+ elseif ($keywords['ch']) {
+ $ret[] = $keywords['ch'];
+ $keywords['cv'] = false; // prevent re-use: center = center center
}
+ elseif (count($measures)) $ret[] = array_shift($measures);
if ($keywords['v']) $ret[] = $keywords['v'];
+ elseif ($keywords['cv']) $ret[] = $keywords['cv'];
elseif (count($measures)) $ret[] = array_shift($measures);
- elseif ($keywords['c']) $ret[] = $keywords['c'];
if (empty($ret)) return false;
return implode(' ', $ret);
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Border.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Border.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Color.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Color.php
old mode 100755
new mode 100644
index 14c6594b6..07f95a671
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Color.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Color.php
@@ -9,7 +9,7 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
public function validate($color, $config, $context) {
static $colors = null;
- if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
+ if ($colors === null) $colors = $config->get('Core.ColorKeywords');
$color = trim($color);
if ($color === '') return false;
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Composite.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Composite.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Filter.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Filter.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Font.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Font.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/FontFamily.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/FontFamily.php
old mode 100755
new mode 100644
index 705ac893d..0d9a4e12c
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/FontFamily.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/FontFamily.php
@@ -2,11 +2,43 @@
/**
* Validates a font family list according to CSS spec
- * @todo whitelisting allowed fonts would be nice
*/
class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
{
+ protected $mask = null;
+
+ public function __construct() {
+ $this->mask = '- ';
+ for ($c = 'a'; $c <= 'z'; $c++) $this->mask .= $c;
+ for ($c = 'A'; $c <= 'Z'; $c++) $this->mask .= $c;
+ for ($c = '0'; $c <= '9'; $c++) $this->mask .= $c; // cast-y, but should be fine
+ // special bytes used by UTF-8
+ for ($i = 0x80; $i <= 0xFF; $i++) {
+ // We don't bother excluding invalid bytes in this range,
+ // because the our restriction of well-formed UTF-8 will
+ // prevent these from ever occurring.
+ $this->mask .= chr($i);
+ }
+
+ /*
+ PHP's internal strcspn implementation is
+ O(length of string * length of mask), making it inefficient
+ for large masks. However, it's still faster than
+ preg_match 8)
+ for (p = s1;;) {
+ spanp = s2;
+ do {
+ if (*spanp == c || p == s1_end) {
+ return p - s1;
+ }
+ } while (spanp++ < (s2_end - 1));
+ c = *++p;
+ }
+ */
+ // possible optimization: invert the mask.
+ }
+
public function validate($string, $config, $context) {
static $generic_names = array(
'serif' => true,
@@ -15,6 +47,7 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
'fantasy' => true,
'cursive' => true
);
+ $allowed_fonts = $config->get('CSS.AllowedFonts');
// assume that no font names contain commas in them
$fonts = explode(',', $string);
@@ -24,7 +57,9 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
if ($font === '') continue;
// match a generic name
if (isset($generic_names[$font])) {
- $final .= $font . ', ';
+ if ($allowed_fonts === null || isset($allowed_fonts[$font])) {
+ $final .= $font . ', ';
+ }
continue;
}
// match a quoted name
@@ -34,50 +69,122 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
$quote = $font[0];
if ($font[$length - 1] !== $quote) continue;
$font = substr($font, 1, $length - 2);
-
- $new_font = '';
- for ($i = 0, $c = strlen($font); $i < $c; $i++) {
- if ($font[$i] === '\\') {
- $i++;
- if ($i >= $c) {
- $new_font .= '\\';
- break;
- }
- if (ctype_xdigit($font[$i])) {
- $code = $font[$i];
- for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) {
- if (!ctype_xdigit($font[$i])) break;
- $code .= $font[$i];
- }
- // We have to be extremely careful when adding
- // new characters, to make sure we're not breaking
- // the encoding.
- $char = HTMLPurifier_Encoder::unichr(hexdec($code));
- if (HTMLPurifier_Encoder::cleanUTF8($char) === '') continue;
- $new_font .= $char;
- if ($i < $c && trim($font[$i]) !== '') $i--;
- continue;
- }
- if ($font[$i] === "\n") continue;
- }
- $new_font .= $font[$i];
- }
-
- $font = $new_font;
}
+
+ $font = $this->expandCSSEscape($font);
+
// $font is a pure representation of the font name
+ if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) {
+ continue;
+ }
+
if (ctype_alnum($font) && $font !== '') {
// very simple font, allow it in unharmed
$final .= $font . ', ';
continue;
}
- // complicated font, requires quoting
+ // bugger out on whitespace. form feed (0C) really
+ // shouldn't show up regardless
+ $font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font);
- // armor single quotes and new lines
- $font = str_replace("\\", "\\\\", $font);
- $font = str_replace("'", "\\'", $font);
+ // Here, there are various classes of characters which need
+ // to be treated differently:
+ // - Alphanumeric characters are essentially safe. We
+ // handled these above.
+ // - Spaces require quoting, though most parsers will do
+ // the right thing if there aren't any characters that
+ // can be misinterpreted
+ // - Dashes rarely occur, but they fairly unproblematic
+ // for parsing/rendering purposes.
+ // The above characters cover the majority of Western font
+ // names.
+ // - Arbitrary Unicode characters not in ASCII. Because
+ // most parsers give little thought to Unicode, treatment
+ // of these codepoints is basically uniform, even for
+ // punctuation-like codepoints. These characters can
+ // show up in non-Western pages and are supported by most
+ // major browsers, for example: "MS 明朝" is a
+ // legitimate font-name
+ // . See
+ // the CSS3 spec for more examples:
+ //
+ // You can see live samples of these on the Internet:
+ //
+ // However, most of these fonts have ASCII equivalents:
+ // for example, 'MS Mincho', and it's considered
+ // professional to use ASCII font names instead of
+ // Unicode font names. Thanks Takeshi Terada for
+ // providing this information.
+ // The following characters, to my knowledge, have not been
+ // used to name font names.
+ // - Single quote. While theoretically you might find a
+ // font name that has a single quote in its name (serving
+ // as an apostrophe, e.g. Dave's Scribble), I haven't
+ // been able to find any actual examples of this.
+ // Internet Explorer's cssText translation (which I
+ // believe is invoked by innerHTML) normalizes any
+ // quoting to single quotes, and fails to escape single
+ // quotes. (Note that this is not IE's behavior for all
+ // CSS properties, just some sort of special casing for
+ // font-family). So a single quote *cannot* be used
+ // safely in the font-family context if there will be an
+ // innerHTML/cssText translation. Note that Firefox 3.x
+ // does this too.
+ // - Double quote. In IE, these get normalized to
+ // single-quotes, no matter what the encoding. (Fun
+ // fact, in IE8, the 'content' CSS property gained
+ // support, where they special cased to preserve encoded
+ // double quotes, but still translate unadorned double
+ // quotes into single quotes.) So, because their
+ // fixpoint behavior is identical to single quotes, they
+ // cannot be allowed either. Firefox 3.x displays
+ // single-quote style behavior.
+ // - Backslashes are reduced by one (so \\ -> \) every
+ // iteration, so they cannot be used safely. This shows
+ // up in IE7, IE8 and FF3
+ // - Semicolons, commas and backticks are handled properly.
+ // - The rest of the ASCII punctuation is handled properly.
+ // We haven't checked what browsers do to unadorned
+ // versions, but this is not important as long as the
+ // browser doesn't /remove/ surrounding quotes (as IE does
+ // for HTML).
+ //
+ // With these results in hand, we conclude that there are
+ // various levels of safety:
+ // - Paranoid: alphanumeric, spaces and dashes(?)
+ // - International: Paranoid + non-ASCII Unicode
+ // - Edgy: Everything except quotes, backslashes
+ // - NoJS: Standards compliance, e.g. sod IE. Note that
+ // with some judicious character escaping (since certain
+ // types of escaping doesn't work) this is theoretically
+ // OK as long as innerHTML/cssText is not called.
+ // We believe that international is a reasonable default
+ // (that we will implement now), and once we do more
+ // extensive research, we may feel comfortable with dropping
+ // it down to edgy.
+
+ // Edgy: alphanumeric, spaces, dashes and Unicode. Use of
+ // str(c)spn assumes that the string was already well formed
+ // Unicode (which of course it is).
+ if (strspn($font, $this->mask) !== strlen($font)) {
+ continue;
+ }
+
+ // Historical:
+ // In the absence of innerHTML/cssText, these ugly
+ // transforms don't pose a security risk (as \\ and \"
+ // might--these escapes are not supported by most browsers).
+ // We could try to be clever and use single-quote wrapping
+ // when there is a double quote present, but I have choosen
+ // not to implement that. (NOTE: you can reduce the amount
+ // of escapes by one depending on what quoting style you use)
+ // $font = str_replace('\\', '\\5C ', $font);
+ // $font = str_replace('"', '\\22 ', $font);
+ // $font = str_replace("'", '\\27 ', $font);
+
+ // font possibly with spaces, requires quoting
$final .= "'$font', ";
}
$final = rtrim($final, ', ');
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Length.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Length.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/ListStyle.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/ListStyle.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Multiple.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Multiple.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Number.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Number.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Percentage.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Percentage.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/TextDecoration.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/TextDecoration.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/URI.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/URI.php
old mode 100755
new mode 100644
index 435d7930b..c2f767e57
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/URI.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/URI.php
@@ -34,20 +34,25 @@ class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI
$uri = substr($uri, 1, $new_length - 1);
}
- $keys = array( '(', ')', ',', ' ', '"', "'");
- $values = array('\\(', '\\)', '\\,', '\\ ', '\\"', "\\'");
- $uri = str_replace($values, $keys, $uri);
+ $uri = $this->expandCSSEscape($uri);
$result = parent::validate($uri, $config, $context);
if ($result === false) return false;
- // escape necessary characters according to CSS spec
- // except for the comma, none of these should appear in the
- // URI at all
- $result = str_replace($keys, $values, $result);
+ // extra sanity check; should have been done by URI
+ $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result);
- return "url($result)";
+ // suspicious characters are ()'; we're going to percent encode
+ // them for safety.
+ $result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result);
+
+ // there's an extra bug where ampersands lose their escaping on
+ // an innerHTML cycle, so a very unlucky query parameter could
+ // then change the meaning of the URL. Unfortunately, there's
+ // not much we can do about that...
+
+ return "url(\"$result\")";
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Enum.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Enum.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Bool.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Bool.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Class.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Class.php
new file mode 100644
index 000000000..370068d97
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Class.php
@@ -0,0 +1,34 @@
+getDefinition('HTML')->doctype->name;
+ if ($name == "XHTML 1.1" || $name == "XHTML 2.0") {
+ return parent::split($string, $config, $context);
+ } else {
+ return preg_split('/\s+/', $string);
+ }
+ }
+ protected function filter($tokens, $config, $context) {
+ $allowed = $config->get('Attr.AllowedClasses');
+ $forbidden = $config->get('Attr.ForbiddenClasses');
+ $ret = array();
+ foreach ($tokens as $token) {
+ if (
+ ($allowed === null || isset($allowed[$token])) &&
+ !isset($forbidden[$token]) &&
+ // We need this O(n) check because of PHP's array
+ // implementation that casts -0 to 0.
+ !in_array($token, $ret, true)
+ ) {
+ $ret[] = $token;
+ }
+ }
+ return $ret;
+ }
+}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Color.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Color.php
old mode 100755
new mode 100644
index 5311a3c61..d01e20454
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Color.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Color.php
@@ -9,7 +9,7 @@ class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef
public function validate($string, $config, $context) {
static $colors = null;
- if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
+ if ($colors === null) $colors = $config->get('Core.ColorKeywords');
$string = trim($string);
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php
old mode 100755
new mode 100644
index bd281a89f..ae6ea7c01
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php
@@ -12,7 +12,7 @@ class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum
public function __construct() {}
public function validate($string, $config, $context) {
- if ($this->valid_values === false) $this->valid_values = $config->get('Attr', 'AllowedFrameTargets');
+ if ($this->valid_values === false) $this->valid_values = $config->get('Attr.AllowedFrameTargets');
return parent::validate($string, $config, $context);
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ID.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ID.php
old mode 100755
new mode 100644
index 7c5c169c2..81d03762d
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ID.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ID.php
@@ -17,18 +17,18 @@ class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef
public function validate($id, $config, $context) {
- if (!$config->get('Attr', 'EnableID')) return false;
+ if (!$config->get('Attr.EnableID')) return false;
$id = trim($id); // trim it first
if ($id === '') return false;
- $prefix = $config->get('Attr', 'IDPrefix');
+ $prefix = $config->get('Attr.IDPrefix');
if ($prefix !== '') {
- $prefix .= $config->get('Attr', 'IDPrefixLocal');
+ $prefix .= $config->get('Attr.IDPrefixLocal');
// prevent re-appending the prefix
if (strpos($id, $prefix) !== 0) $id = $prefix . $id;
- } elseif ($config->get('Attr', 'IDPrefixLocal') !== '') {
+ } elseif ($config->get('Attr.IDPrefixLocal') !== '') {
trigger_error('%Attr.IDPrefixLocal cannot be used unless '.
'%Attr.IDPrefix is set', E_USER_WARNING);
}
@@ -51,7 +51,7 @@ class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef
$result = ($trim === '');
}
- $regexp = $config->get('Attr', 'IDBlacklistRegexp');
+ $regexp = $config->get('Attr.IDBlacklistRegexp');
if ($regexp && preg_match($regexp, $id)) {
return false;
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Length.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Length.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php
old mode 100755
new mode 100644
index 8a0da0c89..76d25ed08
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php
@@ -27,7 +27,7 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
public function validate($string, $config, $context) {
- $allowed = $config->get('Attr', $this->name);
+ $allowed = $config->get('Attr.' . $this->name);
if (empty($allowed)) return false;
$string = $this->parseCDATA($string);
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/MultiLength.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/MultiLength.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php
old mode 100755
new mode 100644
index 55035c4d0..aa34120bd
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php
@@ -2,10 +2,6 @@
/**
* Validates contents based on NMTOKENS attribute type.
- * @note The only current use for this is the class attribute in HTML
- * @note Could have some functionality factored out into Nmtoken class
- * @warning We cannot assume this class will be used only for 'class'
- * attributes. Not sure how to hook in magic behavior, then.
*/
class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
{
@@ -17,6 +13,17 @@ class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
// early abort: '' and '0' (strings that convert to false) are invalid
if (!$string) return false;
+ $tokens = $this->split($string, $config, $context);
+ $tokens = $this->filter($tokens, $config, $context);
+ if (empty($tokens)) return false;
+ return implode(' ', $tokens);
+
+ }
+
+ /**
+ * Splits a space separated list of tokens into its constituent parts.
+ */
+ protected function split($string, $config, $context) {
// OPTIMIZABLE!
// do the preg_match, capture all subpatterns for reformulation
@@ -24,23 +31,20 @@ class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
// escaping because I don't know how to do that with regexps
// and plus it would complicate optimization efforts (you never
// see that anyway).
- $matches = array();
$pattern = '/(?:(?<=\s)|\A)'. // look behind for space or string start
'((?:--|-?[A-Za-z_])[A-Za-z_\-0-9]*)'.
'(?:(?=\s)|\z)/'; // look ahead for space or string end
preg_match_all($pattern, $string, $matches);
+ return $matches[1];
+ }
- if (empty($matches[1])) return false;
-
- // reconstruct string
- $new_string = '';
- foreach ($matches[1] as $token) {
- $new_string .= $token . ' ';
- }
- $new_string = rtrim($new_string);
-
- return $new_string;
-
+ /**
+ * Template method for removing certain tokens based on arbitrary criteria.
+ * @note If we wanted to be really functional, we'd do an array_filter
+ * with a callback. But... we're not.
+ */
+ protected function filter($tokens, $config, $context) {
+ return $tokens;
}
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Pixels.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Pixels.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Integer.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Integer.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Lang.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Lang.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Switch.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Switch.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Text.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/Text.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI.php
old mode 100755
new mode 100644
index 93d2f0bbf..01a6d83e9
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI.php
@@ -25,7 +25,7 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
public function validate($uri, $config, $context) {
- if ($config->get('URI', 'Disable')) return false;
+ if ($config->get('URI.Disable')) return false;
$uri = $this->parseCDATA($uri);
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php
old mode 100755
new mode 100644
index 2156c10c6..feca469d7
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php
@@ -23,6 +23,12 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
public function validate($string, $config, $context) {
$length = strlen($string);
+ // empty hostname is OK; it's usually semantically equivalent:
+ // the default host as defined by a URI scheme is used:
+ //
+ // If the URI scheme defines a default for host, then that
+ // default applies when the host subcomponent is undefined
+ // or when the registered name is empty (zero length).
if ($string === '') return '';
if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') {
//IPv6
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv4.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv4.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv6.php b/lib/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv6.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Background.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Background.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/BdoDir.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/BdoDir.php
old mode 100755
new mode 100644
index 40310b914..4d1a05665
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/BdoDir.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/BdoDir.php
@@ -10,7 +10,7 @@ class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform
public function transform($attr, $config, $context) {
if (isset($attr['dir'])) return $attr;
- $attr['dir'] = $config->get('Attr', 'DefaultTextDir');
+ $attr['dir'] = $config->get('Attr.DefaultTextDir');
return $attr;
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/BgColor.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/BgColor.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/BoolToCSS.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/BoolToCSS.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Border.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Border.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/EnumToCSS.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/EnumToCSS.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/ImgRequired.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/ImgRequired.php
old mode 100755
new mode 100644
index 25c9403c2..7f0e4b7a5
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/ImgRequired.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/ImgRequired.php
@@ -15,21 +15,22 @@ class HTMLPurifier_AttrTransform_ImgRequired extends HTMLPurifier_AttrTransform
$src = true;
if (!isset($attr['src'])) {
- if ($config->get('Core', 'RemoveInvalidImg')) return $attr;
- $attr['src'] = $config->get('Attr', 'DefaultInvalidImage');
+ if ($config->get('Core.RemoveInvalidImg')) return $attr;
+ $attr['src'] = $config->get('Attr.DefaultInvalidImage');
$src = false;
}
if (!isset($attr['alt'])) {
if ($src) {
- $alt = $config->get('Attr', 'DefaultImageAlt');
+ $alt = $config->get('Attr.DefaultImageAlt');
if ($alt === null) {
- $attr['alt'] = basename($attr['src']);
+ // truncate if the alt is too long
+ $attr['alt'] = substr(basename($attr['src']),0,40);
} else {
$attr['alt'] = $alt;
}
} else {
- $attr['alt'] = $config->get('Attr', 'DefaultInvalidImageAlt');
+ $attr['alt'] = $config->get('Attr.DefaultInvalidImageAlt');
}
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/ImgSpace.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/ImgSpace.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Input.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Input.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Lang.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Lang.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Length.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Length.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Name.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Name.php
old mode 100755
new mode 100644
index e6f93aee3..15315bc73
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Name.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Name.php
@@ -7,6 +7,8 @@ class HTMLPurifier_AttrTransform_Name extends HTMLPurifier_AttrTransform
{
public function transform($attr, $config, $context) {
+ // Abort early if we're using relaxed definition of name
+ if ($config->get('HTML.Attr.Name.UseCDATA')) return $attr;
if (!isset($attr['name'])) return $attr;
$id = $this->confiscateAttr($attr, 'name');
if ( isset($attr['id'])) return $attr;
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/NameSync.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/NameSync.php
new file mode 100644
index 000000000..a95638c14
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/NameSync.php
@@ -0,0 +1,27 @@
+idDef = new HTMLPurifier_AttrDef_HTML_ID();
+ }
+
+ public function transform($attr, $config, $context) {
+ if (!isset($attr['name'])) return $attr;
+ $name = $attr['name'];
+ if (isset($attr['id']) && $attr['id'] === $name) return $attr;
+ $result = $this->idDef->validate($name, $config, $context);
+ if ($result === false) unset($attr['name']);
+ else $attr['name'] = $result;
+ return $attr;
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Nofollow.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Nofollow.php
new file mode 100644
index 000000000..573b42c9c
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Nofollow.php
@@ -0,0 +1,41 @@
+parser = new HTMLPurifier_URIParser();
+ }
+
+ public function transform($attr, $config, $context) {
+
+ if (!isset($attr['href'])) {
+ return $attr;
+ }
+
+ // XXX Kind of inefficient
+ $url = $this->parser->parse($attr['href']);
+ $scheme = $url->getSchemeObj($config, $context);
+
+ if (!is_null($url->host) && $scheme !== false && $scheme->browsable) {
+ if (isset($attr['rel'])) {
+ $attr['rel'] .= ' nofollow';
+ } else {
+ $attr['rel'] = 'nofollow';
+ }
+ }
+
+ return $attr;
+
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeEmbed.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeEmbed.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeObject.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeObject.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeParam.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeParam.php
old mode 100755
new mode 100644
index 94e8052a9..bd86a7455
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeParam.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeParam.php
@@ -19,6 +19,7 @@ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform
public function __construct() {
$this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded
+ $this->wmode = new HTMLPurifier_AttrDef_Enum(array('window', 'opaque', 'transparent'));
}
public function transform($attr, $config, $context) {
@@ -33,12 +34,25 @@ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform
case 'allowNetworking':
$attr['value'] = 'internal';
break;
+ case 'allowFullScreen':
+ if ($config->get('HTML.FlashAllowFullScreen')) {
+ $attr['value'] = ($attr['value'] == 'true') ? 'true' : 'false';
+ } else {
+ $attr['value'] = 'false';
+ }
+ break;
case 'wmode':
- $attr['value'] = 'window';
+ $attr['value'] = $this->wmode->validate($attr['value'], $config, $context);
break;
case 'movie':
+ case 'src':
+ $attr['name'] = "movie";
$attr['value'] = $this->uri->validate($attr['value'], $config, $context);
break;
+ case 'flashvars':
+ // we're going to allow arbitrary inputs to the SWF, on
+ // the reasoning that it could only hack the SWF, not us.
+ break;
// add other cases to support other param name/value pairs
default:
$attr['name'] = $attr['value'] = null;
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/ScriptRequired.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/ScriptRequired.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Textarea.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTransform/Textarea.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrTypes.php b/lib/htmlpurifier/library/HTMLPurifier/AttrTypes.php
old mode 100755
new mode 100644
index 6c624bb0b..fc2ea4e58
--- a/lib/htmlpurifier/library/HTMLPurifier/AttrTypes.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/AttrTypes.php
@@ -36,6 +36,9 @@ class HTMLPurifier_AttrTypes
$this->info['Charsets'] = new HTMLPurifier_AttrDef_Text();
$this->info['Character'] = new HTMLPurifier_AttrDef_Text();
+ // "proprietary" types
+ $this->info['Class'] = new HTMLPurifier_AttrDef_HTML_Class();
+
// number is really a positive integer (one or more digits)
// FIXME: ^^ not always, see start and value of list items
$this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true);
diff --git a/lib/htmlpurifier/library/HTMLPurifier/AttrValidator.php b/lib/htmlpurifier/library/HTMLPurifier/AttrValidator.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/Bootstrap.php b/lib/htmlpurifier/library/HTMLPurifier/Bootstrap.php
old mode 100755
new mode 100644
index 559f61a23..607c5b188
--- a/lib/htmlpurifier/library/HTMLPurifier/Bootstrap.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/Bootstrap.php
@@ -37,7 +37,12 @@ class HTMLPurifier_Bootstrap
public static function autoload($class) {
$file = HTMLPurifier_Bootstrap::getPath($class);
if (!$file) return false;
- require HTMLPURIFIER_PREFIX . '/' . $file;
+ // Technically speaking, it should be ok and more efficient to
+ // just do 'require', but Antonio Parraga reports that with
+ // Zend extensions such as Zend debugger and APC, this invariant
+ // may be broken. Since we have efficient alternatives, pay
+ // the cost here and avoid the bug.
+ require_once HTMLPURIFIER_PREFIX . '/' . $file;
return true;
}
@@ -65,10 +70,11 @@ class HTMLPurifier_Bootstrap
if ( ($funcs = spl_autoload_functions()) === false ) {
spl_autoload_register($autoload);
} elseif (function_exists('spl_autoload_unregister')) {
+ $buggy = version_compare(PHP_VERSION, '5.2.11', '<');
$compat = version_compare(PHP_VERSION, '5.1.2', '<=') &&
version_compare(PHP_VERSION, '5.1.0', '>=');
foreach ($funcs as $func) {
- if (is_array($func)) {
+ if ($buggy && is_array($func)) {
// :TRICKY: There are some compatibility issues and some
// places where we need to error out
$reflector = new ReflectionMethod($func[0], $func[1]);
diff --git a/lib/htmlpurifier/library/HTMLPurifier/CSSDefinition.php b/lib/htmlpurifier/library/HTMLPurifier/CSSDefinition.php
old mode 100755
new mode 100644
index 1a1805733..91619f5d3
--- a/lib/htmlpurifier/library/HTMLPurifier/CSSDefinition.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/CSSDefinition.php
@@ -154,7 +154,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('auto'))
));
- $max = $config->get('CSS', 'MaxImgLength');
+ $max = $config->get('CSS.MaxImgLength');
$this->info['width'] =
$this->info['height'] =
@@ -211,15 +211,19 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
// partial support
$this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(array('nowrap'));
- if ($config->get('CSS', 'Proprietary')) {
+ if ($config->get('CSS.Proprietary')) {
$this->doSetupProprietary($config);
}
- if ($config->get('CSS', 'AllowTricky')) {
+ if ($config->get('CSS.AllowTricky')) {
$this->doSetupTricky($config);
}
- $allow_important = $config->get('CSS', 'AllowImportant');
+ if ($config->get('CSS.Trusted')) {
+ $this->doSetupTrusted($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);
@@ -260,6 +264,23 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll'));
}
+ protected function doSetupTrusted($config) {
+ $this->info['position'] = new HTMLPurifier_AttrDef_Enum(array(
+ 'static', 'relative', 'absolute', 'fixed'
+ ));
+ $this->info['top'] =
+ $this->info['left'] =
+ $this->info['right'] =
+ $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
+ new HTMLPurifier_AttrDef_CSS_Length(),
+ new HTMLPurifier_AttrDef_CSS_Percentage(),
+ new HTMLPurifier_AttrDef_Enum(array('auto')),
+ ));
+ $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite(array(
+ new HTMLPurifier_AttrDef_Integer(),
+ new HTMLPurifier_AttrDef_Enum(array('auto')),
+ ));
+ }
/**
* Performs extra config-based processing. Based off of
@@ -272,20 +293,29 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
// setup allowed elements
$support = "(for information on implementing this, see the ".
"support forums) ";
- $allowed_attributes = $config->get('CSS', 'AllowedProperties');
- if ($allowed_attributes !== null) {
+ $allowed_properties = $config->get('CSS.AllowedProperties');
+ if ($allowed_properties !== null) {
foreach ($this->info as $name => $d) {
- if(!isset($allowed_attributes[$name])) unset($this->info[$name]);
- unset($allowed_attributes[$name]);
+ if(!isset($allowed_properties[$name])) unset($this->info[$name]);
+ unset($allowed_properties[$name]);
}
// emit errors
- foreach ($allowed_attributes as $name => $d) {
+ foreach ($allowed_properties as $name => $d) {
// :TODO: Is this htmlspecialchars() call really necessary?
$name = htmlspecialchars($name);
trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING);
}
}
+ $forbidden_properties = $config->get('CSS.ForbiddenProperties');
+ if ($forbidden_properties !== null) {
+ foreach ($this->info as $name => $d) {
+ if (isset($forbidden_properties[$name])) {
+ unset($this->info[$name]);
+ }
+ }
+ }
+
}
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ChildDef.php b/lib/htmlpurifier/library/HTMLPurifier/ChildDef.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Chameleon.php b/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Chameleon.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Custom.php b/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Custom.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Empty.php b/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Empty.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Optional.php b/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Optional.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Required.php b/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Required.php
old mode 100755
new mode 100644
index c3e748b26..4889f249b
--- a/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Required.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Required.php
@@ -59,7 +59,7 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef
$all_whitespace = true;
// some configuration
- $escape_invalid_children = $config->get('Core', 'EscapeInvalidChildren');
+ $escape_invalid_children = $config->get('Core.EscapeInvalidChildren');
// generator
$gen = new HTMLPurifier_Generator($config, $context);
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ChildDef/StrictBlockquote.php b/lib/htmlpurifier/library/HTMLPurifier/ChildDef/StrictBlockquote.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Table.php b/lib/htmlpurifier/library/HTMLPurifier/ChildDef/Table.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/Config.php b/lib/htmlpurifier/library/HTMLPurifier/Config.php
old mode 100755
new mode 100644
index f8e1f7804..b6551398f
--- a/lib/htmlpurifier/library/HTMLPurifier/Config.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/Config.php
@@ -20,7 +20,7 @@ class HTMLPurifier_Config
/**
* HTML Purifier's version
*/
- public $version = '3.3.0';
+ public $version = '4.3.0';
/**
* Bool indicator whether or not to automatically finalize
@@ -68,12 +68,31 @@ class HTMLPurifier_Config
*/
protected $plist;
+ /**
+ * Whether or not a set is taking place due to an
+ * alias lookup.
+ */
+ private $aliasMode;
+
+ /**
+ * Set to false if you do not want line and file numbers in errors
+ * (useful when unit testing). This will also compress some errors
+ * and exceptions.
+ */
+ public $chatty = true;
+
+ /**
+ * Current lock; only gets to this namespace are allowed.
+ */
+ private $lock;
+
/**
* @param $definition HTMLPurifier_ConfigSchema that defines what directives
* are allowed.
*/
- public function __construct($definition) {
- $this->plist = new HTMLPurifier_PropertyList($definition->defaultPlist);
+ public function __construct($definition, $parent = null) {
+ $parent = $parent ? $parent : $definition->defaultPlist;
+ $this->plist = new HTMLPurifier_PropertyList($parent);
$this->def = $definition; // keep a copy around for checking
$this->parser = new HTMLPurifier_VarParser_Flexible();
}
@@ -102,6 +121,16 @@ class HTMLPurifier_Config
return $ret;
}
+ /**
+ * Creates a new config object that inherits from a previous one.
+ * @param HTMLPurifier_Config $config Configuration object to inherit
+ * from.
+ * @return HTMLPurifier_Config object with $config as its parent.
+ */
+ public static function inherit(HTMLPurifier_Config $config) {
+ return new HTMLPurifier_Config($config->def, $config->plist);
+ }
+
/**
* Convenience constructor that creates a default configuration object.
* @return Default HTMLPurifier_Config object.
@@ -114,24 +143,34 @@ class HTMLPurifier_Config
/**
* Retreives a value from the configuration.
- * @param $namespace String namespace
* @param $key String key
*/
- public function get($namespace, $key) {
- if (!$this->finalized) $this->autoFinalize ? $this->finalize() : $this->plist->squash(true);
- if (!isset($this->def->info[$namespace][$key])) {
+ public function get($key, $a = null) {
+ if ($a !== null) {
+ $this->triggerError("Using deprecated API: use \$config->get('$key.$a') instead", E_USER_WARNING);
+ $key = "$key.$a";
+ }
+ if (!$this->finalized) $this->autoFinalize();
+ if (!isset($this->def->info[$key])) {
// can't add % due to SimpleTest bug
- trigger_error('Cannot retrieve value of undefined directive ' . htmlspecialchars("$namespace.$key"),
+ $this->triggerError('Cannot retrieve value of undefined directive ' . htmlspecialchars($key),
E_USER_WARNING);
return;
}
- if (isset($this->def->info[$namespace][$key]->isAlias)) {
- $d = $this->def->info[$namespace][$key];
- trigger_error('Cannot get value from aliased directive, use real name ' . $d->namespace . '.' . $d->name,
+ if (isset($this->def->info[$key]->isAlias)) {
+ $d = $this->def->info[$key];
+ $this->triggerError('Cannot get value from aliased directive, use real name ' . $d->key,
E_USER_ERROR);
return;
}
- return $this->plist->get("$namespace.$key");
+ if ($this->lock) {
+ list($ns) = explode('.', $key);
+ if ($ns !== $this->lock) {
+ $this->triggerError('Cannot get value of namespace ' . $ns . ' when lock for ' . $this->lock . ' is active, this probably indicates a Definition setup method is accessing directives that are not within its namespace', E_USER_ERROR);
+ return;
+ }
+ }
+ return $this->plist->get($key);
}
/**
@@ -139,13 +178,13 @@ class HTMLPurifier_Config
* @param $namespace String namespace
*/
public function getBatch($namespace) {
- if (!$this->finalized) $this->autoFinalize ? $this->finalize() : $this->plist->squash(true);
- if (!isset($this->def->info[$namespace])) {
- trigger_error('Cannot retrieve undefined namespace ' . htmlspecialchars($namespace),
+ if (!$this->finalized) $this->autoFinalize();
+ $full = $this->getAll();
+ if (!isset($full[$namespace])) {
+ $this->triggerError('Cannot retrieve undefined namespace ' . htmlspecialchars($namespace),
E_USER_WARNING);
return;
}
- $full = $this->getAll();
return $full[$namespace];
}
@@ -178,9 +217,10 @@ class HTMLPurifier_Config
/**
* Retrieves all directives, organized by namespace
+ * @warning This is a pretty inefficient function, avoid if you can
*/
public function getAll() {
- if (!$this->finalized) $this->autoFinalize ? $this->finalize() : $this->plist->squash(true);
+ if (!$this->finalized) $this->autoFinalize();
$ret = array();
foreach ($this->plist->squash() as $name => $value) {
list($ns, $key) = explode('.', $name, 2);
@@ -191,29 +231,37 @@ class HTMLPurifier_Config
/**
* Sets a value to configuration.
- * @param $namespace String namespace
* @param $key String key
* @param $value Mixed value
*/
- public function set($namespace, $key, $value, $from_alias = false) {
+ public function set($key, $value, $a = null) {
+ if (strpos($key, '.') === false) {
+ $namespace = $key;
+ $directive = $value;
+ $value = $a;
+ $key = "$key.$directive";
+ $this->triggerError("Using deprecated API: use \$config->set('$key', ...) instead", E_USER_NOTICE);
+ } else {
+ list($namespace) = explode('.', $key);
+ }
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',
+ if (!isset($this->def->info[$key])) {
+ $this->triggerError('Cannot set undefined directive ' . htmlspecialchars($key) . ' to value',
E_USER_WARNING);
return;
}
- $def = $this->def->info[$namespace][$key];
+ $def = $this->def->info[$key];
if (isset($def->isAlias)) {
- if ($from_alias) {
- trigger_error('Double-aliases not allowed, please fix '.
- 'ConfigSchema bug with' . "$namespace.$key", E_USER_ERROR);
+ if ($this->aliasMode) {
+ $this->triggerError('Double-aliases not allowed, please fix '.
+ 'ConfigSchema bug with' . $key, E_USER_ERROR);
return;
}
- $this->set($new_ns = $def->namespace,
- $new_dir = $def->name,
- $value, true);
- trigger_error("$namespace.$key is an alias, preferred directive name is $new_ns.$new_dir", E_USER_NOTICE);
+ $this->aliasMode = true;
+ $this->set($def->key, $value);
+ $this->aliasMode = false;
+ $this->triggerError("$key is an alias, preferred directive name is {$def->key}", E_USER_NOTICE);
return;
}
@@ -231,7 +279,7 @@ class HTMLPurifier_Config
try {
$value = $this->parser->parse($value, $type, $allow_null);
} catch (HTMLPurifier_VarParserException $e) {
- trigger_error('Value for ' . "$namespace.$key" . ' is of invalid type, should be ' . HTMLPurifier_VarParser::getTypeName($type), E_USER_WARNING);
+ $this->triggerError('Value for ' . $key . ' is of invalid type, should be ' . HTMLPurifier_VarParser::getTypeName($type), E_USER_WARNING);
return;
}
if (is_string($value) && is_object($def)) {
@@ -241,17 +289,17 @@ class HTMLPurifier_Config
}
// check to see if the value is allowed
if (isset($def->allowed) && !isset($def->allowed[$value])) {
- trigger_error('Value not supported, valid values are: ' .
+ $this->triggerError('Value not supported, valid values are: ' .
$this->_listify($def->allowed), E_USER_WARNING);
return;
}
}
- $this->plist->set("$namespace.$key", $value);
+ $this->plist->set($key, $value);
// reset definitions if the directives they depend on changed
// this is a very costly process, so it's discouraged
// with finalization
- if ($namespace == 'HTML' || $namespace == 'CSS') {
+ if ($namespace == 'HTML' || $namespace == 'CSS' || $namespace == 'URI') {
$this->definitions[$namespace] = null;
}
@@ -271,74 +319,203 @@ class HTMLPurifier_Config
* 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.
+ * @param $optimized If true, this method may return null, to
+ * indicate that a cached version of the modified
+ * definition object is available and no further edits
+ * are necessary. Consider using
+ * maybeGetRawHTMLDefinition, which is more explicitly
+ * named, instead.
*/
- public function getHTMLDefinition($raw = false) {
- return $this->getDefinition('HTML', $raw);
+ public function getHTMLDefinition($raw = false, $optimized = false) {
+ return $this->getDefinition('HTML', $raw, $optimized);
}
/**
* 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.
+ * @param $optimized If true, this method may return null, to
+ * indicate that a cached version of the modified
+ * definition object is available and no further edits
+ * are necessary. Consider using
+ * maybeGetRawCSSDefinition, which is more explicitly
+ * named, instead.
*/
- public function getCSSDefinition($raw = false) {
- return $this->getDefinition('CSS', $raw);
+ public function getCSSDefinition($raw = false, $optimized = false) {
+ return $this->getDefinition('CSS', $raw, $optimized);
+ }
+
+ /**
+ * Retrieves object reference to the URI definition
+ * @param $raw Return a copy that has not been setup yet. Must be
+ * called before it's been setup, otherwise won't work.
+ * @param $optimized If true, this method may return null, to
+ * indicate that a cached version of the modified
+ * definition object is available and no further edits
+ * are necessary. Consider using
+ * maybeGetRawURIDefinition, which is more explicitly
+ * named, instead.
+ */
+ public function getURIDefinition($raw = false, $optimized = false) {
+ return $this->getDefinition('URI', $raw, $optimized);
}
/**
* Retrieves a definition
* @param $type Type of definition: HTML, CSS, etc
* @param $raw Whether or not definition should be returned raw
+ * @param $optimized Only has an effect when $raw is true. Whether
+ * or not to return null if the result is already present in
+ * the cache. This is off by default for backwards
+ * compatibility reasons, but you need to do things this
+ * way in order to ensure that caching is done properly.
+ * Check out enduser-customize.html for more details.
+ * We probably won't ever change this default, as much as the
+ * maybe semantics is the "right thing to do."
*/
- public function getDefinition($type, $raw = false) {
- if (!$this->finalized) $this->autoFinalize ? $this->finalize() : $this->plist->squash(true);
+ public function getDefinition($type, $raw = false, $optimized = false) {
+ if ($optimized && !$raw) {
+ throw new HTMLPurifier_Exception("Cannot set optimized = true when raw = false");
+ }
+ if (!$this->finalized) $this->autoFinalize();
+ // temporarily suspend locks, so we can handle recursive definition calls
+ $lock = $this->lock;
+ $this->lock = null;
$factory = HTMLPurifier_DefinitionCacheFactory::instance();
$cache = $factory->create($type, $this);
+ $this->lock = $lock;
if (!$raw) {
- // see if we can quickly supply a definition
+ // full definition
+ // ---------------
+ // check if definition is in memory
if (!empty($this->definitions[$type])) {
- if (!$this->definitions[$type]->setup) {
- $this->definitions[$type]->setup($this);
- $cache->set($this->definitions[$type], $this);
+ $def = $this->definitions[$type];
+ // check if the definition is setup
+ if ($def->setup) {
+ return $def;
+ } else {
+ $def->setup($this);
+ if ($def->optimized) $cache->add($def, $this);
+ return $def;
}
- return $this->definitions[$type];
}
- // memory check missed, try cache
- $this->definitions[$type] = $cache->get($this);
- if ($this->definitions[$type]) {
- // definition in cache, return it
- return $this->definitions[$type];
+ // check if definition is in cache
+ $def = $cache->get($this);
+ if ($def) {
+ // definition in cache, save to memory and return it
+ $this->definitions[$type] = $def;
+ return $def;
}
- } elseif (
- !empty($this->definitions[$type]) &&
- !$this->definitions[$type]->setup
- ) {
- // raw requested, raw in memory, quick return
- return $this->definitions[$type];
+ // initialize it
+ $def = $this->initDefinition($type);
+ // set it up
+ $this->lock = $type;
+ $def->setup($this);
+ $this->lock = null;
+ // save in cache
+ $cache->add($def, $this);
+ // return it
+ return $def;
+ } else {
+ // raw definition
+ // --------------
+ // check preconditions
+ $def = null;
+ if ($optimized) {
+ if (is_null($this->get($type . '.DefinitionID'))) {
+ // fatally error out if definition ID not set
+ throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID");
+ }
+ }
+ if (!empty($this->definitions[$type])) {
+ $def = $this->definitions[$type];
+ if ($def->setup && !$optimized) {
+ $extra = $this->chatty ? " (try moving this code block earlier in your initialization)" : "";
+ throw new HTMLPurifier_Exception("Cannot retrieve raw definition after it has already been setup" . $extra);
+ }
+ if ($def->optimized === null) {
+ $extra = $this->chatty ? " (try flushing your cache)" : "";
+ throw new HTMLPurifier_Exception("Optimization status of definition is unknown" . $extra);
+ }
+ if ($def->optimized !== $optimized) {
+ $msg = $optimized ? "optimized" : "unoptimized";
+ $extra = $this->chatty ? " (this backtrace is for the first inconsistent call, which was for a $msg raw definition)" : "";
+ throw new HTMLPurifier_Exception("Inconsistent use of optimized and unoptimized raw definition retrievals" . $extra);
+ }
+ }
+ // check if definition was in memory
+ if ($def) {
+ if ($def->setup) {
+ // invariant: $optimized === true (checked above)
+ return null;
+ } else {
+ return $def;
+ }
+ }
+ // if optimized, check if definition was in cache
+ // (because we do the memory check first, this formulation
+ // is prone to cache slamming, but I think
+ // guaranteeing that either /all/ of the raw
+ // setup code or /none/ of it is run is more important.)
+ if ($optimized) {
+ // This code path only gets run once; once we put
+ // something in $definitions (which is guaranteed by the
+ // trailing code), we always short-circuit above.
+ $def = $cache->get($this);
+ if ($def) {
+ // save the full definition for later, but don't
+ // return it yet
+ $this->definitions[$type] = $def;
+ return null;
+ }
+ }
+ // check invariants for creation
+ if (!$optimized) {
+ if (!is_null($this->get($type . '.DefinitionID'))) {
+ if ($this->chatty) {
+ $this->triggerError("Due to a documentation error in previous version of HTML Purifier, your definitions are not being cached. If this is OK, you can remove the %$type.DefinitionRev and %$type.DefinitionID declaration. Otherwise, modify your code to use maybeGetRawDefinition, and test if the returned value is null before making any edits (if it is null, that means that a cached version is available, and no raw operations are necessary). See Customize for more details", E_USER_WARNING);
+ } else {
+ $this->triggerError("Useless DefinitionID declaration", E_USER_WARNING);
+ }
+ }
+ }
+ // initialize it
+ $def = $this->initDefinition($type);
+ $def->optimized = $optimized;
+ return $def;
}
+ throw new HTMLPurifier_Exception("The impossible happened!");
+ }
+
+ private function initDefinition($type) {
// quick checks failed, let's create the object
if ($type == 'HTML') {
- $this->definitions[$type] = new HTMLPurifier_HTMLDefinition();
+ $def = new HTMLPurifier_HTMLDefinition();
} elseif ($type == 'CSS') {
- $this->definitions[$type] = new HTMLPurifier_CSSDefinition();
+ $def = new HTMLPurifier_CSSDefinition();
} elseif ($type == 'URI') {
- $this->definitions[$type] = new HTMLPurifier_URIDefinition();
+ $def = new HTMLPurifier_URIDefinition();
} else {
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
- throw new HTMLPurifier_Exception("Cannot retrieve raw version without specifying %$type.DefinitionID");
- }
- return $this->definitions[$type];
- }
- // set it up
- $this->definitions[$type]->setup($this);
- // save in cache
- $cache->set($this->definitions[$type], $this);
- return $this->definitions[$type];
+ $this->definitions[$type] = $def;
+ return $def;
+ }
+
+ public function maybeGetRawDefinition($name) {
+ return $this->getDefinition($name, true, true);
+ }
+
+ public function maybeGetRawHTMLDefinition() {
+ return $this->getDefinition('HTML', true, true);
+ }
+
+ public function maybeGetRawCSSDefinition() {
+ return $this->getDefinition('CSS', true, true);
+ }
+
+ public function maybeGetRawURIDefinition() {
+ return $this->getDefinition('URI', true, true);
}
/**
@@ -351,14 +528,12 @@ class HTMLPurifier_Config
foreach ($config_array as $key => $value) {
$key = str_replace('_', '.', $key);
if (strpos($key, '.') !== false) {
- // condensed form
- list($namespace, $directive) = explode('.', $key);
- $this->set($namespace, $directive, $value);
+ $this->set($key, $value);
} else {
$namespace = $key;
$namespace_values = $value;
foreach ($namespace_values as $directive => $value) {
- $this->set($namespace, $directive, $value);
+ $this->set($namespace .'.'. $directive, $value);
}
}
}
@@ -394,16 +569,15 @@ class HTMLPurifier_Config
}
}
$ret = array();
- foreach ($schema->info as $ns => $keypairs) {
- foreach ($keypairs as $directive => $def) {
- if ($allowed !== true) {
- if (isset($blacklisted_directives["$ns.$directive"])) continue;
- if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue;
- }
- if (isset($def->isAlias)) continue;
- if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue;
- $ret[] = array($ns, $directive);
+ foreach ($schema->info as $key => $def) {
+ list($ns, $directive) = explode('.', $key, 2);
+ if ($allowed !== true) {
+ if (isset($blacklisted_directives["$ns.$directive"])) continue;
+ if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue;
}
+ if (isset($def->isAlias)) continue;
+ if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue;
+ $ret[] = array($ns, $directive);
}
return $ret;
}
@@ -472,7 +646,7 @@ class HTMLPurifier_Config
*/
public function isFinalized($error = false) {
if ($this->finalized && $error) {
- trigger_error($error, E_USER_ERROR);
+ $this->triggerError($error, E_USER_ERROR);
}
return $this->finalized;
}
@@ -482,7 +656,11 @@ class HTMLPurifier_Config
* already finalized
*/
public function autoFinalize() {
- if (!$this->finalized && $this->autoFinalize) $this->finalize();
+ if ($this->autoFinalize) {
+ $this->finalize();
+ } else {
+ $this->plist->squash(true);
+ }
}
/**
@@ -490,6 +668,40 @@ class HTMLPurifier_Config
*/
public function finalize() {
$this->finalized = true;
+ unset($this->parser);
+ }
+
+ /**
+ * Produces a nicely formatted error message by supplying the
+ * stack frame information OUTSIDE of HTMLPurifier_Config.
+ */
+ protected function triggerError($msg, $no) {
+ // determine previous stack frame
+ $extra = '';
+ if ($this->chatty) {
+ $trace = debug_backtrace();
+ // zip(tail(trace), trace) -- but PHP is not Haskell har har
+ for ($i = 0, $c = count($trace); $i < $c - 1; $i++) {
+ if ($trace[$i + 1]['class'] === 'HTMLPurifier_Config') {
+ continue;
+ }
+ $frame = $trace[$i];
+ $extra = " invoked on line {$frame['line']} in file {$frame['file']}";
+ break;
+ }
+ }
+ trigger_error($msg . $extra, $no);
+ }
+
+ /**
+ * Returns a serialized form of the configuration object that can
+ * be reconstituted.
+ */
+ public function serialize() {
+ $this->getDefinition('HTML');
+ $this->getDefinition('CSS');
+ $this->getDefinition('URI');
+ return serialize($this);
}
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema.php
old mode 100755
new mode 100644
index 340ed7dbc..fadf7a589
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema.php
@@ -60,7 +60,13 @@ class HTMLPurifier_ConfigSchema {
* Unserializes the default ConfigSchema.
*/
public static function makeFromSerial() {
- return unserialize(file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'));
+ $contents = file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser');
+ $r = unserialize($contents);
+ if (!$r) {
+ $hash = sha1($contents);
+ trigger_error("Unserialization of configuration schema failed, sha1 of file was $hash", E_USER_ERROR);
+ }
+ return $r;
}
/**
@@ -87,24 +93,13 @@ class HTMLPurifier_ConfigSchema {
* HTMLPurifier_DirectiveDef::$type for allowed values
* @param $allow_null Whether or not to allow null values
*/
- public function add($namespace, $name, $default, $type, $allow_null) {
+ public function add($key, $default, $type, $allow_null) {
$obj = new stdclass();
$obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type];
if ($allow_null) $obj->allow_null = true;
- $this->info[$namespace][$name] = $obj;
- $this->defaults[$namespace][$name] = $default;
- $this->defaultPlist->set("$namespace.$name", $default);
- }
-
- /**
- * Defines a namespace for directives to be put into.
- * @warning This is slightly different from the corresponding static
- * method.
- * @param $namespace Namespace's name
- */
- public function addNamespace($namespace) {
- $this->info[$namespace] = array();
- $this->defaults[$namespace] = array();
+ $this->info[$key] = $obj;
+ $this->defaults[$key] = $default;
+ $this->defaultPlist->set($key, $default);
}
/**
@@ -116,12 +111,12 @@ class HTMLPurifier_ConfigSchema {
* @param $name Name of Directive
* @param $aliases Hash of aliased values to the real alias
*/
- public function addValueAliases($namespace, $name, $aliases) {
- if (!isset($this->info[$namespace][$name]->aliases)) {
- $this->info[$namespace][$name]->aliases = array();
+ public function addValueAliases($key, $aliases) {
+ if (!isset($this->info[$key]->aliases)) {
+ $this->info[$key]->aliases = array();
}
foreach ($aliases as $alias => $real) {
- $this->info[$namespace][$name]->aliases[$alias] = $real;
+ $this->info[$key]->aliases[$alias] = $real;
}
}
@@ -133,8 +128,8 @@ class HTMLPurifier_ConfigSchema {
* @param $name Name of directive
* @param $allowed Lookup array of allowed values
*/
- public function addAllowedValues($namespace, $name, $allowed) {
- $this->info[$namespace][$name]->allowed = $allowed;
+ public function addAllowedValues($key, $allowed) {
+ $this->info[$key]->allowed = $allowed;
}
/**
@@ -144,88 +139,26 @@ class HTMLPurifier_ConfigSchema {
* @param $new_namespace
* @param $new_name Directive that the alias will be to
*/
- public function addAlias($namespace, $name, $new_namespace, $new_name) {
+ public function addAlias($key, $new_key) {
$obj = new stdclass;
- $obj->namespace = $new_namespace;
- $obj->name = $new_name;
+ $obj->key = $new_key;
$obj->isAlias = true;
- $this->info[$namespace][$name] = $obj;
+ $this->info[$key] = $obj;
}
/**
* Replaces any stdclass that only has the type property with type integer.
*/
public function postProcess() {
- foreach ($this->info as $namespace => $info) {
- foreach ($info as $directive => $v) {
- if (count((array) $v) == 1) {
- $this->info[$namespace][$directive] = $v->type;
- } elseif (count((array) $v) == 2 && isset($v->allow_null)) {
- $this->info[$namespace][$directive] = -$v->type;
- }
+ foreach ($this->info as $key => $v) {
+ if (count((array) $v) == 1) {
+ $this->info[$key] = $v->type;
+ } elseif (count((array) $v) == 2 && isset($v->allow_null)) {
+ $this->info[$key] = -$v->type;
}
}
}
- // DEPRECATED METHODS
-
- /** @see HTMLPurifier_ConfigSchema->set() */
- public static function define($namespace, $name, $default, $type, $description) {
- HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
- $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 = 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);
- $parser = new HTMLPurifier_VarParser();
- return $parser->parse($a, $b, $c);
- }
-
- /**
- * Throws an E_USER_NOTICE stating that a method is deprecated.
- */
- private static function deprecated($method) {
- trigger_error("Static HTMLPurifier_ConfigSchema::$method deprecated, use add*() method instead", E_USER_NOTICE);
- }
-
}
// vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php
old mode 100755
new mode 100644
index 987f547bc..c05668a70
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php
@@ -9,36 +9,28 @@ 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->id->key,
$d->default,
$d->type,
$d->typeAllowsNull
);
if ($d->allowed !== null) {
$schema->addAllowedValues(
- $d->id->namespace,
- $d->id->directive,
+ $d->id->key,
$d->allowed
);
}
foreach ($d->aliases as $alias) {
$schema->addAlias(
- $alias->namespace,
- $alias->directive,
- $d->id->namespace,
- $d->id->directive
+ $alias->key,
+ $d->id->key
);
}
if ($d->valueAliases !== null) {
$schema->addValueAliases(
- $d->id->namespace,
- $d->id->directive,
+ $d->id->key,
$d->valueAliases
);
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Builder/Xml.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Builder/Xml.php
old mode 100755
new mode 100644
index 51bcab78c..244561a37
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Builder/Xml.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Builder/Xml.php
@@ -8,6 +8,7 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
{
protected $interchange;
+ private $namespace;
protected function writeHTMLDiv($html) {
$this->startElement('div');
@@ -34,36 +35,33 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
$this->startElement('configdoc');
$this->writeElement('title', $interchange->name);
- foreach ($interchange->namespaces as $namespace) {
- $this->buildNamespace($namespace);
+ foreach ($interchange->directives as $directive) {
+ $this->buildDirective($directive);
}
+ if ($this->namespace) $this->endElement(); // namespace
+
$this->endElement(); // configdoc
$this->flush();
}
- public function buildNamespace($namespace) {
- $this->startElement('namespace');
- $this->writeAttribute('id', $namespace->namespace);
+ public function buildDirective($directive) {
- $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);
+ // Kludge, although I suppose having a notion of a "root namespace"
+ // certainly makes things look nicer when documentation is built.
+ // Depends on things being sorted.
+ if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) {
+ if ($this->namespace) $this->endElement(); // namespace
+ $this->namespace = $directive->id->getRootNamespace();
+ $this->startElement('namespace');
+ $this->writeAttribute('id', $this->namespace);
+ $this->writeElement('name', $this->namespace);
}
- $this->endElement(); // namespace
- }
-
- public function buildDirective($directive) {
$this->startElement('directive');
$this->writeAttribute('id', $directive->id->toString());
- $this->writeElement('name', $directive->id->directive);
+ $this->writeElement('name', $directive->id->getDirective());
$this->startElement('aliases');
foreach ($directive->aliases as $alias) $this->writeElement('alias', $alias->toString());
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Exception.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Exception.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange.php
old mode 100755
new mode 100644
index 365c66357..91a5aa730
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange.php
@@ -13,26 +13,11 @@ class HTMLPurifier_ConfigSchema_Interchange
*/
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
*/
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange/Directive.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange/Directive.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange/Id.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange/Id.php
old mode 100755
new mode 100644
index ec01589b6..b9b3c6f5c
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange/Id.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Interchange/Id.php
@@ -6,11 +6,10 @@
class HTMLPurifier_ConfigSchema_Interchange_Id
{
- public $namespace, $directive;
+ public $key;
- public function __construct($namespace, $directive) {
- $this->namespace = $namespace;
- $this->directive = $directive;
+ public function __construct($key) {
+ $this->key = $key;
}
/**
@@ -18,12 +17,19 @@ class HTMLPurifier_ConfigSchema_Interchange_Id
* cause problems for PHP 5.0 support.
*/
public function toString() {
- return $this->namespace . '.' . $this->directive;
+ return $this->key;
+ }
+
+ public function getRootNamespace() {
+ return substr($this->key, 0, strpos($this->key, "."));
+ }
+
+ public function getDirective() {
+ return substr($this->key, strpos($this->key, ".") + 1);
}
public static function make($id) {
- list($namespace, $directive) = explode('.', $id);
- return new HTMLPurifier_ConfigSchema_Interchange_Id($namespace, $directive);
+ return new HTMLPurifier_ConfigSchema_Interchange_Id($id);
}
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php
old mode 100755
new mode 100644
index a1a24eacb..785b72ce8
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php
@@ -13,13 +13,17 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
}
public static function buildFromDirectory($dir = null) {
- $parser = new HTMLPurifier_StringHashParser();
$builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder();
$interchange = new HTMLPurifier_ConfigSchema_Interchange();
+ return $builder->buildDir($interchange, $dir);
+ }
- if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema/';
- $info = parse_ini_file($dir . 'info.ini');
- $interchange->name = $info['name'];
+ public function buildDir($interchange, $dir = null) {
+ if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema';
+ if (file_exists($dir . '/info.ini')) {
+ $info = parse_ini_file($dir . '/info.ini');
+ $interchange->name = $info['name'];
+ }
$files = array();
$dh = opendir($dir);
@@ -33,15 +37,20 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
sort($files);
foreach ($files as $file) {
- $builder->build(
- $interchange,
- new HTMLPurifier_StringHash( $parser->parseFile($dir . $file) )
- );
+ $this->buildFile($interchange, $dir . '/' . $file);
}
return $interchange;
}
+ public function buildFile($interchange, $file) {
+ $parser = new HTMLPurifier_StringHashParser();
+ $this->build(
+ $interchange,
+ new HTMLPurifier_StringHash( $parser->parseFile($file) )
+ );
+ }
+
/**
* Builds an interchange object based on a hash.
* @param $interchange HTMLPurifier_ConfigSchema_Interchange object to build
@@ -55,22 +64,17 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID');
}
if (strpos($hash['ID'], '.') === false) {
- $this->buildNamespace($interchange, $hash);
+ if (count($hash) == 2 && isset($hash['DESCRIPTION'])) {
+ $hash->offsetGet('DESCRIPTION'); // prevent complaining
+ } else {
+ throw new HTMLPurifier_ConfigSchema_Exception('All directives must have a namespace');
+ }
} 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();
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Validator.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Validator.php
old mode 100755
new mode 100644
index 2dfd37bae..f374f6a02
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Validator.php
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/Validator.php
@@ -39,10 +39,6 @@ class HTMLPurifier_ConfigSchema_Validator
$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'");
@@ -51,20 +47,6 @@ class HTMLPurifier_ConfigSchema_Validator
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.
*/
@@ -75,12 +57,11 @@ class HTMLPurifier_ConfigSchema_Validator
// 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')
+ // keys are now unconstrained (we might want to narrow down to A-Za-z0-9.)
+ // we probably should check that it has at least one namespace
+ $this->with($id, 'key')
->assertNotEmpty()
- ->assertAlnum(); // implicit assertIsString handled by InterchangeBuilder
+ ->assertIsString(); // implicit assertIsString handled by InterchangeBuilder
array_pop($this->context);
}
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/ValidatorAtom.php b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/ValidatorAtom.php
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema.ser b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema.ser
old mode 100755
new mode 100644
index 1eaecd11f..245ba5d2d
Binary files a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema.ser and b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema.ser differ
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt
new file mode 100644
index 000000000..0517fed0a
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt
@@ -0,0 +1,8 @@
+Attr.AllowedClasses
+TYPE: lookup/null
+VERSION: 4.0.0
+DEFAULT: null
+--DESCRIPTION--
+List of allowed class values in the class attribute. By default, this is null,
+which means all classes are allowed.
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt
new file mode 100644
index 000000000..e774b823b
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt
@@ -0,0 +1,19 @@
+Attr.ClassUseCDATA
+TYPE: bool/null
+DEFAULT: null
+VERSION: 4.0.0
+--DESCRIPTION--
+If null, class will auto-detect the doctype and, if matching XHTML 1.1 or
+XHTML 2.0, will use the restrictive NMTOKENS specification of class. Otherwise,
+it will use a relaxed CDATA definition. If true, the relaxed CDATA definition
+is forced; if false, the NMTOKENS definition is forced. To get behavior
+of HTML Purifier prior to 4.0.0, set this directive to false.
+
+Some rational behind the auto-detection:
+in previous versions of HTML Purifier, it was assumed that the form of
+class was NMTOKENS, as specified by the XHTML Modularization (representing
+XHTML 1.1 and XHTML 2.0). The DTDs for HTML 4.01 and XHTML 1.0, however
+specify class as CDATA. HTML 5 effectively defines it as CDATA, but
+with the additional constraint that each name should be unique (this is not
+explicitly outlined in previous specifications).
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt
new file mode 100644
index 000000000..f31d226f5
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt
@@ -0,0 +1,8 @@
+Attr.ForbiddenClasses
+TYPE: lookup
+VERSION: 4.0.0
+DEFAULT: array()
+--DESCRIPTION--
+List of forbidden class values in the class attribute. By default, this is
+empty, which means that no classes are forbidden. See also %Attr.AllowedClasses.
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt
new file mode 100644
index 000000000..db58b1346
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt
@@ -0,0 +1,12 @@
+AutoFormat.PurifierLinkify.DocURL
+TYPE: string
+VERSION: 2.0.1
+DEFAULT: '#%s'
+ALIASES: AutoFormatParam.PurifierLinkifyDocURL
+--DESCRIPTION--
+
+ Location of configuration documentation to link to, let %s substitute
+ into the configuration's namespace and directive names sans the percent
+ sign.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt
new file mode 100644
index 000000000..35c393b4e
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt
@@ -0,0 +1,11 @@
+AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions
+TYPE: lookup
+VERSION: 4.0.0
+DEFAULT: array('td' => true, 'th' => true)
+--DESCRIPTION--
+
+ When %AutoFormat.RemoveEmpty and %AutoFormat.RemoveEmpty.RemoveNbsp
+ are enabled, this directive defines what HTML elements should not be
+ removede if they have only a non-breaking space in them.
+
+ When enabled, HTML Purifier will treat any elements that contain only
+ non-breaking spaces as well as regular whitespace as empty, and remove
+ them when %AutoForamt.RemoveEmpty is enabled.
+
+
+ See %AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions for a list of elements
+ that don't have this behavior applied to them.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt
old mode 100755
new mode 100644
index aaede47d6..34657ba47
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt
@@ -31,7 +31,8 @@ DEFAULT: false
Elements that contain only whitespace will be treated as empty. Non-breaking
- spaces, however, do not count as whitespace.
+ spaces, however, do not count as whitespace. See
+ %AutoFormat.RemoveEmpty.RemoveNbsp for alternate behavior.
This algorithm is not perfect; you may still notice some empty tags,
@@ -39,7 +40,7 @@ DEFAULT: false
because they were not permitted in that context, or tags that, after
being auto-closed by another tag, where empty. This is for safety reasons
to prevent clever code from breaking validation. The general rule of thumb:
- if a tag looked empty on the way end, it will get removed; if HTML Purifier
+ if a tag looked empty on the way in, it will get removed; if HTML Purifier
made it empty, it will stay.
+ This directive causes span tags without any attributes
+ to be removed. It will also remove spans that had all attributes
+ removed during processing.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt
new file mode 100644
index 000000000..3fd465406
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt
@@ -0,0 +1,12 @@
+CSS.AllowedFonts
+TYPE: lookup/null
+VERSION: 4.3.0
+DEFAULT: NULL
+--DESCRIPTION--
+
+ Allows you to manually specify a set of allowed fonts. If
+ NULL, all fonts are allowed. This directive
+ affects generic names (serif, sans-serif, monospace, cursive,
+ fantasy) as well as specific font families.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt
new file mode 100644
index 000000000..f1f5c5f12
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt
@@ -0,0 +1,13 @@
+CSS.ForbiddenProperties
+TYPE: lookup
+VERSION: 4.2.0
+DEFAULT: array()
+--DESCRIPTION--
+
+ This is the logical inverse of %CSS.AllowedProperties, and it will
+ override that directive or any other directive. If possible,
+ %CSS.AllowedProperties is recommended over this directive,
+ because it can sometimes be difficult to tell whether or not you've
+ forbidden all of the CSS properties you truly would like to disallow.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt
new file mode 100644
index 000000000..e733a61e8
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt
@@ -0,0 +1,9 @@
+CSS.Trusted
+TYPE: bool
+VERSION: 4.2.1
+DEFAULT: false
+--DESCRIPTION--
+Indicates whether or not the user's CSS input is trusted or not. If the
+input is trusted, a more expansive set of allowed properties. See
+also %HTML.Trusted.
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt
new file mode 100644
index 000000000..b2b83d9ab
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt
@@ -0,0 +1,11 @@
+Cache.SerializerPermissions
+TYPE: int
+VERSION: 4.3.0
+DEFAULT: 0755
+--DESCRIPTION--
+
+
+ Directory permissions of the files and directories created inside
+ the DefinitionCache/Serializer or other custom serializer path.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.Language.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.Language.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt
new file mode 100644
index 000000000..d77f5360d
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt
@@ -0,0 +1,11 @@
+Core.NormalizeNewlines
+TYPE: bool
+VERSION: 4.2.0
+DEFAULT: true
+--DESCRIPTION--
+
+ Whether or not to normalize newlines to the operating
+ system default. When false, HTML Purifier
+ will attempt to preserve mixed newline files.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt
new file mode 100644
index 000000000..3397d9f71
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt
@@ -0,0 +1,11 @@
+Core.RemoveProcessingInstructions
+TYPE: bool
+VERSION: 4.2.0
+DEFAULT: false
+--DESCRIPTION--
+Instead of escaping processing instructions in the form <? ...
+?>, remove it out-right. This may be useful if the HTML
+you are validating contains XML processing instruction gunk, however,
+it can also be user-unfriendly for people attempting to post PHP
+snippets.
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt
new file mode 100644
index 000000000..16829bcda
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt
@@ -0,0 +1,14 @@
+Filter.ExtractStyleBlocks.Escaping
+TYPE: bool
+VERSION: 3.0.0
+DEFAULT: true
+ALIASES: Filter.ExtractStyleBlocksEscaping, FilterParam.ExtractStyleBlocksEscaping
+--DESCRIPTION--
+
+
+ Whether or not to escape the dangerous characters <, > and &
+ as \3C, \3E and \26, respectively. This is can be safely set to false
+ if the contents of StyleBlocks will be placed in an external stylesheet,
+ where there is no risk of it being interpreted as HTML.
+
+ If you would like users to be able to define external stylesheets, but
+ only allow them to specify CSS declarations for a specific node and
+ prevent them from fiddling with other elements, use this directive.
+ It accepts any valid CSS selector, and will prepend this to any
+ CSS declaration extracted from the document. For example, if this
+ directive is set to #user-content and a user uses the
+ selector a:hover, the final selector will be
+ #user-content a:hover.
+
+
+ The comma shorthand may be used; consider the above example, with
+ #user-content, #user-content2, the final selector will
+ be #user-content a:hover, #user-content2 a:hover.
+
+
+ Warning: It is possible for users to bypass this measure
+ using a naughty + selector. This is a bug in CSS Tidy 1.3, not HTML
+ Purifier, and I am working to get it fixed. Until then, HTML Purifier
+ performs a basic check to prevent this.
+
+ If left NULL, HTML Purifier will attempt to instantiate a csstidy
+ class to use for internal cleaning. This will usually be good enough.
+
+
+ However, for trusted user input, you can set this to false to
+ disable cleaning. In addition, you can supply your own concrete implementation
+ of Tidy's interface to use, although I don't know why you'd want to do that.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt
old mode 100755
new mode 100644
index 7fa6536b2..321eaa2d8
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt
@@ -3,6 +3,11 @@ TYPE: bool
VERSION: 3.1.0
DEFAULT: false
--DESCRIPTION--
+
+ Warning: Deprecated in favor of %HTML.SafeObject and
+ %Output.FlashCompat (turn both on to allow YouTube videos and other
+ Flash content).
+
Warning: If another directive conflicts with the
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt
new file mode 100644
index 000000000..151fb7b82
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt
@@ -0,0 +1,11 @@
+HTML.Attr.Name.UseCDATA
+TYPE: bool
+DEFAULT: false
+VERSION: 4.0.0
+--DESCRIPTION--
+The W3C specification DTD defines the name attribute to be CDATA, not ID, due
+to limitations of DTD. In certain documents, this relaxed behavior is desired,
+whether it is to specify duplicate names, or to specify names that would be
+illegal IDs (for example, names that begin with a digit.) Set this configuration
+directive to true to use the relaxed parsing rules.
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt
new file mode 100644
index 000000000..7878dc0bf
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt
@@ -0,0 +1,11 @@
+HTML.FlashAllowFullScreen
+TYPE: bool
+VERSION: 4.2.0
+DEFAULT: false
+--DESCRIPTION--
+
+ Whether or not to permit embedded Flash content from
+ %HTML.SafeObject to expand to the full screen. Corresponds to
+ the allowFullScreen parameter.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt
new file mode 100644
index 000000000..700b30924
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt
@@ -0,0 +1,7 @@
+HTML.Nofollow
+TYPE: bool
+VERSION: 4.3.0
+DEFAULT: FALSE
+--DESCRIPTION--
+If enabled, nofollow rel attributes are added to all outgoing links.
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt
old mode 100755
new mode 100644
index f635a6854..cdda09a4c
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt
@@ -7,8 +7,7 @@ DEFAULT: false
Whether or not to permit embed tags in documents, with a number of extra
security features added to prevent script execution. This is similar to
what websites like MySpace do to embed tags. Embed is a proprietary
- element and will cause your website to stop validating. You probably want
- to enable this with %HTML.SafeObject.
- Highly experimental.
-
+ element and will cause your website to stop validating; you should
+ see if you can use %Output.FlashCompat with %HTML.SafeObject instead
+ first.
--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt
old mode 100755
new mode 100644
index 32967b88f..ceb342e22
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt
@@ -6,9 +6,8 @@ DEFAULT: false
Whether or not to permit object tags in documents, with a number of extra
security features added to prevent script execution. This is similar to
- what websites like MySpace do to object tags. You may also want to
- enable %HTML.SafeEmbed for maximum interoperability with Internet Explorer,
- although embed tags will cause your website to stop validating.
- Highly experimental.
+ what websites like MySpace do to object tags. You should also enable
+ %Output.FlashCompat in order to generate Internet Explorer
+ compatibility code for your object tags.
--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt
old mode 100755
new mode 100644
index 89133b1a3..1db9237e9
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt
@@ -5,4 +5,5 @@ DEFAULT: false
--DESCRIPTION--
Indicates whether or not the user input is trusted or not. If the input is
trusted, a more expansive set of allowed tags and attributes will be used.
+See also %CSS.Trusted.
--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt
new file mode 100644
index 000000000..d6f0d9f29
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt
@@ -0,0 +1,15 @@
+Output.FixInnerHTML
+TYPE: bool
+VERSION: 4.3.0
+DEFAULT: true
+--DESCRIPTION--
+
+ If true, HTML Purifier will protect against Internet Explorer's
+ mishandling of the innerHTML attribute by appending
+ a space to any attribute that does not contain angled brackets, spaces
+ or quotes, but contains a backtick. This slightly changes the
+ semantics of any given attribute, so if this is unacceptable and
+ you do not use innerHTML on any of your pages, you can
+ turn this directive off.
+
+ If true, HTML Purifier will generate Internet Explorer compatibility
+ code for all object code. This is highly recommended if you enable
+ %HTML.SafeObject.
+
+--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt
old mode 100755
new mode 100644
index 98fdfe922..666635a5f
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt
@@ -12,4 +12,6 @@ array (
--DESCRIPTION--
Whitelist that defines the schemes that a URI is allowed to have. This
prevents XSS attacks from using pseudo-schemes like javascript or mocha.
+There is also support for the data and file
+URI schemes, but they are not enabled by default.
--# vim: et sw=4 sts=4
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.Base.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.Base.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt
old mode 100755
new mode 100644
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt
old mode 100755
new mode 100644
index 51e6ea91f..f891de499
--- a/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt
+++ b/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt
@@ -1,12 +1,15 @@
URI.DisableResources
TYPE: bool
-VERSION: 1.3.0
+VERSION: 4.2.0
DEFAULT: false
--DESCRIPTION--
-
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.
+
+ Note: While this directive has been available since 1.3.0,
+ it didn't actually start doing anything until 4.2.0.
+