Skip to content

Commit 4c39668

Browse files
authored
Merge pull request #1911 from atishamte/json_cast_exception
JSON Cast exception test cases
2 parents 4872f0a + 56fa534 commit 4c39668

2 files changed

Lines changed: 95 additions & 1 deletion

File tree

system/Entity.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ public function __get(string $key)
313313
* @param null $value
314314
*
315315
* @return $this
316+
* @throws \Exception
316317
*/
317318
public function __set(string $key, $value = null)
318319
{
@@ -349,6 +350,11 @@ public function __set(string $key, $value = null)
349350
if (($castTo === 'json' || $castTo === 'json-array') && function_exists('json_encode'))
350351
{
351352
$value = json_encode($value);
353+
354+
if (json_last_error() !== JSON_ERROR_NONE)
355+
{
356+
throw CastException::forInvalidJsonFormatException(json_last_error());
357+
}
352358
}
353359
}
354360

tests/system/EntityTest.php

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace CodeIgniter;
44

5+
use CodeIgniter\Exceptions\CastException;
56
use CodeIgniter\I18n\Time;
67
use CodeIgniter\Test\ReflectionHelper;
78
use Tests\Support\SomeEntity;
@@ -430,6 +431,93 @@ public function testCastAsJSONArray()
430431
$this->assertEquals($data, $entity->eleventh);
431432
}
432433

434+
public function testCastAsJSONErrorDepth()
435+
{
436+
$entity = $this->getCastEntity();
437+
438+
// Create array with depth 513 to get depth error
439+
$array = [];
440+
$value = "test value";
441+
$keys = rtrim(str_repeat('test.', 513), '.');
442+
$keys = explode(".", $keys);
443+
$current = &$array;
444+
foreach ($keys as $key)
445+
{
446+
$current = &$current[$key];
447+
}
448+
$current = $value;
449+
450+
$this->expectException(CastException::class);
451+
$this->expectExceptionMessage('Maximum stack depth exceeded');
452+
453+
$entity->tenth = $array;
454+
$this->getPrivateProperty($entity, 'tenth');
455+
}
456+
457+
public function testCastAsJSONErrorUTF8()
458+
{
459+
$entity = $this->getCastEntity();
460+
461+
$this->expectException(CastException::class);
462+
$this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded');
463+
464+
$entity->tenth = "\xB1\x31";
465+
$this->getPrivateProperty($entity, 'tenth');
466+
}
467+
468+
public function testCastAsJSONSyntaxError()
469+
{
470+
$entity = new Entity();
471+
472+
$method = $this->getPrivateMethodInvoker($entity,'castAsJson');
473+
474+
$this->expectException(CastException::class);
475+
$this->expectExceptionMessage('Syntax error, malformed JSON');
476+
477+
$method("{ this is bad string", true);
478+
}
479+
480+
public function testCastAsJSONAnotherErrorDepth()
481+
{
482+
$entity = new Entity();
483+
484+
$method = $this->getPrivateMethodInvoker($entity,'castAsJson');
485+
486+
$this->expectException(CastException::class);
487+
$this->expectExceptionMessage('Maximum stack depth exceeded');
488+
489+
$string = '{'.str_repeat('"test":{', 513).'"test":"value"'.str_repeat('}', 513).'}';
490+
491+
$method($string, true);
492+
}
493+
494+
public function testCastAsJSONControlCharCheck()
495+
{
496+
$entity = new Entity();
497+
498+
$method = $this->getPrivateMethodInvoker($entity,'castAsJson');
499+
500+
$this->expectException(CastException::class);
501+
$this->expectExceptionMessage('Unexpected control character found');
502+
503+
$string = "{\n\t\"property1\": \"The quick brown fox\njumps over the lazy dog\",\n\t\"property2\":\"value2\"\n}";
504+
505+
$method($string, true);
506+
}
507+
508+
public function testCastAsJSONStateMismatch()
509+
{
510+
$entity = new Entity();
511+
512+
$method = $this->getPrivateMethodInvoker($entity,'castAsJson');
513+
514+
$this->expectException(CastException::class);
515+
$this->expectExceptionMessage('Underflow or the modes mismatch');
516+
517+
$string = '[{"name":"jack","product_id":"1234"]';
518+
519+
$method($string, true);
520+
}
433521
//--------------------------------------------------------------------
434522

435523
public function testAsArray()
@@ -648,7 +736,7 @@ protected function getCastNullableEntity()
648736
'casts' => [
649737
'string_null' => '?string',
650738
'string_empty' => 'string',
651-
'integner_null' => '?integer',
739+
'integer_null' => '?integer',
652740
'integer_0' => 'integer',
653741
],
654742
'dates' => [],

0 commit comments

Comments
 (0)