File tree Expand file tree Collapse file tree 2 files changed +56
-0
lines changed Expand file tree Collapse file tree 2 files changed +56
-0
lines changed Original file line number Diff line number Diff line change @@ -227,9 +227,23 @@ PHP_METHOD(Cursor, setTypeMap)
227
227
return ;
228
228
}
229
229
230
+ /* Check if the existing element needs to be freed before we overwrite
231
+ * visitor_data, which contains the only reference to it. */
232
+ if (!Z_ISUNDEF (intern -> visitor_data .zchild )) {
233
+ php_phongo_cursor_free_current (intern );
234
+ }
235
+
230
236
phongo_bson_typemap_to_state (typemap , & state .map TSRMLS_CC );
231
237
232
238
intern -> visitor_data = state ;
239
+
240
+ /* If the cursor has a current element, we just freed it and should restore
241
+ * it with a new type map applied. */
242
+ if (mongoc_cursor_current (intern -> cursor )) {
243
+ const bson_t * doc = mongoc_cursor_current (intern -> cursor );
244
+
245
+ phongo_bson_to_zval_ex (bson_get_data (doc ), doc -> len , & intern -> visitor_data );
246
+ }
233
247
}
234
248
/* }}} */
235
249
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ PHPC-849: Cursor::setTypeMap() leaks current element if called during iteration
3
+ --SKIPIF--
4
+ <?php require __DIR__ . "/../utils/basic-skipif.inc " ; CLEANUP (STANDALONE ) ?>
5
+ --FILE--
6
+ <?php
7
+ require_once __DIR__ . "/../utils/basic.inc " ;
8
+
9
+ $ manager = new MongoDB \Driver \Manager (STANDALONE );
10
+
11
+ $ bulk = new MongoDB \Driver \BulkWrite ();
12
+ $ bulk ->insert (['_id ' => 1 ]);
13
+ $ bulk ->insert (['_id ' => 2 ]);
14
+ $ bulk ->insert (['_id ' => 3 ]);
15
+ $ manager ->executeBulkWrite (NS , $ bulk );
16
+
17
+ $ cursor = $ manager ->executeQuery (NS , new MongoDB \Driver \Query ([]));
18
+ $ cursor ->setTypeMap (['root ' => 'stdClass ' ]);
19
+
20
+ foreach ($ cursor as $ i => $ document ) {
21
+ // Type map will apply to the next iteration, since current element is already converted
22
+ $ cursor ->setTypeMap (['root ' => ($ i % 2 ? 'stdClass ' : 'array ' )]);
23
+ var_dump ($ document );
24
+ }
25
+
26
+ ?>
27
+ ===DONE===
28
+ <?php exit (0 ); ?>
29
+ --EXPECTF--
30
+ object(stdClass)#%d (%d) {
31
+ ["_id"]=>
32
+ int(1)
33
+ }
34
+ array(1) {
35
+ ["_id"]=>
36
+ int(2)
37
+ }
38
+ object(stdClass)#%d (%d) {
39
+ ["_id"]=>
40
+ int(3)
41
+ }
42
+ ===DONE===
You can’t perform that action at this time.
0 commit comments