From 7f2663fb916e582335255bb1eef932ccbbe98f41 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Wed, 7 Dec 2016 10:21:24 -0500 Subject: [PATCH] Message: Fix buggy parameter handling in Message::params() Message::params() wants to take parameters either varargs-style or as a single array. But it also detects "special" parameters like those returned from Message::numParam() as an array of parameters instead of as a single "special" parameter. Bug: T152603 Change-Id: Idef2437470eee843a17ff23f4cefe8f3132988bd --- includes/Message.php | 26 ++++++++++++++++------ tests/phpunit/includes/MessageTest.php | 30 ++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/includes/Message.php b/includes/Message.php index 7e5cc7dca2..9c0ab1ce28 100644 --- a/includes/Message.php +++ b/includes/Message.php @@ -488,18 +488,32 @@ class Message implements MessageSpecifier, Serializable { * * @since 1.17 * - * @param mixed ... Parameters as strings, or a single argument that is - * an array of strings. + * @param mixed ... Parameters as strings or arrays from + * Message::numParam() and the like, or a single array of parameters. * * @return Message $this */ public function params( /*...*/ ) { $args = func_get_args(); - if ( isset( $args[0] ) && is_array( $args[0] ) ) { - $args = $args[0]; + + // If $args has only one entry and it's an array, then it's either a + // non-varargs call or it happens to be a call with just a single + // "special" parameter. Since the "special" parameters don't have any + // numeric keys, we'll test that to differentiate the cases. + if ( count( $args ) === 1 && isset( $args[0] ) && is_array( $args[0] ) ) { + if ( $args[0] === [] ) { + $args = []; + } else { + foreach ( $args[0] as $key => $value ) { + if ( is_int( $key ) ) { + $args = $args[0]; + break; + } + } + } } - $args_values = array_values( $args ); - $this->parameters = array_merge( $this->parameters, $args_values ); + + $this->parameters = array_merge( $this->parameters, array_values( $args ) ); return $this; } diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php index 4fe806c438..2d45c2ebf5 100644 --- a/tests/phpunit/includes/MessageTest.php +++ b/tests/phpunit/includes/MessageTest.php @@ -51,6 +51,10 @@ class MessageTest extends MediaWikiLangTestCase { [], [], ], + [ + [], + [ [] ], + ], [ [ 'foo' ], [ 'foo' ], @@ -68,19 +72,37 @@ class MessageTest extends MediaWikiLangTestCase { [ [ 'baz', 'foo' ] ], ], [ - [ 'baz', 'foo' ], + [ Message::rawParam( 'baz' ) ], + [ Message::rawParam( 'baz' ) ], + ], + [ + [ Message::rawParam( 'baz' ), 'foo' ], + [ Message::rawParam( 'baz' ), 'foo' ], + ], + [ + [ Message::rawParam( 'baz' ) ], + [ [ Message::rawParam( 'baz' ) ] ], + ], + [ + [ Message::rawParam( 'baz' ), 'foo' ], + [ [ Message::rawParam( 'baz' ), 'foo' ] ], + ], + + // Test handling of erroneous input, to detect if it changes + [ + [ [ 'baz', 'foo' ], 'hhh' ], [ [ 'baz', 'foo' ], 'hhh' ], ], [ - [ 'baz', 'foo' ], + [ [ 'baz', 'foo' ], 'hhh', [ 'ahahahahha' ] ], [ [ 'baz', 'foo' ], 'hhh', [ 'ahahahahha' ] ], ], [ - [ 'baz', 'foo' ], + [ [ 'baz', 'foo' ], [ 'ahahahahha' ] ], [ [ 'baz', 'foo' ], [ 'ahahahahha' ] ], ], [ - [ 'baz' ], + [ [ 'baz' ], [ 'ahahahahha' ] ], [ [ 'baz' ], [ 'ahahahahha' ] ], ], ]; -- 2.20.1