From 155cf24d61f3ef3b3d152f2813dcbbff350e7985 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Sat, 20 Jul 2024 19:41:07 +0200 Subject: [PATCH] Default $bStrictObjectTypeChecking to true BC break! Passing simple types to the class constructor may lead to a bunch of unexpected behavior, which can result in crashes or violate expectations - see the list in the README. By enabling strict object type checks automatically, JsonMapper behaves more calculatable. This is a backwards compatibility break. The old behavior can be restored by setting the $bStrictObjectTypeChecking option to `false`. Resolves: https://github.com/cweiske/jsonmapper/issues/226 Resolves: https://github.com/cweiske/jsonmapper/issues/238 --- README.rst | 26 +++++++++++++++++++++----- src/JsonMapper.php | 2 +- tests/ArrayTest.php | 3 +++ tests/ClassMapTest.php | 3 +++ tests/Enums_PHP81_Test.php | 1 + tests/NamespaceTest.php | 2 ++ tests/ObjectTest.php | 1 + 7 files changed, 32 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 142f4c60a..7a52cb7bc 100644 --- a/README.rst +++ b/README.rst @@ -477,17 +477,33 @@ setter methods by setting ``$bIgnoreVisibility`` to true: Simple types instead of objects =============================== When a variable's type is a class and JSON data is a simple type -like ``string``, JsonMapper passes this value to the class' constructor. - -If you do not want this, set ``$bStrictObjectTypeChecking`` to ``true``: +like ``string``, JsonMapper can pass this value to the class' constructor +when configured to do so: .. code:: php $jm = new JsonMapper(); - $jm->bStrictObjectTypeChecking = true; + $jm->bStrictObjectTypeChecking = false; $jm->map(...); -An exception is then thrown in such cases. +This can be used to automatically initialize DateTime objects +from date strings. + +Disabling this strict object type checks may lead to problems, though: + +- When a class does not have a constructor or no constructor parameter, + the value will get lost +- When the constructor has more than 1 required parameter, it will crash. +- When the constructor's parameter type does not match the one of the + data in JSON, it will crash +- ``@required`` properties will not be filled + +.. note:: + The default value changed from ``false`` to ``true`` in version 5 to + increase security. + + Now you have to opt in if you want to pass simple types to + the class constructor. Passing arrays to ``map()`` diff --git a/src/JsonMapper.php b/src/JsonMapper.php index 7d0bb4457..08d7178d4 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -64,7 +64,7 @@ class JsonMapper * * @var boolean */ - public $bStrictObjectTypeChecking = false; + public $bStrictObjectTypeChecking = true; /** * Throw an exception, if null value is found diff --git a/tests/ArrayTest.php b/tests/ArrayTest.php index c0511bc41..bf2e99100 100644 --- a/tests/ArrayTest.php +++ b/tests/ArrayTest.php @@ -48,6 +48,7 @@ public function testMapTypedArray() public function testMapTypedSimpleArray() { $jm = new JsonMapper(); + $jm->bStrictObjectTypeChecking = false; $jm->bStrictNullTypesInArrays = false; $sn = $jm->map( json_decode('{"typedSimpleArray":["2014-01-02",null,"2014-05-07"]}'), @@ -510,6 +511,7 @@ public function testMapArrayStrangeKeys() public function testMapTypedSimpleArrayFromObject() { $jm = new JsonMapper(); + $jm->bStrictObjectTypeChecking = false; $sn = $jm->map( json_decode('{"typedSimpleArray":{"en-US":"2014-01-02"}}'), new JsonMapperTest_Array() @@ -587,6 +589,7 @@ public function testMapArrayFromVariadicFunctionWithSimpleType() public function testMapArrayFromVariadicFunctionWithObjectType() { $jm = new JsonMapper(); + $jm->bStrictObjectTypeChecking = false; /** @var JsonMapperTest_VariadicArray $sn */ $sn = $jm->map( json_decode('{"variadicDateTime":["2014-01-02","2014-05-07"]}'), diff --git a/tests/ClassMapTest.php b/tests/ClassMapTest.php index 511eeb3c4..e9d9a4195 100644 --- a/tests/ClassMapTest.php +++ b/tests/ClassMapTest.php @@ -59,6 +59,7 @@ public static function classMapTestData() public function testClassMap($classMapValue) { $jm = new JsonMapper(); + $jm->bStrictObjectTypeChecking = false; $jm->classMap[self::CLASS_MAP_CLASS] = $classMapValue; $sn = $jm->map( json_decode('{"pPlainObject":"'.self::CLASS_MAP_DATA.'"}'), @@ -75,6 +76,7 @@ public function testClassMap($classMapValue) public function testNamespaceKeyWithLeadingBackslash() { $jm = new JsonMapper(); + $jm->bStrictObjectTypeChecking = false; $jm->classMap['\\namespacetest\\model\\User'] = \namespacetest\Unit::class; $data = $jm->map( @@ -88,6 +90,7 @@ public function testNamespaceKeyWithLeadingBackslash() public function testNamespaceKeyNoLeadingBackslash() { $jm = new JsonMapper(); + $jm->bStrictObjectTypeChecking = false; $jm->classMap[\namespacetest\model\User::class] = \namespacetest\Unit::class; $data = $jm->map( diff --git a/tests/Enums_PHP81_Test.php b/tests/Enums_PHP81_Test.php index 2f15d79ea..deb320d66 100644 --- a/tests/Enums_PHP81_Test.php +++ b/tests/Enums_PHP81_Test.php @@ -22,6 +22,7 @@ class Enums_PHP81_Test extends \PHPUnit\Framework\TestCase public function testEnumMapping() { $jm = new JsonMapper(); + $jm->bStrictObjectTypeChecking = false; /** @var \Enums\ObjectWithEnum $sn */ $sn = $jm->map( json_decode(self::TEST_DATA), diff --git a/tests/NamespaceTest.php b/tests/NamespaceTest.php index f6bc5d2a2..d97ea5122 100644 --- a/tests/NamespaceTest.php +++ b/tests/NamespaceTest.php @@ -53,6 +53,7 @@ public function testMapChildClassNamespace() public function testMapChildClassConstructorNamespace() { $mapper = new \JsonMapper(); + $mapper->bStrictObjectTypeChecking = false; $json = '{"user":"John Smith"}'; $res = $mapper->map(json_decode($json), new UnitData()); $this->assertInstanceOf(\namespacetest\UnitData::class, $res); @@ -106,6 +107,7 @@ public function testMapCustomArrayObject() public function testSetterNamespacedTypeHint() { $mapper = new \JsonMapper(); + $mapper->bStrictObjectTypeChecking = false; $json = '{"namespacedTypeHint":"Foo"}'; $res = $mapper->map(json_decode($json), new UnitData()); $this->assertInstanceOf(\namespacetest\UnitData::class, $res); diff --git a/tests/ObjectTest.php b/tests/ObjectTest.php index 260ae55c0..fa3341f71 100644 --- a/tests/ObjectTest.php +++ b/tests/ObjectTest.php @@ -52,6 +52,7 @@ public function testMapObjectByClassName() public function testMapDateTime() { $jm = new JsonMapper(); + $jm->bStrictObjectTypeChecking = false; $sn = $jm->map( json_decode('{"datetime":"2014-04-01T00:00:00+02:00"}'), new JsonMapperTest_Object()