Index: moodle/lib/htmlpurifier/HTMLPurifier.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier.php	2010-10-28 22:23:39.052512622 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier.php	2010-10-28 22:23:48.572513303 +0100
@@ -19,7 +19,7 @@
  */
 
 /*
-    HTML Purifier 4.1.1 - Standards Compliant HTML Filtering
+    HTML Purifier 4.2.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 @@
 {
 
     /** Version of HTML Purifier */
-    public $version = '4.1.1';
+    public $version = '4.2.0';
 
     /** Constant with version of HTML Purifier */
-    const VERSION = '4.1.1';
+    const VERSION = '4.2.0';
 
     /** Global configuration object */
     public $config;
Index: moodle/lib/htmlpurifier/HTMLPurifier.safe-includes.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier.safe-includes.php	2010-10-28 22:23:39.102515145 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier.safe-includes.php	2010-10-28 22:23:48.572513303 +0100
@@ -190,10 +190,12 @@
 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';
Index: moodle/lib/htmlpurifier/HTMLPurifier/AttrDef/Lang.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/AttrDef/Lang.php	2010-10-28 22:23:39.152513826 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/AttrDef/Lang.php	2010-10-28 22:23:48.572513303 +0100
@@ -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;
 
Index: moodle/lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeParam.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeParam.php	2010-10-28 22:23:39.202514266 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeParam.php	2010-10-28 22:23:48.572513303 +0100
@@ -33,6 +33,13 @@
             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';
                 break;
Index: moodle/lib/htmlpurifier/HTMLPurifier/CSSDefinition.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/CSSDefinition.php	2010-10-28 22:23:39.252515105 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/CSSDefinition.php	2010-10-28 22:23:48.572513303 +0100
@@ -272,20 +272,29 @@
         // 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]);
+                }
+            }
+        }
+
     }
 }
 
Index: moodle/lib/htmlpurifier/HTMLPurifier/Config.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/Config.php	2010-10-28 22:23:39.312514701 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/Config.php	2010-10-28 22:23:48.572513303 +0100
@@ -20,7 +20,7 @@
     /**
      * HTML Purifier's version
      */
