Skip to content

Commit cda461d

Browse files
committed
PHPC-2456: Correctly dereference arrays in type maps
1 parent 3ffbe12 commit cda461d

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

src/contrib/php_array_api.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,17 @@ char *php_array_zval_to_string(zval *z, int *plen, zend_bool *pfree) {
420420
* zval *php_array_fetchz_array(zval *zarr, zval *key)
421421
*/
422422
static inline zval *php_array_zval_to_array(zval *zarr) {
423-
return (zarr && (Z_TYPE_P(zarr) == IS_ARRAY)) ? zarr : NULL;
423+
try_again:
424+
if (!zarr) { return NULL; }
425+
switch (Z_TYPE_P(zarr)) {
426+
case IS_REFERENCE:
427+
ZVAL_DEREF(zarr);
428+
goto try_again;
429+
case IS_ARRAY:
430+
return zarr;
431+
default:
432+
return NULL;
433+
}
424434
}
425435
PHP_ARRAY_FETCH_TYPE_MAP(zval*, array)
426436
#define php_array_fetchc_array(zarr, litstr) \
@@ -493,8 +503,17 @@ void *php_array_zval_to_resource(zval *z, int le) {
493503
*/
494504
static inline
495505
zval *php_array_zval_to_object(zval *z, zend_class_entry *ce) {
496-
return (z && (Z_TYPE_P(z) == IS_OBJECT) &&
497-
((!ce) || instanceof_function(Z_OBJCE_P(z), ce))) ? z : NULL;
506+
try_again:
507+
if (!z) { return NULL; }
508+
switch (Z_TYPE_P(z)) {
509+
case IS_REFERENCE:
510+
ZVAL_DEREF(z);
511+
goto try_again;
512+
case IS_OBJECT:
513+
return (!ce) || instanceof_function(Z_OBJCE_P(z), ce) ? z : NULL;
514+
default:
515+
return NULL;
516+
}
498517
}
499518
#define php_array_fetch_object(zarr, key, ce) \
500519
php_array_zval_to_object(php_array_fetch(zarr, key), ce)

tests/bson/bug2456-001.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
PHPC-2456: References passed in a typeMap
3+
--FILE--
4+
<?php
5+
require_once __DIR__ . "/../utils/basic.inc";
6+
7+
$fieldPaths = [];
8+
9+
$typeMap = ['fieldPaths' => &$fieldPaths];
10+
11+
var_dump(MongoDB\BSON\Document::fromPHP([])->toPHP($typeMap));
12+
var_dump(MongoDB\BSON\PackedArray::fromPHP([])->toPHP($typeMap));
13+
var_dump(MongoDB\BSON\toPHP(MongoDB\BSON\fromPHP([]), $typeMap));
14+
15+
?>
16+
===DONE===
17+
<?php exit(0); ?>
18+
--EXPECTF--
19+
object(stdClass)#%d (0) {
20+
}
21+
array(0) {
22+
}
23+
object(stdClass)#%d (0) {
24+
}
25+
===DONE===

0 commit comments

Comments
 (0)