Merge "Remove unreachable block"
[lhc/web/wiklou.git] / includes / Sanitizer.php
index cd936f3..fbf3234 100644 (file)
@@ -963,7 +963,8 @@ class Sanitizer {
                $value = self::normalizeCss( $value );
 
                // Reject problematic keywords and control characters
-               if ( preg_match( '/[\000-\010\013\016-\037\177]/', $value ) ) {
+               if ( preg_match( '/[\000-\010\013\016-\037\177]/', $value ) ||
+                       strpos( $value, UtfNormal\Constants::UTF8_REPLACEMENT ) !== false ) {
                        return '/* invalid control char */';
                } elseif ( preg_match(
                        '! expression
@@ -1393,15 +1394,19 @@ class Sanitizer {
        }
 
        /**
-        * Returns true if a given Unicode codepoint is a valid character in XML.
+        * Returns true if a given Unicode codepoint is a valid character in
+        * both HTML5 and XML.
         * @param int $codepoint
         * @return bool
         */
        private static function validateCodepoint( $codepoint ) {
+               # U+000C is valid in HTML5 but not allowed in XML.
+               # U+000D is valid in XML but not allowed in HTML5.
+               # U+007F - U+009F are disallowed in HTML5 (control characters).
                return $codepoint == 0x09
                        || $codepoint == 0x0a
-                       || $codepoint == 0x0d
-                       || ( $codepoint >= 0x20 && $codepoint <= 0xd7ff )
+                       || ( $codepoint >= 0x20 && $codepoint <= 0x7e )
+                       || ( $codepoint >= 0xa0 && $codepoint <= 0xd7ff )
                        || ( $codepoint >= 0xe000 && $codepoint <= 0xfffd )
                        || ( $codepoint >= 0x10000 && $codepoint <= 0x10ffff );
        }
@@ -1803,6 +1808,11 @@ class Sanitizer {
 
                        $host = preg_replace( $strip, '', $host );
 
+                       // IPv6 host names are bracketed with [].  Url-decode these.
+                       if ( substr_compare( "//%5B", $host, 0, 5 ) === 0 && preg_match( '!^//%5B(.*?)%5D((:\d+)?)$!', $host, $matches ) ) {
+                               $host = '//[' . $matches[1] . ']' . $matches[2];
+                       }
+
                        // @todo FIXME: Validate hostnames here
 
                        return $protocol . $host . $rest;