-    public $version = '4.1.1';
+    public $version = '4.2.0';
 
     /**
      * Bool indicator whether or not to automatically finalize
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt	2010-10-28 22:23:48.572513303 +0100
@@ -0,0 +1,13 @@
+CSS.ForbiddenProperties
+TYPE: lookup
+VERSION: 4.2.0
+DEFAULT: array()
+--DESCRIPTION--
+<p>
+    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.
+</p>
+--# vim: et sw=4 sts=4
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt	2010-10-28 22:23:48.572513303 +0100
@@ -0,0 +1,11 @@
+Core.NormalizeNewlines
+TYPE: bool
+VERSION: 4.2.0
+DEFAULT: true
+--DESCRIPTION--
+<p>
+    Whether or not to normalize newlines to the operating
+    system default.  When <code>false</code>, HTML Purifier
+    will attempt to preserve mixed newline files.
+</p>
+--# vim: et sw=4 sts=4
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt	2010-10-28 22:23:48.572513303 +0100
@@ -0,0 +1,11 @@
+Core.RemoveProcessingInstructions
+TYPE: bool
+VERSION: 4.2.0
+DEFAULT: false
+--DESCRIPTION--
+Instead of escaping processing instructions in the form <code>&lt;? ...
+?&gt;</code>, 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
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt	2010-10-28 22:23:39.482513539 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt	2010-10-28 22:23:48.572513303 +0100
@@ -4,6 +4,11 @@
 DEFAULT: false
 --DESCRIPTION--
 <p>
+  <strong>Warning:</strong> Deprecated in favor of %HTML.SafeObject and
+  %Output.FlashCompat (turn both on to allow YouTube videos and other
+  Flash content).
+</p>
+<p>
   This directive enables YouTube video embedding in HTML Purifier. Check
   <a href="http://htmlpurifier.org/docs/enduser-youtube.html">this document
   on embedding videos</a> for more information on what this filter does.
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt	2010-10-28 22:23:39.522514020 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt	2010-10-28 22:23:48.572513303 +0100
@@ -5,11 +5,14 @@
 --DESCRIPTION--
 
 <p>
-    This is a convenience directive that rolls the functionality of
-    %HTML.AllowedElements and %HTML.AllowedAttributes into one directive.
+    This is a preferred convenience directive that combines
+    %HTML.AllowedElements and %HTML.AllowedAttributes.
     Specify elements and attributes that are allowed using:
-    <code>element1[attr1|attr2],element2...</code>. You can also use
-    newlines instead of commas to separate elements.
+    <code>element1[attr1|attr2],element2...</code>.  For example,
+    if you would like to only allow paragraphs and links, specify
+    <code>a[href],p</code>.  You can specify attributes that apply
+    to all elements using an asterisk, e.g. <code>*[lang]</code>.
+    You can also use newlines instead of commas to separate elements.
 </p>
 <p>
     <strong>Warning</strong>:
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt	2010-10-28 22:23:39.572514903 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt	2010-10-28 22:23:48.582513544 +0100
@@ -4,12 +4,17 @@
 DEFAULT: NULL
 --DESCRIPTION--
 <p>
-    If HTML Purifier's tag set is unsatisfactory for your needs, you
-    can overload it with your own list of tags to allow.  Note that this
-    method is subtractive: it does its job by taking away from HTML Purifier
-    usual feature set, so you cannot add a tag that HTML Purifier never
-    supported in the first place (like embed, form or head).  If you
-    change this, you probably also want to change %HTML.AllowedAttributes.
+    If HTML Purifier's tag set is unsatisfactory for your needs, you can
+    overload it with your own list of tags to allow.  If you change
+    this, you probably also want to change %HTML.AllowedAttributes; see
+    also %HTML.Allowed which lets you set allowed elements and
+    attributes at the same time.
+</p>
+<p>
+    If you attempt to allow an element that HTML Purifier does not know
+    about, HTML Purifier will raise an error.  You will need to manually
+    tell HTML Purifier about this element by using the
+    <a href="http://htmlpurifier.org/docs/enduser-customize.html">advanced customization features.</a>
 </p>
 <p>
     <strong>Warning:</strong> If another directive conflicts with the
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt	2010-10-28 22:23:48.582513544 +0100
@@ -0,0 +1,11 @@
+HTML.FlashAllowFullScreen
+TYPE: bool
+VERSION: 4.2.0
+DEFAULT: false
+--DESCRIPTION--
+<p>
+    Whether or not to permit embedded Flash content from
+    %HTML.SafeObject to expand to the full screen.  Corresponds to
+    the <code>allowFullScreen</code> parameter.
+</p>
+--# vim: et sw=4 sts=4
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt	2010-10-28 22:23:39.662516546 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt	2010-10-28 22:23:48.582513544 +0100
@@ -12,6 +12,6 @@
 --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 <code>data</code> URI scheme, but it is not
-enabled by default.
+There is also support for the <code>data</code> and <code>file</code>
+URI schemes, but they are not enabled by default.
 --# vim: et sw=4 sts=4
Index: moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt	2010-10-28 22:23:39.722515705 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt	2010-10-28 22:23:48.582513544 +0100
@@ -1,12 +1,15 @@
 URI.DisableResources
 TYPE: bool
-VERSION: 1.3.0
+VERSION: 4.2.0
 DEFAULT: false
 --DESCRIPTION--
-
 <p>
     Disables embedding resources, essentially meaning no pictures. You can
     still link to them though. See %URI.DisableExternalResources for why
     this might be a good idea.
 </p>
+<p>
+    <em>Note:</em> While this directive has been available since 1.3.0,
+    it didn't actually start doing anything until 4.2.0.
+</p>
 --# vim: et sw=4 sts=4
Index: moodle/lib/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer.php	2010-10-28 22:23:39.762514225 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer.php	2010-10-28 22:23:48.582513544 +0100
@@ -109,6 +109,11 @@
      */
     private function _prepareDir($config) {
         $directory = $this->generateDirectoryPath($config);
+        //$chmod = $config->get('Cache.SerializerPermissions'); // it would be nice to get this accepted in upstream
+        global $CFG; $chmod = $CFG->directorypermissions;
+        if (!$chmod) {
+            $chmod = 0755;
+        }
         if (!is_dir($directory)) {
             $base = $this->generateBaseDirectoryPath($config);
             if (!is_dir($base)) {
@@ -116,13 +121,13 @@
                     please create or change using %Cache.SerializerPath',
                     E_USER_WARNING);
                 return false;
-            } elseif (!$this->_testPermissions($base)) {
+            } elseif (!$this->_testPermissions($base, $chmod)) {
                 return false;
             }
-            $old = umask(0022); // disable group and world writes
-            mkdir($directory);
+            $old = umask(0000);
+            mkdir($directory, $chmod);
             umask($old);
-        } elseif (!$this->_testPermissions($directory)) {
+        } elseif (!$this->_testPermissions($directory, $chmod)) {
             return false;
         }
         return true;
