diff --git a/library/HTMLPurifier/AttrDef/CSS.php b/library/HTMLPurifier/AttrDef/CSS.php
index af6b8a05..9d3fa499 100644
--- a/library/HTMLPurifier/AttrDef/CSS.php
+++ b/library/HTMLPurifier/AttrDef/CSS.php
@@ -14,6 +14,20 @@
class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
{
+ const CACHE_LIMIT = 1000;
+
+ /**
+ * Internal values cache for styles.
+ * @type array
+ */
+ protected $cache = array();
+
+ /**
+ * Cached serial for the CSS config namespace.
+ * @type string|null
+ */
+ protected $cacheSerial;
+
/**
* @param string $css
* @param HTMLPurifier_Config $config
@@ -23,6 +37,20 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
public function validate($css, $config, $context)
{
$css = $this->parseCDATA($css);
+ if ($css === '') {
+ return false;
+ }
+
+ // Warning: This is a VERY simple cache, so we only keep it valid
+ // for the current CSS configuration namespace.
+ $serial = $config->getBatchSerial('CSS');
+ if ($this->cacheSerial !== $serial) {
+ $this->cache = array();
+ $this->cacheSerial = $serial;
+ }
+ if (array_key_exists($css, $this->cache)) {
+ return $this->cache[$css];
+ }
$definition = $config->getCSSDefinition();
$allow_duplicates = $config->get("CSS.AllowDuplicates");
@@ -131,7 +159,11 @@ public function validate($css, $config, $context)
$new_declarations .= "$prop:$value;";
}
- return $new_declarations ? $new_declarations : false;
+ $result = $new_declarations ? $new_declarations : false;
+ if (count($this->cache) < self::CACHE_LIMIT) {
+ $this->cache[$css] = $result;
+ }
+ return $result;
}