ApiQueryBase: Fix addWhereFld for PHP 7.2
[lhc/web/wiklou.git] / includes / Message.php
index 0240fa7..16ae839 100644 (file)
@@ -1123,11 +1123,29 @@ class Message implements MessageSpecifier, Serializable {
         * @return string
         */
        protected function replaceParameters( $message, $type = 'before', $format ) {
+               // A temporary marker for $1 parameters that is only valid
+               // in non-attribute contexts. However if the entire message is escaped
+               // then we don't want to use it because it will be mangled in all contexts
+               // and its unnessary as ->escaped() messages aren't html.
+               $marker = $format === self::FORMAT_ESCAPED ? '$' : '$\'"';
                $replacementKeys = [];
                foreach ( $this->parameters as $n => $param ) {
                        list( $paramType, $value ) = $this->extractParam( $param, $format );
-                       if ( $type === $paramType ) {
-                               $replacementKeys['$' . ( $n + 1 )] = $value;
+                       if ( $type === 'before' ) {
+                               if ( $paramType === 'before' ) {
+                                       $replacementKeys['$' . ( $n + 1 )] = $value;
+                               } else /* $paramType === 'after' */ {
+                                       // To protect against XSS from replacing parameters
+                                       // inside html attributes, we convert $1 to $'"1.
+                                       // In the event that one of the parameters ends up
+                                       // in an attribute, either the ' or the " will be
+                                       // escaped, breaking the replacement and avoiding XSS.
+                                       $replacementKeys['$' . ( $n + 1 )] = $marker . ( $n + 1 );
+                               }
+                       } else {
+                               if ( $paramType === 'after' ) {
+                                       $replacementKeys[$marker . ( $n + 1 )] = $value;
+                               }
                        }
                }
                $message = strtr( $message, $replacementKeys );
@@ -1167,11 +1185,17 @@ class Message implements MessageSpecifier, Serializable {
                        } elseif ( isset( $param['list'] ) ) {
                                return $this->formatListParam( $param['list'], $param['type'], $format );
                        } else {
-                               $warning = 'Invalid parameter for message "' . $this->getKey() . '": ' .
-                                       htmlspecialchars( serialize( $param ) );
-                               trigger_error( $warning, E_USER_WARNING );
-                               $e = new Exception;
-                               wfDebugLog( 'Bug58676', $warning . "\n" . $e->getTraceAsString() );
+                               if ( !is_scalar( $param ) ) {
+                                       $param = serialize( $param );
+                               }
+                               \MediaWiki\Logger\LoggerFactory::getInstance( 'Bug58676' )->warning(
+                                       'Invalid parameter for message "{msgkey}": {param}',
+                                       [
+                                               'exception' => new Exception,
+                                               'msgkey' => $this->getKey(),
+                                               'param' => htmlspecialchars( $param ),
+                                       ]
+                               );
 
                                return [ 'before', '[INVALID]' ];
                        }
@@ -1220,7 +1244,9 @@ class Message implements MessageSpecifier, Serializable {
                        $this->getLanguage()
                );
 
-               return $out instanceof ParserOutput ? $out->getText() : $out;
+               return $out instanceof ParserOutput
+                       ? $out->getText( [ 'enableSectionEditLinks' => false ] )
+                       : $out;
        }
 
        /**