Skip to content

Commit eff1969

Browse files
committed
PHPC:2498: Accept integer types for Document array access
1 parent 65bbd1b commit eff1969

File tree

5 files changed

+130
-45
lines changed

5 files changed

+130
-45
lines changed

src/BSON/Document.c

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,36 @@ static bool php_phongo_document_get(php_phongo_document_t* intern, char* key, si
192192
return true;
193193
}
194194

195+
static bool php_phongo_document_get_by_zval(php_phongo_document_t* intern, zval* key, zval* return_value, bool null_if_missing)
196+
{
197+
if (Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_LONG) {
198+
if (null_if_missing) {
199+
ZVAL_NULL(return_value);
200+
return true;
201+
}
202+
203+
phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Could not find key of type \"%s\" in BSON document", zend_zval_type_name(key));
204+
return false;
205+
}
206+
207+
zend_string* tmp_str;
208+
zend_string* str = zval_try_get_tmp_string(key, &tmp_str);
209+
210+
if (!str) {
211+
// Exception already thrown
212+
return false;
213+
}
214+
215+
if (!php_phongo_document_get(intern, ZSTR_VAL(str), ZSTR_LEN(str), return_value, null_if_missing)) {
216+
// Exception already thrown
217+
zend_tmp_string_release(tmp_str);
218+
return false;
219+
}
220+
221+
zend_tmp_string_release(tmp_str);
222+
return true;
223+
}
224+
195225
static PHP_METHOD(MongoDB_BSON_Document, get)
196226
{
197227
php_phongo_document_t* intern;
@@ -229,6 +259,30 @@ static bool php_phongo_document_has(php_phongo_document_t* intern, char* key, si
229259
return bson_iter_find_w_len(&iter, key, key_len);
230260
}
231261

262+
static bool php_phongo_document_has_by_zval(php_phongo_document_t* intern, zval* key)
263+
{
264+
if (Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_LONG) {
265+
return false;
266+
}
267+
268+
zend_string* tmp_str;
269+
zend_string* str = zval_try_get_tmp_string(key, &tmp_str);
270+
271+
if (!str) {
272+
// Exception already thrown
273+
return false;
274+
}
275+
276+
if (!php_phongo_document_has(intern, ZSTR_VAL(str), ZSTR_LEN(str))) {
277+
// Exception may be thrown if BSON iterator could not be initialized
278+
zend_tmp_string_release(tmp_str);
279+
return false;
280+
}
281+
282+
zend_tmp_string_release(tmp_str);
283+
return true;
284+
}
285+
232286
static PHP_METHOD(MongoDB_BSON_Document, has)
233287
{
234288
php_phongo_document_t* intern;
@@ -309,11 +363,7 @@ static PHP_METHOD(MongoDB_BSON_Document, offsetExists)
309363

310364
intern = Z_DOCUMENT_OBJ_P(getThis());
311365

312-
if (Z_TYPE_P(offset) != IS_STRING) {
313-
RETURN_FALSE;
314-
}
315-
316-
RETURN_BOOL(php_phongo_document_has(intern, Z_STRVAL_P(offset), Z_STRLEN_P(offset)));
366+
RETURN_BOOL(php_phongo_document_has_by_zval(intern, offset));
317367
}
318368

319369
static PHP_METHOD(MongoDB_BSON_Document, offsetGet)
@@ -327,13 +377,8 @@ static PHP_METHOD(MongoDB_BSON_Document, offsetGet)
327377

328378
intern = Z_DOCUMENT_OBJ_P(getThis());
329379

330-
if (Z_TYPE_P(offset) != IS_STRING) {
331-
phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Could not find key of type \"%s\" in BSON document", zend_zval_type_name(offset));
332-
return;
333-
}
334-
335380
// May throw, in which case we do nothing
336-
php_phongo_document_get(intern, Z_STRVAL_P(offset), Z_STRLEN_P(offset), return_value, false);
381+
php_phongo_document_get_by_zval(intern, offset, return_value, false);
337382
}
338383

