Blob Blame History Raw
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/AttrDef/CSS/BackgroundPosition.php lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
--- lib/htmlpurifier/HTMLPurifier.old/AttrDef/CSS/BackgroundPosition.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php	2010-05-31 22:22:39.000000000 -0500
@@ -59,7 +59,8 @@
         $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 @@
             $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 @@
 
         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 -r -U3 lib/htmlpurifier/HTMLPurifier.old/AttrDef/CSS/FontFamily.php lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/FontFamily.php
--- lib/htmlpurifier/HTMLPurifier.old/AttrDef/CSS/FontFamily.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/FontFamily.php	2010-05-31 22:22:39.000000000 -0500
@@ -34,37 +34,10 @@
                 $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 = $this->expandCSSEscape($font);
 
-                $font = $new_font;
-            }
             // $font is a pure representation of the font name
 
             if (ctype_alnum($font) && $font !== '') {
@@ -73,12 +46,21 @@
                 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);
+
+            // These ugly transforms don't pose a security
+            // risk (as \\ and \" might).  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.
+            // (warning: this code relies on the selection of quotation
+            // mark below)
+            $font = str_replace('\\', '\\5C ', $font);
+            $font = str_replace('"',  '\\22 ', $font);
 
-            // armor single quotes and new lines
-            $font = str_replace("\\", "\\\\", $font);
-            $font = str_replace("'", "\\'", $font);
-            $final .= "'$font', ";
+            // complicated font, requires quoting
+            $final .= "\"$font\", "; // note that this will later get turned into &quot;
         }
         $final = rtrim($final, ', ');
         if ($final === '') return false;
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/AttrDef/CSS/URI.php lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/URI.php
--- lib/htmlpurifier/HTMLPurifier.old/AttrDef/CSS/URI.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/URI.php	2010-05-31 22:22:39.000000000 -0500
@@ -34,20 +34,16 @@
             $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')";
+        return "url(\"$result\")";
 
     }
 
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/AttrDef/Lang.php lib/htmlpurifier/HTMLPurifier/AttrDef/Lang.php
--- lib/htmlpurifier/HTMLPurifier.old/AttrDef/Lang.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/AttrDef/Lang.php	2010-05-31 22:22:39.000000000 -0500
@@ -9,10 +9,6 @@
 
     public function validate($string, $config, $context) {
 
-// moodle change - we use special lang strings unfortunatelly
-        return preg_replace('/[^0-9a-zA-Z_-]/', '', $string);
-// moodle change end
-
         $string = trim($string);
         if (!$string) return false;
 
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/AttrDef.php lib/htmlpurifier/HTMLPurifier/AttrDef.php
--- lib/htmlpurifier/HTMLPurifier.old/AttrDef.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/AttrDef.php	2010-05-31 22:22:39.000000000 -0500
@@ -82,6 +82,42 @@
         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 -r -U3 lib/htmlpurifier/HTMLPurifier.old/Config.php lib/htmlpurifier/HTMLPurifier/Config.php
--- lib/htmlpurifier/HTMLPurifier.old/Config.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/Config.php	2010-05-31 22:22:39.000000000 -0500
@@ -20,7 +20,7 @@
     /**
      * HTML Purifier's version
      */
-    public $version = '4.1.0';
+    public $version = '4.1.1';
 
     /**
      * Bool indicator whether or not to automatically finalize
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/HTMLModule/Text.php lib/htmlpurifier/HTMLPurifier/HTMLModule/Text.php
--- lib/htmlpurifier/HTMLPurifier.old/HTMLModule/Text.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/HTMLModule/Text.php	2010-05-31 22:22:39.000000000 -0500
@@ -45,13 +45,6 @@
         $this->addElement('span', 'Inline', 'Inline', 'Common');
         $this->addElement('br',   'Inline', 'Empty',  'Core');
 
-        // Moodle specific elements - start
-        $this->addElement('nolink',  'Inline', 'Flow');
-        $this->addElement('tex',     'Inline', 'Flow');
-        $this->addElement('algebra', 'Inline', 'Flow');
-        $this->addElement('lang',    'Inline', 'Flow', 'I18N');
-        // Moodle specific elements - end
-        
         // Block Phrasal --------------------------------------------------
         $this->addElement('address',     'Block', 'Inline', 'Common');
         $this->addElement('blockquote',  'Block', 'Optional: Heading | Block | List', 'Common', array('cite' => 'URI') );
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/HTMLModule/XMLCommonAttributes.php lib/htmlpurifier/HTMLPurifier/HTMLModule/XMLCommonAttributes.php
--- lib/htmlpurifier/HTMLPurifier.old/HTMLModule/XMLCommonAttributes.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/HTMLModule/XMLCommonAttributes.php	2010-05-31 22:22:39.000000000 -0500
@@ -5,11 +5,9 @@
     public $name = 'XMLCommonAttributes';
 
     public $attr_collections = array(
-/* moodle comment - xml:lang breaks our multilang
         'Lang' => array(
             'xml:lang' => 'LanguageCode',
         )
-*/
     );
 }
 
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/Language/messages/en.php lib/htmlpurifier/HTMLPurifier/Language/messages/en.php
--- lib/htmlpurifier/HTMLPurifier.old/Language/messages/en.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/Language/messages/en.php	2010-05-31 22:22:39.000000000 -0500
@@ -23,6 +23,7 @@
 'Lexer: Missing gt'            => 'Missing greater-than sign (>), previous less-than sign (<) should be escaped',
 'Lexer: Missing attribute key' => 'Attribute declaration has no key',
 'Lexer: Missing end quote'     => 'Attribute declaration has no end quote',