@@ -132,7 +137,7 @@
      * Tests permissions on a directory and throws out friendly
      * error messages and attempts to chmod it itself if possible
      */
-    private function _testPermissions($dir) {
+    private function _testPermissions($dir, $chmod) {
         // early abort, if it is writable, everything is hunky-dory
         if (is_writable($dir)) return true;
         if (!is_dir($dir)) {
@@ -146,17 +151,18 @@
             // POSIX system, we can give more specific advice
             if (fileowner($dir) === posix_getuid()) {
                 // we can chmod it ourselves
-                chmod($dir, 0755);
+                $chmod = $chmod | 0700;
+                chmod($dir, $chmod);
                 return true;
             } elseif (filegroup($dir) === posix_getgid()) {
-                $chmod = '775';
+                $chmod = $chmod | 0007;
             } else {
                 // PHP's probably running as nobody, so we'll
                 // need to give global permissions
-                $chmod = '777';
+                $chmod = $chmod | 0777;
             }
             trigger_error('Directory '.$dir.' not writable, '.
-                'please chmod to ' . $chmod,
+                'please chmod to ' . decoct($chmod),
                 E_USER_WARNING);
         } else {
             // generic error message
Index: moodle/lib/htmlpurifier/HTMLPurifier/Generator.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/Generator.php	2010-10-28 22:23:39.822513780 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/Generator.php	2010-10-28 22:23:48.582513544 +0100
@@ -98,9 +98,11 @@
         }
 
         // Normalize newlines to system defined value
-        $nl = $this->config->get('Output.Newline');
-        if ($nl === null) $nl = PHP_EOL;
-        if ($nl !== "\n") $html = str_replace("\n", $nl, $html);
+        if ($this->config->get('Core.NormalizeNewlines')) {
+            $nl = $this->config->get('Output.Newline');
+            if ($nl === null) $nl = PHP_EOL;
+            if ($nl !== "\n") $html = str_replace("\n", $nl, $html);
+        }
         return $html;
     }
 
@@ -215,7 +217,10 @@
      *               permissible for non-attribute output.
      * @return String escaped data.
      */
-    public function escape($string, $quote = ENT_COMPAT) {
+    public function escape($string, $quote = null) {
+        // Workaround for APC bug on Mac Leopard reported by sidepodcast
+        // http://htmlpurifier.org/phorum/read.php?3,4823,4846
+        if ($quote === null) $quote = ENT_COMPAT;
         return htmlspecialchars($string, $quote, 'UTF-8');
     }
 
Index: moodle/lib/htmlpurifier/HTMLPurifier/HTMLDefinition.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/HTMLDefinition.php	2010-10-28 22:23:39.872514933 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/HTMLDefinition.php	2010-10-28 22:23:48.582513544 +0100
@@ -300,7 +300,12 @@
                             unset($allowed_attributes_mutable[$key]);
                         }
                     }
