diff --git a/src/Response/JsonResponse.php b/src/Response/JsonResponse.php index 8dcad1b2..f570a0a0 100644 --- a/src/Response/JsonResponse.php +++ b/src/Response/JsonResponse.php @@ -4,6 +4,7 @@ namespace Laminas\Diactoros\Response; +use JsonException; use Laminas\Diactoros\Exception; use Laminas\Diactoros\Response; use Laminas\Diactoros\Stream; @@ -11,15 +12,13 @@ use function is_object; use function is_resource; use function json_encode; -use function json_last_error; -use function json_last_error_msg; use function sprintf; -use const JSON_ERROR_NONE; use const JSON_HEX_AMP; use const JSON_HEX_APOS; use const JSON_HEX_QUOT; use const JSON_HEX_TAG; +use const JSON_THROW_ON_ERROR; use const JSON_UNESCAPED_SLASHES; /** @@ -131,17 +130,15 @@ private function jsonEncode(mixed $data, int $encodingOptions): string // Clear json_last_error() json_encode(null); - $json = json_encode($data, $encodingOptions); - - if (JSON_ERROR_NONE !== json_last_error()) { + try { + return json_encode($data, $encodingOptions | JSON_THROW_ON_ERROR); + } catch (JsonException $e) { throw new Exception\InvalidArgumentException(sprintf( 'Unable to encode data to JSON in %s: %s', self::class, - json_last_error_msg() - )); + $e->getMessage() + ), 0, $e); } - - return $json; } private function setPayload(mixed $data): void diff --git a/test/Response/JsonResponseTest.php b/test/Response/JsonResponseTest.php index 3dc24344..aa2bdf13 100644 --- a/test/Response/JsonResponseTest.php +++ b/test/Response/JsonResponseTest.php @@ -19,6 +19,7 @@ use const JSON_HEX_QUOT; use const JSON_HEX_TAG; use const JSON_PRETTY_PRINT; +use const JSON_THROW_ON_ERROR; use const JSON_UNESCAPED_SLASHES; class JsonResponseTest extends TestCase @@ -103,6 +104,22 @@ public function testJsonErrorHandlingOfBadEmbeddedData(): void new JsonResponse($data); } + public function testJsonErrorHandlingOfMalformedUtf8(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Unable to encode'); + + new JsonResponse("\xff"); + } + + public function testJsonErrorHandlingOfMalformedUtf8IfExplicitlySettingThrowFlag(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Unable to encode'); + + new JsonResponse("\xff", encodingOptions: JsonResponse::DEFAULT_JSON_FLAGS | JSON_THROW_ON_ERROR); + } + /** @return non-empty-array */ public function valuesToJsonEncode(): array {