Skip to content

Commit e7e9fe7

Browse files
committed
PHPC-1154: Fix memory leak with typemaps and MongoDB\BSON\toPHP
1 parent eddcd4b commit e7e9fe7

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

src/BSON/functions.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,11 @@ PHP_FUNCTION(MongoDB_BSON_toPHP)
7474

7575
if (!php_phongo_bson_to_zval_ex((const unsigned char*) data, data_len, &state)) {
7676
zval_ptr_dtor(&state.zchild);
77+
php_phongo_bson_typemap_dtor(&state.map);
7778
RETURN_NULL();
7879
}
80+
81+
php_phongo_bson_typemap_dtor(&state.map);
7982

8083
#if PHP_VERSION_ID >= 70000
8184
RETURN_ZVAL(&state.zchild, 0, 1);

tests/bson/typemap-008.phpt

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
--TEST--
2+
MongoDB\Driver\Cursor::setTypeMap(): fieldPath typemaps without server
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
--FILE--
6+
<?php
7+
8+
class MyArrayObject extends ArrayObject implements MongoDB\BSON\Unserializable
9+
{
10+
function bsonUnserialize(array $data)
11+
{
12+
parent::__construct($data, ArrayObject::ARRAY_AS_PROPS);
13+
}
14+
}
15+
16+
class MyWildCardArrayObject extends MyArrayObject {};
17+
18+
$bson = \MongoDB\BSON\fromPHP( [
19+
'_id' => 1,
20+
'object' => [
21+
'parent1' => [
22+
'child1' => [ 1, 2, 3 ],
23+
'child2' => [ 4, 5, 6 ],
24+
],
25+
'parent2' => [
26+
'child1' => [ 7, 8, 9 ],
27+
'child2' => [ 10, 11, 12 ],
28+
],
29+
],
30+
] );
31+
32+
function fetch($bson, $typeMap = [])
33+
{
34+
for ($i = 0; $i < 25000; $i++) {
35+
$documents = [ \MongoDB\BSON\toPHP($bson, $typeMap) ];
36+
}
37+
return $documents;
38+
}
39+
40+
41+
echo "\nSetting 'object.$.child1' path to 'MyWildCardArrayObject'\n";
42+
$documents = fetch($bson, ["fieldPaths" => [
43+
'object.$.child1' => "MyWildCardArrayObject"
44+
]]);
45+
var_dump($documents[0]->object->parent1 instanceof stdClass);
46+
var_dump($documents[0]->object->parent1->child1 instanceof MyWildCardArrayObject);
47+
var_dump(is_array($documents[0]->object->parent1->child2));
48+
var_dump($documents[0]->object->parent2 instanceof stdClass);
49+
var_dump($documents[0]->object->parent2->child1 instanceof MyWildCardArrayObject);
50+
var_dump(is_array($documents[0]->object->parent2->child2));
51+
52+
echo "\nSetting 'object.parent1.$' path to 'MyWildCardArrayObject' and 'object.parent2.child1' to 'MyArrayObject'\n";
53+
$documents = fetch($bson, ["fieldPaths" => [
54+
'object.parent1.$' => "MyWildCardArrayObject",
55+
'object.parent2.child1' => "MyArrayObject",
56+
]]);
57+
var_dump($documents[0]->object->parent1 instanceof stdClass);
58+
var_dump($documents[0]->object->parent1->child1 instanceof MyWildCardArrayObject);
59+
var_dump($documents[0]->object->parent1->child2 instanceof MyWildCardArrayObject);
60+
var_dump($documents[0]->object->parent2 instanceof stdClass);
61+
var_dump($documents[0]->object->parent2->child1 instanceof MyArrayObject);
62+
var_dump(is_array($documents[0]->object->parent2->child2));
63+
64+
echo "\nSetting 'object.parent1.$' path to 'MyWildCardArrayObject' and 'object.$.$' to 'MyArrayObject'\n";
65+
$documents = fetch($bson, ["fieldPaths" => [
66+
'object.parent1.$' => "MyWildCardArrayObject",
67+
'object.$.$' => "MyArrayObject",
68+
]]);
69+
var_dump($documents[0]->object->parent1 instanceof stdClass);
70+
var_dump($documents[0]->object->parent1->child1 instanceof MyWildCardArrayObject);
71+
var_dump($documents[0]->object->parent1->child2 instanceof MyWildCardArrayObject);
72+
var_dump($documents[0]->object->parent2 instanceof stdClass);
73+
var_dump($documents[0]->object->parent2->child1 instanceof MyArrayObject);
74+
var_dump($documents[0]->object->parent2->child2 instanceof MyArrayObject);
75+
76+
echo "\nSetting 'object.parent1.$' path to 'MyWildCardArrayObject' and 'object.$.child2' to 'MyArrayObject'\n";
77+
$documents = fetch($bson, ["fieldPaths" => [
78+
'object.parent1.child1' => "MyWildCardArrayObject",
79+
'object.$.child2' => "MyArrayObject",
80+
]]);
81+
var_dump($documents[0]->object->parent1 instanceof stdClass);
82+
var_dump($documents[0]->object->parent1->child1 instanceof MyWildCardArrayObject);
83+
var_dump($documents[0]->object->parent1->child2 instanceof MyArrayObject);
84+
var_dump($documents[0]->object->parent2 instanceof stdClass);
85+
var_dump(is_array($documents[0]->object->parent2->child1));
86+
var_dump($documents[0]->object->parent2->child2 instanceof MyArrayObject);
87+
?>
88+
===DONE===
89+
<?php exit(0); ?>
90+
--EXPECT--
91+
Setting 'object.$.child1' path to 'MyWildCardArrayObject'
92+
bool(true)
93+
bool(true)
94+
bool(true)
95+
bool(true)
96+
bool(true)
97+
bool(true)
98+
99+
Setting 'object.parent1.$' path to 'MyWildCardArrayObject' and 'object.parent2.child1' to 'MyArrayObject'
100+
bool(true)
101+
bool(true)
102+
bool(true)
103+
bool(true)
104+
bool(true)
105+
bool(true)
106+
107+
Setting 'object.parent1.$' path to 'MyWildCardArrayObject' and 'object.$.$' to 'MyArrayObject'
108+
bool(true)
109+
bool(true)
110+
bool(true)
111+
bool(true)
112+
bool(true)
113+
bool(true)
114+
115+
Setting 'object.parent1.$' path to 'MyWildCardArrayObject' and 'object.$.child2' to 'MyArrayObject'
116+
bool(true)
117+
bool(true)
118+
bool(true)
119+
bool(true)
120+
bool(true)
121+
bool(true)
122+
===DONE===

0 commit comments

Comments
 (0)