-                    if ($delete) unset($this->info[$tag]->attr[$attr]);
+                    if ($delete) {
+                        if ($this->info[$tag]->attr[$attr]->required) {
+                            trigger_error("Required attribute '$attr' in element '$tag' was not allowed, which means '$tag' will not be allowed either", E_USER_WARNING);
+                        }
+                        unset($this->info[$tag]->attr[$attr]);
+                    }
                 }
             }
             // emit errors
Index: moodle/lib/htmlpurifier/HTMLPurifier/HTMLModule/Text.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/HTMLModule/Text.php	2010-10-28 22:23:39.912513693 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/HTMLModule/Text.php	2010-10-28 22:23:48.582513544 +0100
@@ -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') );
Index: moodle/lib/htmlpurifier/HTMLPurifier/HTMLModule/XMLCommonAttributes.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/HTMLModule/XMLCommonAttributes.php	2010-10-28 22:23:39.962515857 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/HTMLModule/XMLCommonAttributes.php	2010-10-28 22:23:48.582513544 +0100
@@ -5,11 +5,9 @@
     public $name = 'XMLCommonAttributes';
 
     public $attr_collections = array(
-/* moodle comment - xml:lang breaks our multilang
         'Lang' => array(
             'xml:lang' => 'LanguageCode',
         )
-*/
     );
 }
 
Index: moodle/lib/htmlpurifier/HTMLPurifier/Injector/SafeObject.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/Injector/SafeObject.php	2010-10-28 22:23:40.022517580 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/Injector/SafeObject.php	2010-10-28 22:23:48.582513544 +0100
@@ -22,6 +22,7 @@
         'movie' => true,
         'flashvars' => true,
         'src' => true,
