Skip to content

Commit 013c9c4

Browse files
committed
Merge pull request #646
2 parents 4e74331 + 4b6f3ec commit 013c9c4

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

src/bson.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,11 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
12841284
* properties, we'll need to filter them out later. */
12851285
bool ht_data_from_properties = false;
12861286

1287+
/* If the object is an instance of MongoDB\BSON\Persistable, we will need to
1288+
* inject the PHP class name as a BSON key and ignore any existing key in
1289+
* the return value of bsonSerialize(). */
1290+
bool skip_odm_field = false;
1291+
12871292
ZVAL_UNDEF(&obj_data);
12881293

12891294
switch(Z_TYPE_P(data)) {
@@ -1338,11 +1343,12 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
13381343
if (instanceof_function(Z_OBJCE_P(data), php_phongo_persistable_ce TSRMLS_CC)) {
13391344
#if PHP_VERSION_ID >= 70000
13401345
bson_append_binary(bson, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(data)->name->val, Z_OBJCE_P(data)->name->len);
1341-
zend_hash_str_del(ht_data, PHONGO_ODM_FIELD_NAME, sizeof(PHONGO_ODM_FIELD_NAME)-1);
13421346
#else
13431347
bson_append_binary(bson, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(data)->name, strlen(Z_OBJCE_P(data)->name));
1344-
zend_hash_del(ht_data, PHONGO_ODM_FIELD_NAME, sizeof(PHONGO_ODM_FIELD_NAME));
13451348
#endif
1349+
/* Ensure that we ignore an existing key with the same name
1350+
* if one exists in the bsonSerialize() return value. */
1351+
skip_odm_field = true;
13461352
}
13471353

13481354
break;
@@ -1387,6 +1393,10 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
13871393
goto cleanup;
13881394
}
13891395

1396+
if (skip_odm_field && !strcmp(ZSTR_VAL(string_key), PHONGO_ODM_FIELD_NAME)) {
1397+
continue;
1398+
}
1399+
13901400
if (flags & PHONGO_BSON_ADD_ID) {
13911401
if (!strcmp(ZSTR_VAL(string_key), "_id")) {
13921402
flags &= ~PHONGO_BSON_ADD_ID;
@@ -1439,6 +1449,10 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
14391449
goto cleanup;
14401450
}
14411451

1452+
if (skip_odm_field && !strcmp(string_key, PHONGO_ODM_FIELD_NAME)) {
1453+
continue;
1454+
}
1455+
14421456
if (flags & PHONGO_BSON_ADD_ID) {
14431457
if (!strcmp(string_key, "_id")) {
14441458
flags &= ~PHONGO_BSON_ADD_ID;

tests/bson/bug1006-001.phpt

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
PHPC-1005: Do not modify memory of Persistable::bsonSerialize() return value
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/tools.php';
7+
8+
class MyClass implements MongoDB\BSON\Persistable
9+
{
10+
public $data;
11+
12+
public function __construct()
13+
{
14+
$this->data = [
15+
'__pclass' => 'baz',
16+
'foo' => 'bar',
17+
];
18+
}
19+
20+
function bsonSerialize()
21+
{
22+
return $this->data;
23+
}
24+
25+
function bsonUnserialize(array $data)
26+
{
27+
}
28+
}
29+
30+
$obj = new MyClass;
31+
var_dump($obj->data);
32+
hex_dump(fromPHP($obj));
33+
var_dump($obj->data);
34+
35+
?>
36+
===DONE===
37+
<?php exit(0); ?>
38+
--EXPECT--
39+
array(2) {
40+
["__pclass"]=>
41+
string(3) "baz"
42+
["foo"]=>
43+
string(3) "bar"
44+
}
45+
0 : 28 00 00 00 05 5f 5f 70 63 6c 61 73 73 00 07 00 [(....__pclass...]
46+
10 : 00 00 80 4d 79 43 6c 61 73 73 02 66 6f 6f 00 04 [...MyClass.foo..]
47+
20 : 00 00 00 62 61 72 00 00 [...bar..]
48+
array(2) {
49+
["__pclass"]=>
50+
string(3) "baz"
51+
["foo"]=>
52+
string(3) "bar"
53+
}
54+
===DONE===

0 commit comments

Comments
 (0)