bug #11418 [JsonResponse] Silent only JSON errors (GromNaN)

This PR was submitted for the master branch but it was merged into the 2.5 branch instead (closes #11418).

Discussion
----------

[JsonResponse] Silent only JSON errors

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | maybe
| Fixed tickets | #11415
| License       | MIT
| Doc PR        | n/a

Commits
-------

6d6a3af Clear json_last_error
ef91f71 Fix JsonSerializable namespace
d952f90 Catch exceptions to restore the error handler
ddf95c7 [HttpFoundation] Silent only JSON errors
This commit is contained in:
Fabien Potencier 2014-09-22 17:58:59 +02:00
commit 6a435cd28e
2 changed files with 51 additions and 1 deletions

View File

@ -95,7 +95,29 @@ class JsonResponse extends Response
*/
public function setData($data = array())
{
$this->data = @json_encode($data, $this->encodingOptions);
$errorHandler = null;
$errorHandler = set_error_handler(function () use (&$errorHandler) {
if (JSON_ERROR_NONE !== json_last_error()) {
return;
}
if ($errorHandler) {
call_user_func_array($errorHandler, func_get_args());
}
});
try {
// Clear json_last_error()
json_encode(null);
$this->data = json_encode($data, $this->encodingOptions);
restore_error_handler();
} catch (\Exception $exception) {
restore_error_handler();
throw $exception;
}
if (JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException($this->transformJsonError());

View File

@ -201,4 +201,32 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase
{
JsonResponse::create("\xB1\x31");
}
/**
* @expectedException Exception
* @expectedExceptionMessage Failed calling Symfony\Component\HttpFoundation\Tests\JsonSerializableObject::jsonSerialize()
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php#114688
*/
public function testSetContentJsonSerializeError()
{
if (!interface_exists('JsonSerializable')) {
$this->markTestSkipped('Interface JsonSerializable is available in PHP 5.4+');
}
$serializable = new JsonSerializableObject();
JsonResponse::create($serializable);
}
}
if (interface_exists('JsonSerializable')) {
class JsonSerializableObject implements \JsonSerializable
{
public function jsonSerialize()
{
trigger_error('This error is expected', E_USER_WARNING);
return array();
}
}
}