+        'allowFullScreen' => true, // if omitted, assume to be 'false'
     );
 
     public function prepare($config, $context) {
Index: moodle/lib/htmlpurifier/HTMLPurifier/Lexer.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/Lexer.php	2010-10-28 22:23:40.072513023 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/Lexer.php	2010-10-28 22:23:48.592513104 +0100
@@ -231,6 +231,17 @@
     }
 
     /**
+     * Special Internet Explorer conditional comments should be removed.
+     */
+    protected static function removeIEConditional($string) {
+        return preg_replace(
+            '#<!--\[if [^>]+\]>.*<!\[endif\]-->#si', // probably should generalize for all strings
+            '',
+            $string
+        );
+    }
+
+    /**
      * Callback function for escapeCDATA() that does the work.
      *
      * @warning Though this is public in order to let the callback happen,
@@ -252,7 +263,7 @@
     public function normalize($html, $config, $context) {
 
         // normalize newlines to \n
-        if ($config->get('Output.Newline')!=="\n") {
+        if ($config->get('Core.NormalizeNewlines')) {
             $html = str_replace("\r\n", "\n", $html);
             $html = str_replace("\r", "\n", $html);
         }
@@ -262,6 +273,8 @@
             $html = $this->escapeCommentedCDATA($html);
         }
 
+        $html = $this->removeIEConditional($html);
+
         // escape CDATA
         $html = $this->escapeCDATA($html);
 
@@ -286,6 +299,11 @@
         // represent non-SGML characters (horror, horror!)
         $html = HTMLPurifier_Encoder::cleanUTF8($html);
 
+        // if processing instructions are to removed, remove them now
+        if ($config->get('Core.RemoveProcessingInstructions')) {
+            $html = preg_replace('#<\?.+?\?>#s', '', $html);
+        }
+
         return $html;
     }
 
Index: moodle/lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php	2010-10-28 22:23:40.132512625 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php	2010-10-28 22:23:48.592513104 +0100
@@ -125,8 +125,6 @@
     const EOF      = 5;
 
     public function __construct($data) {
-        $data = str_replace("\r\n", "\n", $data);
-        $data = str_replace("\r", null, $data);
 
         $this->data = $data;
         $this->char = -1;
Index: moodle/lib/htmlpurifier/HTMLPurifier/URIFilter/DisableResources.php
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ moodle/lib/htmlpurifier/HTMLPurifier/URIFilter/DisableResources.php	2010-10-28 22:23:48.592513104 +0100
@@ -0,0 +1,11 @@
+<?php
+
+class HTMLPurifier_URIFilter_DisableResources extends HTMLPurifier_URIFilter
+{
+    public $name = 'DisableResources';
+    public function filter(&$uri, $config, $context) {
+        return !$context->get('EmbeddedURI', true);
+    }
+}
+
+// vim: et sw=4 sts=4
Index: moodle/lib/htmlpurifier/HTMLPurifier/URIScheme/file.php
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ moodle/lib/htmlpurifier/HTMLPurifier/URIScheme/file.php	2010-10-28 22:23:48.592513104 +0100
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * Validates file as defined by RFC 1630 and RFC 1738.
+ */
+class HTMLPurifier_URIScheme_file extends HTMLPurifier_URIScheme {
+
+    // Generally file:// URLs are not accessible from most
+    // machines, so placing them as an img src is incorrect.
+    public $browsable = false;
+
+    public function validate(&$uri, $config, $context) {
+        parent::validate($uri, $config, $context);
+        // Authentication method is not supported
+        $uri->userinfo = null;
+        // file:// makes no provisions for accessing the resource
+        $uri->port     = null;
+        // While it seems to work on Firefox, the querystring has
+        // no possible effect and is thus stripped.
+        $uri->query    = null;
+        return true;
+    }
+
+}
+
+// vim: et sw=4 sts=4
Index: moodle/lib/htmlpurifier/HTMLPurifier/VarParser/Flexible.php
===================================================================
--- moodle.orig/lib/htmlpurifier/HTMLPurifier/VarParser/Flexible.php	2010-10-28 22:23:40.262513505 +0100
+++ moodle/lib/htmlpurifier/HTMLPurifier/VarParser/Flexible.php	2010-10-28 22:23:48.592513104 +0100
@@ -62,7 +62,7 @@
                         foreach ($var as $keypair) {
                             $c = explode(':', $keypair, 2);
                             if (!isset($c[1])) continue;
-                            $nvar[$c[0]] = $c[1];
+                            $nvar[trim($c[0])] = trim($c[1]);
                         }
                         $var = $nvar;
                     }
@@ -79,8 +79,15 @@
                         return $new;
                     } else break;
                 }
+                if ($type === self::ALIST) {
+                    trigger_error("Array list did not have consecutive integer indexes", E_USER_WARNING);
+                    return array_values($var);
+                }
                 if ($type === self::LOOKUP) {
                     foreach ($var as $key => $value) {
+                        if ($value !== true) {
+                            trigger_error("Lookup array has non-true value at key '$key'; maybe your input array was not indexed numerically", E_USER_WARNING);
+                        }
                         $var[$key] = true;
                     }
                 }
Index: moodle/lib/htmlpurifier/readme_moodle.txt
===================================================================
--- moodle.orig/lib/htmlpurifier/readme_moodle.txt	2010-10-28 22:23:40.312513541 +0100
+++ moodle/lib/htmlpurifier/readme_moodle.txt	2010-10-28 22:23:48.592513104 +0100
@@ -1,9 +1,6 @@
-Description of HTML Purifier v4.1.1 library import into Moodle
+Description of HTML Purifier v4.2.0 library import into Moodle
 
 Changes:
