From: Brad Jorsch Date: Thu, 14 Jan 2016 21:11:44 +0000 (-0500) Subject: API: Work around PHP bug 45959 X-Git-Tag: 1.31.0-rc.0~8315^2 X-Git-Url: https://git.cyclocoop.org/%27.%24link.%27?a=commitdiff_plain;h=8deb49f534073304fd501a96ef3fac7bda4c76ce;p=lhc%2Fweb%2Fwiklou.git API: Work around PHP bug 45959 Sigh, PHP. You allow for an array to have string "1" as a key (e.g. when casting from object to array), but then you do everything wrong when trying to deal with it. Bug: T123663 Change-Id: I49f09901a69aab39ca1519bbe9e41267bf9a1216 --- diff --git a/includes/api/ApiResult.php b/includes/api/ApiResult.php index bd5fe08cea..71af80cf97 100644 --- a/includes/api/ApiResult.php +++ b/includes/api/ApiResult.php @@ -364,9 +364,13 @@ class ApiResult implements ApiSerializable { } } if ( is_array( $value ) ) { + // Work around PHP bug 45959 by copying to a temporary + // (in this case, foreach gets $k === "1" but $tmp[$k] assigns as if $k === 1) + $tmp = array(); foreach ( $value as $k => $v ) { - $value[$k] = self::validateValue( $v ); + $tmp[$k] = self::validateValue( $v ); } + $value = $tmp; } elseif ( is_float( $value ) && !is_finite( $value ) ) { throw new InvalidArgumentException( "Cannot add non-finite floats to ApiResult" ); } elseif ( is_string( $value ) ) { diff --git a/tests/phpunit/includes/api/ApiResultTest.php b/tests/phpunit/includes/api/ApiResultTest.php index 9dbde3d93f..292d276b68 100644 --- a/tests/phpunit/includes/api/ApiResultTest.php +++ b/tests/phpunit/includes/api/ApiResultTest.php @@ -218,6 +218,17 @@ class ApiResultTest extends MediaWikiTestCase { 0 => "foo\xef\xbf\xbdbar", 1 => "\xc3\xa1", ), $arr ); + + $obj = new stdClass; + $obj->{'1'} = 'one'; + $arr = array(); + ApiResult::setValue( $arr, 'foo', $obj ); + $this->assertSame( array( + 'foo' => array( + 1 => 'one', + ApiResult::META_TYPE => 'assoc', + ) + ), $arr ); } /** @@ -509,6 +520,19 @@ class ApiResultTest extends MediaWikiTestCase { 1 => "\xc3\xa1", ApiResult::META_TYPE => 'assoc', ), $result->getResultData() ); + + $result = new ApiResult( 8388608 ); + $obj = new stdClass; + $obj->{'1'} = 'one'; + $arr = array(); + $result->addValue( $arr, 'foo', $obj ); + $this->assertSame( array( + 'foo' => array( + 1 => 'one', + ApiResult::META_TYPE => 'assoc', + ), + ApiResult::META_TYPE => 'assoc', + ), $result->getResultData() ); } /**