bug #9908 [HttpFoundation] Throw proper exception when invalid data is passed to JsonResponse class (stloyd)

This PR was merged into the 2.3 branch.

Discussion
----------

[HttpFoundation] Throw proper exception when invalid data is passed to JsonResponse class

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| BC breaks?    | no*
| Tests pass?   | yes
| Fixed tickets | #9903
| License       | MIT

\* as described in mentioned issue, before this PR there was thrown exception `UnexpectedValueException`, which was not correct, but I guess some people trying to hide the bug could use `try {} catch` on it.

Commits
-------

38287e7 [HttpFoundation] Throw proper exception when invalid data is passed to JsonResponse class
This commit is contained in:
Fabien Potencier 2013-12-31 12:26:13 +01:00
commit 323710a291
2 changed files with 50 additions and 8 deletions

View File

@ -85,12 +85,18 @@ class JsonResponse extends Response
* @param mixed $data
*
* @return JsonResponse
*
* @throws \InvalidArgumentException
*/
public function setData($data = array())
{
// Encode <, >, ', &, and " for RFC4627-compliant JSON, which may also be embedded into HTML.
$this->data = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException($this->transformJsonError());
}
return $this->update();
}
@ -116,4 +122,31 @@ class JsonResponse extends Response
return $this->setContent($this->data);
}
private function transformJsonError()
{
if (function_exists('json_last_error_msg')) {
return json_last_error_msg();
}
switch (json_last_error()) {
case JSON_ERROR_DEPTH:
return 'Maximum stack depth exceeded.';
case JSON_ERROR_STATE_MISMATCH:
return 'Underflow or the modes mismatch.';
case JSON_ERROR_CTRL_CHAR:
return 'Unexpected control character found.';
case JSON_ERROR_SYNTAX:
return 'Syntax error, malformed JSON.';
case JSON_ERROR_UTF8:
return 'Malformed UTF-8 characters, possibly incorrectly encoded.';
default:
return 'Unknown error.';
}
}
}

View File

@ -159,18 +159,27 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('text/javascript', $response->headers->get('Content-Type'));
}
public function testSetCallbackInvalidIdentifier()
{
$response = new JsonResponse('foo');
$this->setExpectedException('InvalidArgumentException');
$response->setCallback('+invalid');
}
public function testJsonEncodeFlags()
{
$response = new JsonResponse('<>\'&"');
$this->assertEquals('"\u003C\u003E\u0027\u0026\u0022"', $response->getContent());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testSetCallbackInvalidIdentifier()
{
$response = new JsonResponse('foo');
$response->setCallback('+invalid');
}
/**
* @expectedException \InvalidArgumentException
*/
public function testSetContent()
{
JsonResponse::create("\xB1\x31");
}
}