- * HMLTModule/Text.php - added  <nolink>, <tex>, <lang> and <algebra> tags
- * HMLTModule/XMLCommonAttributes.php - remove xml:lang - needed for multilang
- * AttrDef/Lang.php - relax lang check - needed for multilang
- * Lexer.php - Subverted line break normalisation (requires setting: Output.Newline to \n) MDL-22654
+ * DefinitionCache/Serializer.php - using our directory permissions
 
 skodak
Index: moodle/lib/weblib.php
===================================================================
--- moodle.orig/lib/weblib.php	2010-10-28 22:23:40.362517575 +0100
+++ moodle/lib/weblib.php	2010-10-28 22:23:48.602512385 +0100
@@ -2056,23 +2056,51 @@
 
     // this can not be done only once because we sometimes need to reset the cache
     $cachedir = $CFG->dataroot.'/cache/htmlpurifier';
-    $status = check_dir_exists($cachedir, true, true);
+    check_dir_exists($cachedir);
 
     static $purifier = false;
-    static $config;
     if ($purifier === false) {
         require_once $CFG->libdir.'/htmlpurifier/HTMLPurifier.safe-includes.php';
         $config = HTMLPurifier_Config::createDefault();
-        $config->set('Output.Newline', "\n");
+
+        $config->set('HTML.DefinitionID', 'moodlehtml');
+        $config->set('HTML.DefinitionRev', 1);
+        $config->set('Cache.SerializerPath', $cachedir);
+        //$config->set('Cache.SerializerPermission', $CFG->directorypermissions); // it would be nice to get this upstream
+        $config->set('Core.NormalizeNewlines', false);
         $config->set('Core.ConvertDocumentToFragment', true);
         $config->set('Core.Encoding', 'UTF-8');
         $config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
-        $config->set('Cache.SerializerPath', $cachedir);
-        $config->set('URI.AllowedSchemes', array('http'=>1, 'https'=>1, 'ftp'=>1, 'irc'=>1, 'nntp'=>1, 'news'=>1, 'rtsp'=>1, 'teamspeak'=>1, 'gopher'=>1, 'mms'=>1));
+        $config->set('URI.AllowedSchemes', array('http'=>true, 'https'=>true, 'ftp'=>true, 'irc'=>true, 'nntp'=>true, 'news'=>true, 'rtsp'=>true, 'teamspeak'=>true, 'gopher'=>true, 'mms'=>true));
         $config->set('Attr.AllowedFrameTargets', array('_blank'));
+
+        if (!empty($CFG->allowobjectembed)) {
+            $config->set('HTML.SafeObject', true);
+            $config->set('Output.FlashCompat', true);
+            $config->set('HTML.SafeEmbed', true);
+        }
+
+        $def = $config->getHTMLDefinition(true);
+        $def->addElement('nolink', 'Block', 'Flow', array());                       // skip our filters inside
+        $def->addElement('tex', 'Inline', 'Inline', array());                       // tex syntax, equivalent to $$xx$$
+        $def->addElement('algebra', 'Inline', 'Inline', array());                   // algebra syntax, equivalent to @@xx@@
+        $def->addElement('lang', 'Block', 'Flow', array(), array('lang'=>'CDATA')); // old anf future style multilang - only our hacked lang attribute
+        $def->addAttribute('span', 'xxxlang', 'CDATA');                             // current problematic multilang
+
         $purifier = new HTMLPurifier($config);
     }
-    return $purifier->purify($text);
+
+    $multilang = (strpos($text, 'class="multilang"') !== false);
+
+    if ($multilang) {
+        $text = preg_replace('/<span(\s+lang="([a-zA-Z0-9_-]+)"|\s+class="multilang"){2}\s*>/', '<span xxxlang="${2}">', $text);
+    }
+    $text = $purifier->purify($text);
+    if ($multilang) {
+        $text = preg_replace('/<span xxxlang="([a-zA-Z0-9_-]+)">/', '<span lang="${1}" class="multilang">', $text);
+    }
+
+    return $text;
 }
 
 /**
