From cb300f7b6cd87261759a305d8c69bd291a3b639c Mon Sep 17 00:00:00 2001 From: Alexandru Guzinschi Date: Wed, 11 Mar 2015 13:44:02 +0200 Subject: [PATCH] [Fix] Invalid JSON in response trigger fatal error If the server responded with an invalid JSON for `getAccessToken()`, $result variable will be of type string instead of expected array. This will result in a fatal error was being raised in AbstractProvider when calling `prepareAccessTokenResult` method, which expects an argument of type array. Proposed solution is to set the variable `$result` to an empty array if json_decode was not successful. Doesn't make sense to throw an expection at this point, because response will not have an access_token and an `InvalidArgumentException` will be thrown latter when `$grant->handleResponse()` will be called. Fix #230 --- src/Provider/AbstractProvider.php | 5 +++++ test/src/Provider/GithubTest.php | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Provider/AbstractProvider.php b/src/Provider/AbstractProvider.php index c43a0fd..ccbb249 100644 --- a/src/Provider/AbstractProvider.php +++ b/src/Provider/AbstractProvider.php @@ -205,6 +205,11 @@ abstract class AbstractProvider implements ProviderInterface switch ($this->responseType) { case 'json': $result = json_decode($response, true); + + if (JSON_ERROR_NONE !== json_last_error()) { + $result = []; + } + break; case 'string': parse_str($response, $result); diff --git a/test/src/Provider/GithubTest.php b/test/src/Provider/GithubTest.php index b0e14db..dd66f50 100644 --- a/test/src/Provider/GithubTest.php +++ b/test/src/Provider/GithubTest.php @@ -65,6 +65,25 @@ class GithubTest extends \PHPUnit_Framework_TestCase $this->assertEquals('1', $token->uid); } + /** + * @ticket 230 + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Required option not passed: access_token + */ + public function testGetAccessTokenWithInvalidJson() + { + $response = m::mock('Guzzle\Http\Message\Response'); + $response->shouldReceive('getBody')->times(1)->andReturn('invalid'); + + $client = m::mock('Guzzle\Service\Client'); + $client->shouldReceive('setBaseUrl')->times(1); + $client->shouldReceive('post->send')->times(1)->andReturn($response); + $this->provider->setHttpClient($client); + $this->provider->responseType = 'json'; + + $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']); + } + public function testGetAccessTokenSetResultUid() { $this->provider->uidKey = 'otherKey';