339384
static PHP_METHOD(MongoDB_BSON_Document, offsetSet)
@@ -588,21 +633,9 @@ void php_phongo_document_unset_property(zend_object* object, zend_string* member
588633

589634
zval* php_phongo_document_read_dimension(zend_object* object, zval* offset, int type, zval* rv)
590635
{
591-
php_phongo_document_t* intern;
592-
593-
intern = Z_OBJ_DOCUMENT(object);
594-
595-
if (Z_TYPE_P(offset) != IS_STRING) {
596-
if (type == BP_VAR_IS) {
597-
ZVAL_NULL(rv);
598-
return rv;
599-
}
600-
601-
phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Could not find key of type \"%s\" in BSON document", zend_zval_type_name(offset));
602-
return &EG(uninitialized_zval);
603-
}
636+
php_phongo_document_t* intern = Z_OBJ_DOCUMENT(object);
604637

605-
if (!php_phongo_document_get(intern, Z_STRVAL_P(offset), Z_STRLEN_P(offset), rv, type == BP_VAR_IS)) {
638+
if (!php_phongo_document_get_by_zval(intern, offset, rv, type == BP_VAR_IS)) {
606639
// Exception already thrown
607640
return &EG(uninitialized_zval);
608641
}
@@ -617,15 +650,9 @@ void php_phongo_document_write_dimension(zend_object* object, zval* offset, zval
617650

618651
int php_phongo_document_has_dimension(zend_object* object, zval* member, int check_empty)
619652
{
620-
php_phongo_document_t* intern;
621-
622-
intern = Z_OBJ_DOCUMENT(object);
623-
624-
if (Z_TYPE_P(member) != IS_STRING) {
625-
return false;
626-
}
653+
php_phongo_document_t* intern = Z_OBJ_DOCUMENT(object);
627654

628-
return php_phongo_document_has(intern, Z_STRVAL_P(member), Z_STRLEN_P(member));
655+
return php_phongo_document_has_by_zval(intern, member);
629656
}
630657

631658
void php_phongo_document_unset_dimension(zend_object* object, zval* offset)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
MongoDB\BSON\Document array access with integers (dimension object accessors)
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/basic.inc';
7+
8+
$document = MongoDB\BSON\Document::fromPHP([
9+
'0' => 'foo',
10+
'1' => 'bar',
11+
]);
12+
13+
// Use a variable to assert that conversion doesn't affect the original zval
14+
$key = 1;
15+
16+
var_dump(isset($document[0]));
17+
var_dump(isset($document[$key]));
18+
var_dump(isset($document[2]));
19+
20+
var_dump($document[0]);
21+
var_dump($document[$key]);
22+
23+
var_dump($key);
24+
25+
?>
26+
===DONE===
27+
<?php exit(0); ?>
28+
--EXPECT--
29+
bool(true)
30+
bool(true)
31+
bool(false)
32+
string(3) "foo"
33+
string(3) "bar"
34+
int(1)
35+
===DONE===
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
MongoDB\BSON\Document array access with integers (ArrayAccess methods)
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/basic.inc';
7+
8+
$document = MongoDB\BSON\Document::fromPHP([
9+
'0' => 'foo',
10+
'1' => 'bar',
11+
]);
12+
13+
// Use a variable to assert that conversion doesn't affect the original zval
14+
$key = 1;
15+
16+
var_dump($document->offsetExists(0));
17+
var_dump($document->offsetExists($key));
18+
var_dump($document->offsetExists(2));
19+
20+
var_dump($document->offsetGet(0));
21+
var_dump($document->offsetGet($key));
22+
23+
var_dump($key);
24+
25+
?>
26+
===DONE===
27+
<?php exit(0); ?>
28+
--EXPECT--
29+
bool(true)
30+
bool(true)
31+
bool(false)
32+
string(3) "foo"
33+
string(3) "bar"
34+
int(1)
35+
===DONE===

tests/bson/bson-document-array-access_error-003.phpt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ $document = MongoDB\BSON\Document::fromPHP([
1111
'int64' => new MongoDB\BSON\Int64(123),
1212
]);
1313

14-
echo throws(function() use ($document) {
15-
$document[0];
16-
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";
17-
1814
echo throws(function() use ($document) {
1915
$document[0.1];
2016
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";
@@ -28,8 +24,6 @@ echo throws(function() use ($document) {
2824
<?php exit(0); ?>
2925
--EXPECT--
3026
OK: Got MongoDB\Driver\Exception\RuntimeException
31-
Could not find key of type "int" in BSON document
32-
OK: Got MongoDB\Driver\Exception\RuntimeException
3327
Could not find key of type "float" in BSON document
3428
OK: Got MongoDB\Driver\Exception\RuntimeException
3529
Could not find key of type "bool" in BSON document

tests/bson/bson-document-array-access_error-004.phpt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ $document = MongoDB\BSON\Document::fromPHP([
1111
'int64' => new MongoDB\BSON\Int64(123),
1212
]);
1313

14-
echo throws(function() use ($document) {
15-
$document->offsetGet(0);
16-
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";
17-
1814
echo throws(function() use ($document) {
1915
$document->offsetGet(0.1);
2016
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";
@@ -28,8 +24,6 @@ echo throws(function() use ($document) {
2824
<?php exit(0); ?>
2925
--EXPECT--
3026
OK: Got MongoDB\Driver\Exception\RuntimeException
31-
Could not find key of type "int" in BSON document
32-
OK: Got MongoDB\Driver\Exception\RuntimeException
3327
Could not find key of type "float" in BSON document
3428
OK: Got MongoDB\Driver\Exception\RuntimeException
3529
Could not find key of type "bool" in BSON document

0 commit comments

Comments
 (0)