Skip to content

Commit 047bea5

Browse files
committed
PHPC-275: object_to_bson() handling for invalid bsonSerialize() retval
This also refactors the handling to be consistent with zval_to_bson().
1 parent 9e59cee commit 047bea5

File tree

2 files changed

+72
-21
lines changed

2 files changed

+72
-21
lines changed

src/bson.c

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -607,34 +607,43 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
607607

608608
if (instanceof_function(Z_OBJCE_P(object), php_phongo_type_ce TSRMLS_CC)) {
609609
if (instanceof_function(Z_OBJCE_P(object), php_phongo_serializable_ce TSRMLS_CC)) {
610-
zval *retval = NULL;
610+
zval *obj_data = NULL;
611+
bson_t child;
612+
HashTable *tmp_ht;
611613

612-
zend_call_method_with_0_params(&object, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &retval);
613-
if (retval) {
614-
bson_t child;
615-
HashTable *tmp_ht;
614+
zend_call_method_with_0_params(&object, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data);
616615

617-
convert_to_array_ex(&retval);
618-
tmp_ht = HASH_OF(retval);
616+
if (!obj_data) {
617+
/* zend_call_method() failed */
618+
return;
619+
}
619620

620-
if (tmp_ht) {
621-
tmp_ht->nApplyCount++;
622-
}
621+
if (Z_TYPE_P(obj_data) != IS_ARRAY) {
622+
phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Expected %s() to return an array, %s given", BSON_SERIALIZE_FUNC_NAME, zend_get_type_by_const(Z_TYPE_P(obj_data)));
623+
zval_ptr_dtor(&obj_data);
623624

624-
bson_append_document_begin(bson, key, key_len, &child);
625-
if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC)) {
626-
if (flags & PHONGO_BSON_ADD_CHILD_ODS) {
627-
bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(object)->name, strlen(Z_OBJCE_P(object)->name));
628-
}
629-
}
630-
zval_to_bson(retval, flags, &child, NULL TSRMLS_CC);
631-
bson_append_document_end(bson, &child);
625+
return;
626+
}
632627

633-
if (tmp_ht) {
634-
tmp_ht->nApplyCount--;
628+
tmp_ht = HASH_OF(obj_data);
629+
630+
if (tmp_ht) {
631+
tmp_ht->nApplyCount++;
632+
}
633+
634+
bson_append_document_begin(bson, key, key_len, &child);
635+
if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC)) {
636+
if (flags & PHONGO_BSON_ADD_CHILD_ODS) {
637+
bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(object)->name, strlen(Z_OBJCE_P(object)->name));
635638
}
636-
zval_ptr_dtor(&retval);
637639
}
640+
zval_to_bson(obj_data, flags, &child, NULL TSRMLS_CC);
641+
bson_append_document_end(bson, &child);
642+
643+
if (tmp_ht) {
644+
tmp_ht->nApplyCount--;
645+
}
646+
zval_ptr_dtor(&obj_data);
638647
return;
639648
}
640649

tests/bson/bson-encode_error-002.phpt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
BSON encoding error when bsonSerialize() for embedded document does not return an array
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
class MyClass implements BSON\Serializable
10+
{
11+
private $value;
12+
13+
public function __construct($value)
14+
{
15+
$this->value = $value;
16+
}
17+
18+
public function bsonSerialize()
19+
{
20+
return $this->value;
21+
}
22+
}
23+
24+
$invalidValues = array(new stdClass, 'foo', 1, true);
25+
26+
foreach ($invalidValues as $invalidValue) {
27+
try {
28+
$bson = BSON\fromArray(array('embed' => new MyClass($invalidValue)));
29+
} catch (MongoDB\Driver\Exception\RuntimeException $e) {
30+
echo $e->getMessage(), "\n";
31+
}
32+
}
33+
34+
?>
35+
===DONE===
36+
<?php exit(0); ?>
37+
--EXPECT--
38+
Expected bsonSerialize() to return an array, object given
39+
Expected bsonSerialize() to return an array, string given
40+
Expected bsonSerialize() to return an array, integer given
41+
Expected bsonSerialize() to return an array, boolean given
42+
===DONE===

0 commit comments

Comments
 (0)