diff --git a/src/Illuminate/Http/JsonResponse.php b/src/Illuminate/Http/JsonResponse.php index 3e065d8603ab..7bf257b93b37 100755 --- a/src/Illuminate/Http/JsonResponse.php +++ b/src/Illuminate/Http/JsonResponse.php @@ -86,9 +86,24 @@ public function setData($data = []) */ protected function hasValidJson($jsonError) { - return $jsonError === JSON_ERROR_NONE || - ($jsonError === JSON_ERROR_UNSUPPORTED_TYPE && - $this->hasEncodingOption(JSON_PARTIAL_OUTPUT_ON_ERROR)); + // No error is obviously fine + if ($jsonError === JSON_ERROR_NONE) { + return true; + } + + // If the JSON_PARTIAL_OUTPUT_ON_ERROR option is set, some additional errors are fine + // (see https://secure.php.net/manual/en/json.constants.php) + if ($this->hasEncodingOption(JSON_PARTIAL_OUTPUT_ON_ERROR)) { + $acceptableErrors = [ + JSON_ERROR_RECURSION, + JSON_ERROR_INF_OR_NAN, + JSON_ERROR_UNSUPPORTED_TYPE, + ]; + + return \in_array($jsonError, $acceptableErrors); + } + + return false; } /** diff --git a/tests/Http/HttpJsonResponseTest.php b/tests/Http/HttpJsonResponseTest.php index 46761942d043..e310a976c99f 100644 --- a/tests/Http/HttpJsonResponseTest.php +++ b/tests/Http/HttpJsonResponseTest.php @@ -75,22 +75,49 @@ public function testSetAndRetrieveStatusCode() } /** + * @param mixed $data + * * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Type is not supported + * + * @dataProvider jsonErrorDataProvider */ - public function testJsonErrorResource() + public function testInvalidArgumentExceptionOnJsonError($data) { - $resource = tmpfile(); - $response = new \Illuminate\Http\JsonResponse(['resource' => $resource]); + new \Illuminate\Http\JsonResponse(['data' => $data]); } - public function testJsonErrorResourceWithPartialOutputOnError() + /** + * @param mixed $data + * + * @dataProvider jsonErrorDataProvider + */ + public function testGracefullyHandledSomeJsonErrorsWithPartialOutputOnError($data) { + new \Illuminate\Http\JsonResponse(['data' => $data], 200, [], JSON_PARTIAL_OUTPUT_ON_ERROR); + } + + /** + * @return array + */ + public function jsonErrorDataProvider() + { + // Resources can't be encoded $resource = tmpfile(); - $response = new \Illuminate\Http\JsonResponse(['resource' => $resource], 200, [], JSON_PARTIAL_OUTPUT_ON_ERROR); - $data = $response->getData(); - $this->assertInstanceOf('stdClass', $data); - $this->assertNull($data->resource); + + // Recursion can't be encoded + $recursiveObject = new \stdClass(); + $objectB = new \stdClass(); + $recursiveObject->b = $objectB; + $objectB->a = $recursiveObject; + + // NAN or INF can't be encoded + $nan = NAN; + + return [ + [$resource], + [$recursiveObject], + [$nan], + ]; } }