Skip to content

Commit 4da1efd

Browse files
committed
Merge pull request #35 from bjori/PHPc-239
PHPC-239: Cursor refcount issues
2 parents 11997ff + 251ed3e commit 4da1efd

File tree

2 files changed

+140
-2
lines changed

2 files changed

+140
-2
lines changed

php_phongo.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,13 +1561,18 @@ static void php_phongo_cursor_iterator_dtor(zend_object_iterator *iter TSRMLS_DC
15611561
{
15621562
php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter;
15631563

1564+
if (cursor_it->cursor->firstBatch) {
1565+
bson_clear(&cursor_it->cursor->firstBatch);
1566+
cursor_it->cursor->firstBatch = NULL;
1567+
}
1568+
1569+
php_phongo_cursor_free_current(cursor_it->cursor);
1570+
15641571
if (cursor_it->intern.data) {
15651572
zval_ptr_dtor((zval**)&cursor_it->intern.data);
15661573
cursor_it->intern.data = NULL;
15671574
}
15681575

1569-
php_phongo_cursor_free_current(cursor_it->cursor);
1570-
15711576
efree(cursor_it);
15721577
} /* }}} */
15731578

tests/standalone/bug0239.phpt

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
--TEST--
2+
PHPC-239: Iterator segfault
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+
class Address implements BSON\Persistable {
10+
protected $streetAddress;
11+
protected $city;
12+
protected $postalCode;
13+
14+
function __construct($streetAddress, $city, $postalCode) {
15+
$this->streetAddress = $streetAddress;
16+
$this->city = $city;
17+
$this->postalCode = $postalCode;
18+
19+
}
20+
function bsonUnserialize(array $array) {
21+
foreach($array as $k => $v) {
22+
$this->{$k} = $v;
23+
}
24+
25+
return $this;
26+
}
27+
28+
function bsonSerialize() {
29+
return get_object_vars($this);
30+
}
31+
}
32+
33+
class Person implements BSON\Persistable {
34+
protected $_id;
35+
protected $username;
36+
protected $email;
37+
protected $name;
38+
protected $addresses = array();
39+
40+
function __construct($username, $email, $name) {
41+
$this->username = $username;
42+
$this->email = $email;
43+
$this->name = $name;
44+
45+
/* Pregenerate our ObjectID */
46+
$this->_id = new BSON\ObjectID();
47+
}
48+
function addAddress(Address $address) {
49+
$this->addresses[] = $address;
50+
}
51+
52+
function bsonUnserialize(array $array) {
53+
foreach($array as $k => $v) {
54+
$this->{$k} = $v;
55+
}
56+
}
57+
58+
function bsonSerialize() {
59+
return get_object_vars($this);
60+
}
61+
62+
function getName() {
63+
return $this->name;
64+
}
65+
}
66+
67+
68+
$bulk = new MongoDB\Driver\BulkWrite;
69+
70+
71+
$lair77 = new Person('lair77', '[email protected]', 'Claire Corwin');
72+
$hillardhaven = new Address('4527 Kohler Square Apt. 316', 'Hillardhaven', '02622-5175');
73+
$lair77->addAddress($hillardhaven);
74+
$prudencemouth = new Address('7042 Freida Springs', 'Prudencemouth', '94805');
75+
$lair77->addAddress($prudencemouth);
76+
$bulk->insert($lair77);
77+
78+
79+
80+
$hartmann = new Person('hartmann', '[email protected]', 'Hartmann Dedrick');
81+
$leannefurt = new Address('151 Delbert Hills Suite 923', 'Leannefurt', '22036');
82+
$hartmann->addAddress($leannefurt);
83+
$bulk->insert($hartmann);
84+
85+
86+
$dropcoll = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME));
87+
$query = new MongoDB\Driver\Query(array());
88+
$queryHartmann = new MongoDB\Driver\Query(array("username" => "hartmann"));
89+
90+
91+
92+
$m = new MongoDB\Driver\Manager(STANDALONE);
93+
try {
94+
$m->executeCommand(DATABASE_NAME, $dropcoll);
95+
} catch(Exception $e) {}
96+
97+
$m->executeBulkWrite(NS, $bulk);
98+
99+
100+
$res = $m->executeQuery(NS, $query);
101+
foreach($res as $person) {
102+
var_dump($person->getName());
103+
}
104+
foreach($res as $person) {
105+
echo "This will never happen: ";
106+
echo $person->getName(), "\n";
107+
}
108+
109+
echo "-----\n";
110+
$cursor = $m->executeQuery(NS, $queryHartmann);
111+
foreach($cursor as $hartmann) {
112+
echo $hartmann->getName(), "\n";
113+
}
114+
115+
foreach($cursor as $hartmann) {
116+
echo "This will never happen: ";
117+
echo $hartmann->getName(), "\n";
118+
}
119+
foreach($cursor as $hartmann) {
120+
echo "This will never happen: ";
121+
echo $hartmann->getName(), "\n";
122+
}
123+
echo "All Good!\n";
124+
?>
125+
===DONE===
126+
<?php exit(0); ?>
127+
--EXPECT--
128+
string(13) "Claire Corwin"
129+
string(16) "Hartmann Dedrick"
130+
-----
131+
Hartmann Dedrick
132+
All Good!
133+
===DONE===

0 commit comments

Comments
 (0)