(bug 10055) Populate email address and real name properties of User objects passed...
[lhc/web/wiklou.git] / includes / Sanitizer.php
index 51c751c..fa5416d 100644 (file)
@@ -28,7 +28,7 @@
  * Sanitizer::normalizeCharReferences and Sanitizer::decodeCharReferences
  */
 define( 'MW_CHAR_REFS_REGEX',
-       '/&([A-Za-z0-9]+);
+       '/&([A-Za-z0-9\x80-\xff]+);
         |&\#([0-9]+);
         |&\#x([0-9A-Za-z]+);
         |&\#X([0-9A-Za-z]+);
@@ -315,6 +315,20 @@ $wgHtmlEntities = array(
        'zwj'      => 8205,
        'zwnj'     => 8204 );
 
+/**
+ * Character entity aliases accepted by MediaWiki
+ */
+global $wgHtmlEntityAliases;
+$wgHtmlEntityAliases = array(
+       'רלמ' => 'rlm',
+       'رلم' => 'rlm',
+);
+
+
+/**
+ * XHTML sanitizer for MediaWiki
+ * @addtogroup Parser
+ */
 class Sanitizer {
        /**
         * Cleans up HTML, removes dangerous tags and attributes, and
@@ -326,7 +340,7 @@ class Sanitizer {
         * @return string
         */
        static function removeHTMLtags( $text, $processCallback = null, $args = array() ) {
-               global $wgUseTidy, $wgUserHtml;
+               global $wgUseTidy;
 
                static $htmlpairs, $htmlsingle, $htmlsingleonly, $htmlnest, $tabletags,
                        $htmllist, $listtags, $htmlsingleallowed, $htmlelements, $staticInitialised;
@@ -334,40 +348,33 @@ class Sanitizer {
                wfProfileIn( __METHOD__ );
 
                if ( !$staticInitialised ) {
-                       if( $wgUserHtml ) {
-                               $htmlpairs = array( # Tags that must be closed
-                                       'b', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1',
-                                       'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's',
-                                       'strike', 'strong', 'tt', 'var', 'div', 'center',
-                                       'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre',
-                                       'ruby', 'rt' , 'rb' , 'rp', 'p', 'span', 'u'
-                               );
-                               $htmlsingle = array(
-                                       'br', 'hr', 'li', 'dt', 'dd'
-                               );
-                               $htmlsingleonly = array( # Elements that cannot have close tags
-                                       'br', 'hr'
-                               );
-                               $htmlnest = array( # Tags that can be nested--??
-                                       'table', 'tr', 'td', 'th', 'div', 'blockquote', 'ol', 'ul',
-                                       'dl', 'font', 'big', 'small', 'sub', 'sup', 'span'
-                               );
-                               $tabletags = array( # Can only appear inside table, we will close them
-                                       'td', 'th', 'tr',
-                               );
-                               $htmllist = array( # Tags used by list
-                                       'ul','ol',
-                               );
-                               $listtags = array( # Tags that can appear in a list
-                                       'li',
-                               );
-
-                       } else {
-                               $htmlpairs = array();
-                               $htmlsingle = array();
-                               $htmlnest = array();
-                               $tabletags = array();
-                       }
+
+                       $htmlpairs = array( # Tags that must be closed
+                               'b', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1',
+                               'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's',
+                               'strike', 'strong', 'tt', 'var', 'div', 'center',
+                               'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre',
+                               'ruby', 'rt' , 'rb' , 'rp', 'p', 'span', 'u'
+                       );
+                       $htmlsingle = array(
+                               'br', 'hr', 'li', 'dt', 'dd'
+                       );
+                       $htmlsingleonly = array( # Elements that cannot have close tags
+                               'br', 'hr'
+                       );
+                       $htmlnest = array( # Tags that can be nested--??
+                               'table', 'tr', 'td', 'th', 'div', 'blockquote', 'ol', 'ul',
+                               'dl', 'font', 'big', 'small', 'sub', 'sup', 'span'
+                       );
+                       $tabletags = array( # Can only appear inside table, we will close them
+                               'td', 'th', 'tr',
+                       );
+                       $htmllist = array( # Tags used by list
+                               'ul','ol',
+                       );
+                       $listtags = array( # Tags that can appear in a list
+                               'li',
+                       );
 
                        $htmlsingleallowed = array_merge( $htmlsingle, $tabletags );
                        $htmlelements = array_merge( $htmlsingle, $htmlpairs, $htmlnest );
@@ -615,7 +622,7 @@ class Sanitizer {
                $stripped = preg_replace( '!\\\\([0-9A-Fa-f]{1,6})[ \\n\\r\\t\\f]?!e',
                        'codepointToUtf8(hexdec("$1"))', $stripped );
                $stripped = str_replace( '\\', '', $stripped );
-               if( preg_match( '/(expression|tps*:\/\/|url\\s*\().*/is',
+               if( preg_match( '/(?:expression|tps*:\/\/|url\\s*\().*/is',
                                $stripped ) ) {
                        # haxx0r
                        return false;
@@ -718,12 +725,10 @@ class Sanitizer {
         * Given a value escape it so that it can be used in an id attribute and
         * return it, this does not validate the value however (see first link)
         *
-        * @link http://www.w3.org/TR/html401/types.html#type-name Valid characters
+        * @see http://www.w3.org/TR/html401/types.html#type-name Valid characters
         *                                                          in the id and
         *                                                          name attributes
-        * @link http://www.w3.org/TR/html401/struct/links.html#h-12.2.3 Anchors with the id attribute
-        *
-        * @bug 4461
+        * @see http://www.w3.org/TR/html401/struct/links.html#h-12.2.3 Anchors with the id attribute
         *
         * @static
         *
@@ -747,7 +752,7 @@ class Sanitizer {
         *
         * @todo For extra validity, input should be validated UTF-8.
         *
-        * @link http://www.w3.org/TR/CSS21/syndata.html Valid characters/format
+        * @see http://www.w3.org/TR/CSS21/syndata.html Valid characters/format
         *
         * @param string $class
         * @return string
@@ -852,11 +857,16 @@ class Sanitizer {
         */
        private static function normalizeAttributeValue( $text ) {
                return str_replace( '"', '"',
-                       preg_replace(
-                               '/\r\n|[\x20\x0d\x0a\x09]/',
-                               ' ',
+                       self::normalizeWhitespace(
                                Sanitizer::normalizeCharReferences( $text ) ) );
        }
+       
+       private static function normalizeWhitespace( $text ) {
+               return preg_replace(
+                       '/\r\n|[\x20\x0d\x0a\x09]/',
+                       ' ',
+                       $text );
+       }
 
        /**
         * Ensure that any entities and character references are legal
@@ -902,16 +912,19 @@ class Sanitizer {
 
        /**
         * If the named entity is defined in the HTML 4.0/XHTML 1.0 DTD,
-        * return the named entity reference as is. Otherwise, returns
-        * HTML-escaped text of pseudo-entity source (eg &foo;)
+        * return the named entity reference as is. If the entity is a 
+        * MediaWiki-specific alias, returns the HTML equivalent. Otherwise, 
+        * returns HTML-escaped text of pseudo-entity source (eg &foo;)
         *
         * @param string $name
         * @return string
         * @static
         */
        static function normalizeEntity( $name ) {
-               global $wgHtmlEntities;
-               if( isset( $wgHtmlEntities[$name] ) ) {
+               global $wgHtmlEntities, $wgHtmlEntityAliases;
+               if ( isset( $wgHtmlEntityAliases[$name] ) ) {
+                       return "&{$wgHtmlEntityAliases[$name]};";
+               } elseif( isset( $wgHtmlEntities[$name] ) ) {
                        return "&$name;";
                } else {
                        return "&$name;";
@@ -1008,7 +1021,10 @@ class Sanitizer {
         * @return string
         */
        static function decodeEntity( $name ) {
-               global $wgHtmlEntities;
+               global $wgHtmlEntities, $wgHtmlEntityAliases;
+               if ( isset( $wgHtmlEntityAliases[$name] ) ) {
+                       $name = $wgHtmlEntityAliases[$name];
+               }
                if( isset( $wgHtmlEntities[$name] ) ) {
                        return codepointToUtf8( $wgHtmlEntities[$name] );
                } else {
@@ -1175,8 +1191,10 @@ class Sanitizer {
 
        /**
         * Take a fragment of (potentially invalid) HTML and return
-        * a version with any tags removed, encoded suitably for literal
-        * inclusion in an attribute value.
+        * a version with any tags removed, encoded as plain text.
+        *
+        * Warning: this return value must be further escaped for literal
+        * inclusion in HTML output as of 1.10!
         *
         * @param string $text HTML fragment
         * @return string
@@ -1186,14 +1204,8 @@ class Sanitizer {
                $text = StringUtils::delimiterReplace( '<', '>', '', $text );
 
                # Normalize &entities and whitespace
-               $text = Sanitizer::normalizeAttributeValue( $text );
-
-               # Will be placed into "double-quoted" attributes,
-               # make sure remaining bits are safe.
-               $text = str_replace(
-                       array('<', '>', '"'),
-                       array('&lt;', '&gt;', '&quot;'),
-                       $text );
+               $text = self::decodeCharReferences( $text );
+               $text = self::normalizeWhitespace( $text );
 
                return $text;
        }