+'Lexer: Extracted body'        => 'Removed document metadata tags',
 
 'Strategy_RemoveForeignElements: Tag transform'              => '<$1> element transformed into $CurrentToken.Serialized',
 'Strategy_RemoveForeignElements: Missing required attribute' => '$CurrentToken.Compact element missing required attribute $1',
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/Lexer/DirectLex.php lib/htmlpurifier/HTMLPurifier/Lexer/DirectLex.php
--- lib/htmlpurifier/HTMLPurifier.old/Lexer/DirectLex.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/Lexer/DirectLex.php	2010-05-31 22:22:39.000000000 -0500
@@ -384,7 +384,7 @@
                 }
             }
             if ($value === false) $value = '';
-            return array($key => $value);
+            return array($key => $this->parseData($value));
         }
 
         // setup loop environment
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/Lexer.php lib/htmlpurifier/HTMLPurifier/Lexer.php
--- lib/htmlpurifier/HTMLPurifier.old/Lexer.php	2010-06-03 19:03:47.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/Lexer.php	2010-05-31 22:22:39.000000000 -0500
@@ -252,10 +252,8 @@
     public function normalize($html, $config, $context) {
 
         // normalize newlines to \n
-        if ($config->get('Output.Newline')!=="\n") {
-            $html = str_replace("\r\n", "\n", $html);
-            $html = str_replace("\r", "\n", $html);
-        }
+        $html = str_replace("\r\n", "\n", $html);
+        $html = str_replace("\r", "\n", $html);
 
         if ($config->get('HTML.Trusted')) {
             // escape convoluted CDATA
@@ -267,7 +265,15 @@
 
         // extract body from document if applicable
         if ($config->get('Core.ConvertDocumentToFragment')) {
-            $html = $this->extractBody($html);
+            $e = false;
+            if ($config->get('Core.CollectErrors')) {
+                $e =& $context->get('ErrorCollector');
+            }
+            $new_html = $this->extractBody($html);
+            if ($e && $new_html != $html) {
+                $e->send(E_WARNING, 'Lexer: Extracted body');
+            }
+            $html = $new_html;
         }
 
         // expand entities that aren't the big five
diff -r -U3 lib/htmlpurifier/HTMLPurifier.old/Strategy/MakeWellFormed.php lib/htmlpurifier/HTMLPurifier/Strategy/MakeWellFormed.php
--- lib/htmlpurifier/HTMLPurifier.old/Strategy/MakeWellFormed.php	2010-05-21 19:04:23.000000000 -0500
+++ lib/htmlpurifier/HTMLPurifier/Strategy/MakeWellFormed.php	2010-05-31 22:22:39.000000000 -0500
@@ -165,6 +165,7 @@
             $token = $tokens[$t];
 
             //echo '<br>'; printTokens($tokens, $t); printTokens($this->stack);
+            //flush();
 
             // quick-check: if it's not a tag, no need to process
             if (empty($token->is_tag)) {
@@ -221,11 +222,14 @@
                     }
 
                     if ($autoclose && $definition->info[$token->name]->wrap) {
-                        // check if this is actually a wrap (mmm wraps!)
+                        // Check if an element can be wrapped by another 
+                        // element to make it valid in a context (for 
+                        // example, <ul><ul> needs a <li> in between)
                         $wrapname = $definition->info[$token->name]->wrap;
                         $wrapdef = $definition->info[$wrapname];
                         $elements = $wrapdef->child->getAllowedElements($config);
-                        if (isset($elements[$token->name])) {
+                        $parent_elements = $definition->info[$parent->name]->child->getAllowedElements($config);
+                        if (isset($elements[$token->name]) && isset($parent_elements[$wrapname])) {
                             $newtoken = new HTMLPurifier_Token_Start($wrapname);
                             $this->insertBefore($newtoken);
                             $reprocess = true;