Armor against French spaces detection in HTML attributes
[lhc/web/wiklou.git] / includes / parser / Sanitizer.php
index 118442d..89a7c96 100644 (file)
@@ -1141,6 +1141,27 @@ class Sanitizer {
                return $encValue;
        }
 
+       /**
+        * Armor French spaces with a replacement character
+        *
+        * @since 1.32
+        * @param string $text Text to armor
+        * @param string $space Space character for the French spaces, defaults to ' '
+        * @return string Armored text
+        */
+       public static function armorFrenchSpaces( $text, $space = ' ' ) {
+               // Replace $ with \$ and \ with \\
+               $space = preg_replace( '#(?<!\\\\)(\\$|\\\\)#', '\\\\$1', $space );
+               $fixtags = [
+                       # French spaces, last one Guillemet-left
+                       # only if there is something before the space
+                       '/(.) (?=\\?|:|;|!|%|\\302\\273)/' => "\\1$space",
+                       # French spaces, Guillemet-right
+                       '/(\\302\\253) /' => "\\1$space",
+               ];
+               return preg_replace( array_keys( $fixtags ), array_values( $fixtags ), $text );
+       }
+
        /**
         * Encode an attribute value for HTML tags, with extra armoring
         * against further wiki processing.
@@ -1168,6 +1189,9 @@ class Sanitizer {
                        '__'   => '&#95;_',
                ] );
 
+               # Armor against French spaces detection (T5158)
+               $encValue = self::armorFrenchSpaces( $encValue, '&#32;' );
+
                # Stupid hack
                $encValue = preg_replace_callback(
                        '/((?i)' . wfUrlProtocols() . ')/',
@@ -1706,9 +1730,7 @@ class Sanitizer {
         */
        static function attributeWhitelist( $element ) {
                $list = self::setupAttributeWhitelist();
-               return isset( $list[$element] )
-                       ? $list[$element]
-                       : [];
+               return $list[$element] ?? [];
        }
 
        /**