Skip to content

Commit dea4ff9

Browse files
committed
PHPC-343: Allow bsonSerialize() to return a stdClass
This revises the UnexpectedValueException message for an invalid return value (PHPC-331). Additionally, we consolidated the previous BSON-encoding error tests.
1 parent 2824214 commit dea4ff9

File tree

4 files changed

+69
-92
lines changed

4 files changed

+69
-92
lines changed

src/bson.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,8 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
621621
return;
622622
}
623623

624-
if (Z_TYPE_P(obj_data) != IS_ARRAY) {
625-
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Expected %s() to return an array, %s given", BSON_SERIALIZE_FUNC_NAME, zend_get_type_by_const(Z_TYPE_P(obj_data)));
624+
if (Z_TYPE_P(obj_data) != IS_ARRAY && !(Z_TYPE_P(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(obj_data), zend_standard_class_def TSRMLS_CC))) {
625+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Expected %s::%s() to return an array or stdClass, %s given", Z_OBJCE_P(object)->name, BSON_SERIALIZE_FUNC_NAME, (Z_TYPE_P(obj_data) == IS_OBJECT ? Z_OBJCE_P(obj_data)->name : zend_get_type_by_const(Z_TYPE_P(obj_data))));
626626
zval_ptr_dtor(&obj_data);
627627

628628
return;
@@ -783,8 +783,8 @@ PHONGO_API void zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *
783783
break;
784784
}
785785

786-
if (Z_TYPE_P(obj_data) != IS_ARRAY) {
787-
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Expected %s() to return an array, %s given", BSON_SERIALIZE_FUNC_NAME, zend_get_type_by_const(Z_TYPE_P(obj_data)));
786+
if (Z_TYPE_P(obj_data) != IS_ARRAY && !(Z_TYPE_P(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(obj_data), zend_standard_class_def TSRMLS_CC))) {
787+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Expected %s::%s() to return an array or stdClass, %s given", Z_OBJCE_P(data)->name, BSON_SERIALIZE_FUNC_NAME, (Z_TYPE_P(obj_data) == IS_OBJECT ? Z_OBJCE_P(obj_data)->name : zend_get_type_by_const(Z_TYPE_P(obj_data))));
788788

789789
break;
790790
}

tests/bson/bson-encode_error-001.phpt

Lines changed: 0 additions & 44 deletions
This file was deleted.

tests/bson/bson-encode_error-002.phpt

Lines changed: 0 additions & 44 deletions
This file was deleted.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
--TEST--
2+
BSON\fromPHP(): bsonSerialize() must return an array or stdClass
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
5+
--FILE--
6+
<?php
7+
use MongoDB\BSON as BSON;
8+
9+
require_once __DIR__ . "/../utils/basic.inc";
10+
11+
class MyDocument implements BSON\Serializable
12+
{
13+
private $data;
14+
15+
public function __construct($data = null)
16+
{
17+
$this->data = $data;
18+
}
19+
20+
public function bsonSerialize()
21+
{
22+
return $this->data;
23+
}
24+
}
25+
26+
$invalidValues = array(null, 123, 'foo', true, new MyDocument);
27+
28+
echo "Testing top-level objects\n";
29+
30+
foreach ($invalidValues as $invalidValue) {
31+
try {
32+
hex_dump(fromPHP(new MyDocument($invalidValue)));
33+
} catch (MongoDB\Driver\Exception\UnexpectedValueException $e) {
34+
echo $e->getMessage(), "\n";
35+
}
36+
}
37+
38+
echo "\nTesting nested objects\n";
39+
40+
foreach ($invalidValues as $invalidValue) {
41+
try {
42+
hex_dump(fromPHP(new MyDocument(array('nested' => new MyDocument($invalidValue)))));
43+
} catch (MongoDB\Driver\Exception\UnexpectedValueException $e) {
44+
echo $e->getMessage(), "\n";
45+
}
46+
}
47+
48+
?>
49+
===DONE===
50+
<?php exit(0); ?>
51+
--EXPECTF--
52+
Testing top-level objects
53+
Expected MyDocument::bsonSerialize() to return an array or stdClass, null given
54+
Expected MyDocument::bsonSerialize() to return an array or stdClass, integer given
55+
Expected MyDocument::bsonSerialize() to return an array or stdClass, string given
56+
Expected MyDocument::bsonSerialize() to return an array or stdClass, boolean given
57+
Expected MyDocument::bsonSerialize() to return an array or stdClass, MyDocument given
58+
59+
Testing nested objects
60+
Expected MyDocument::bsonSerialize() to return an array or stdClass, null given
61+
Expected MyDocument::bsonSerialize() to return an array or stdClass, integer given
62+
Expected MyDocument::bsonSerialize() to return an array or stdClass, string given
63+
Expected MyDocument::bsonSerialize() to return an array or stdClass, boolean given
64+
Expected MyDocument::bsonSerialize() to return an array or stdClass, MyDocument given
65+
===DONE===

0 commit comments

Comments
 (0)