From 8d81e909a2e19960f7410eb29ed2370f7cc1be56 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 May 2023 14:03:06 +0100 Subject: [PATCH] Throw exception when mapping non-flat values in flat typed properties Flat types can all be casted to each other, but objects and arrays can't be casted to flat types. Previously an E_NOTICE has been raised: > Array to string conversion This is prevented now, and a proper JsonMapper_Exception is thrown. --- src/JsonMapper.php | 6 +++--- .../ArrayValueForStringProperty.php | 16 ++++++++++++++++ tests/ObjectTest.php | 2 +- tests/SimpleTest.php | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 tests/JsonMapperTest/ArrayValueForStringProperty.php diff --git a/src/JsonMapper.php b/src/JsonMapper.php index 5ae3895b4..2e8e3e9eb 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -245,11 +245,11 @@ public function map($json, $object) } else if ($this->isSimpleType($type) && !(is_array($jvalue) && $this->hasVariadicArrayType($accessor)) ) { - if ($type === 'string' && is_object($jvalue)) { + if ($this->isFlatType($type) && !$this->isFlatType(gettype($jvalue))) { throw new JsonMapper_Exception( 'JSON property "' . $key . '" in class "' - . $strClassName . '" is an object and' - . ' cannot be converted to a string' + . $strClassName . '" is of type ' . gettype($jvalue) . ' and' + . ' cannot be converted to ' . $type ); } settype($jvalue, $type); diff --git a/tests/JsonMapperTest/ArrayValueForStringProperty.php b/tests/JsonMapperTest/ArrayValueForStringProperty.php new file mode 100644 index 000000000..06199e43f --- /dev/null +++ b/tests/JsonMapperTest/ArrayValueForStringProperty.php @@ -0,0 +1,16 @@ + + * @license OSL-3.0 http://opensource.org/licenses/osl-3.0 + * @link http://cweiske.de/ + */ + +class JsonMapperTest_ArrayValueForStringProperty +{ + public string $value; +} diff --git a/tests/ObjectTest.php b/tests/ObjectTest.php index c2c235c06..90affe700 100644 --- a/tests/ObjectTest.php +++ b/tests/ObjectTest.php @@ -194,7 +194,7 @@ public function testObjectInvalidNull() public function testObjectInsteadOfString() { $this->expectException(JsonMapper_Exception::class); - $this->expectExceptionMessage('JSON property "pString" in class "JsonMapperTest_Object" is an object and cannot be converted to a string'); + $this->expectExceptionMessage('JSON property "pString" in class "JsonMapperTest_Object" is of type object and cannot be converted to string'); $jm = new JsonMapper(); $sn = $jm->map( json_decode('{"pString":{"key":"val"}}'), diff --git a/tests/SimpleTest.php b/tests/SimpleTest.php index e1c48e7ee..fd6cfbf36 100644 --- a/tests/SimpleTest.php +++ b/tests/SimpleTest.php @@ -11,6 +11,7 @@ * @link https://github.com/cweiske/jsonmapper */ require_once 'JsonMapperTest/Simple.php'; +require_once 'JsonMapperTest/ArrayValueForStringProperty.php'; /** * Unit tests for JsonMapper's simple type handling @@ -247,5 +248,19 @@ public function testMapSimpleHyphenSetter() ); } + + /** + * @requires PHP 7.4 + */ + public function testMapArrayValueToStringProperty() + { + $jm = new JsonMapper(); + $this->expectException(JsonMapper_Exception::class); + $this->expectExceptionMessage('JSON property "value" in class "JsonMapperTest_ArrayValueForStringProperty" is of type array and cannot be converted to string'); + $jm->map( + json_decode('{"value":[]}'), + new JsonMapperTest_ArrayValueForStringProperty() + ); + } } ?>