diff --git a/src/contrib/php_array_api.h b/src/contrib/php_array_api.h index 9a332524d..76358dbb9 100644 --- a/src/contrib/php_array_api.h +++ b/src/contrib/php_array_api.h @@ -281,8 +281,12 @@ PHP_ARRAY_FETCH_TYPE_MAP(zend_bool, bool) */ static inline PAA_LONG php_array_zval_to_long(zval *z) { +try_again: if (!z) { return 0; } switch(Z_TYPE_P(z)) { + case IS_REFERENCE: + ZVAL_DEREF(z); + goto try_again; case IS_NULL: return 0; #ifdef ZEND_ENGINE_3 case IS_FALSE: return 0; @@ -315,8 +319,12 @@ PHP_ARRAY_FETCH_TYPE_MAP(PAA_LONG, long) */ static inline double php_array_zval_to_double(zval *z) { +try_again: if (!z) { return 0.0; } switch (Z_TYPE_P(z)) { + case IS_REFERENCE: + ZVAL_DEREF(z); + goto try_again; case IS_NULL: return 0.0; #ifdef ZEND_ENGINE_3 case IS_FALSE: return 0.0; @@ -357,10 +365,14 @@ static inline char *php_array_zval_to_string(zval *z, int *plen, zend_bool *pfree) { *plen = 0; *pfree = 0; +try_again: if (!z) { return NULL; } switch (Z_TYPE_P(z)) { case IS_NULL: return (char *)""; + case IS_REFERENCE: + ZVAL_DEREF(z); + goto try_again; case IS_STRING: *plen = Z_STRLEN_P(z); return Z_STRVAL_P(z); diff --git a/tests/bson/bug1839-001.phpt b/tests/bson/bug1839-001.phpt new file mode 100644 index 000000000..5b1e751dd --- /dev/null +++ b/tests/bson/bug1839-001.phpt @@ -0,0 +1,48 @@ +--TEST-- +PHPC-1839: Referenced, out-of-scope, non-interned string in typeMap +--FILE-- + &$rootValue, 'document' => &$documentValue]; + + return $typemap; +} + +$typemap = createTypemap(); +$bson = MongoDB\BSON\fromPhp((object) []); + +echo "Before:\n"; +debug_zval_dump($typemap); + +MongoDB\BSON\toPHP($bson, $typemap); + +echo "After:\n"; +debug_zval_dump($typemap); + +?> +===DONE=== + +--EXPECT-- +Before: +array(2) refcount(2){ + ["root"]=> + string(5) "array" refcount(1) + ["document"]=> + string(5) "array" refcount(1) +} +After: +array(2) refcount(2){ + ["root"]=> + string(5) "array" refcount(1) + ["document"]=> + string(5) "array" refcount(1) +} +===DONE=== diff --git a/tests/bson/bug1839-002.phpt b/tests/bson/bug1839-002.phpt new file mode 100644 index 000000000..b4e919a2a --- /dev/null +++ b/tests/bson/bug1839-002.phpt @@ -0,0 +1,40 @@ +--TEST-- +PHPC-1839: Referenced, local, non-interned string in typeMap +--FILE-- + &$rootValue, 'document' => &$documentValue]; +$bson = MongoDB\BSON\fromPhp((object) []); + +echo "Before:\n"; +debug_zval_dump($typemap); + +MongoDB\BSON\toPHP($bson, $typemap); + +echo "After:\n"; +debug_zval_dump($typemap); + +?> +===DONE=== + +--EXPECT-- +Before: +array(2) refcount(2){ + ["root"]=> + &string(5) "array" refcount(1) + ["document"]=> + &string(5) "array" refcount(1) +} +After: +array(2) refcount(2){ + ["root"]=> + &string(5) "array" refcount(1) + ["document"]=> + &string(5) "array" refcount(1) +} +===DONE=== diff --git a/tests/bson/bug1839-003.phpt b/tests/bson/bug1839-003.phpt new file mode 100644 index 000000000..87f33d07f --- /dev/null +++ b/tests/bson/bug1839-003.phpt @@ -0,0 +1,46 @@ +--TEST-- +PHPC-1839: Referenced, out-of-scope, interned string in typeMap +--FILE-- + &$rootValue, 'document' => &$documentValue]; + + return $typemap; +} + +$typemap = createTypemap(); +$bson = MongoDB\BSON\fromPhp((object) []); + +echo "Before:\n"; +debug_zval_dump($typemap); + +MongoDB\BSON\toPHP($bson, $typemap); + +echo "After:\n"; +debug_zval_dump($typemap); + +?> +===DONE=== + +--EXPECT-- +Before: +array(2) refcount(2){ + ["root"]=> + string(5) "array" refcount(1) + ["document"]=> + string(5) "array" refcount(1) +} +After: +array(2) refcount(2){ + ["root"]=> + string(5) "array" refcount(1) + ["document"]=> + string(5) "array" refcount(1) +} +===DONE=== diff --git a/tests/bson/bug1839-004.phpt b/tests/bson/bug1839-004.phpt new file mode 100644 index 000000000..42dbcf25a --- /dev/null +++ b/tests/bson/bug1839-004.phpt @@ -0,0 +1,39 @@ +--TEST-- +PHPC-1839: Referenced, local, interned string in typeMap +--FILE-- + &$rootValue, 'document' => &$documentValue]; +$bson = MongoDB\BSON\fromPhp((object) []); + +echo "Before:\n"; +debug_zval_dump($typemap); + +MongoDB\BSON\toPHP($bson, $typemap); + +echo "After:\n"; +debug_zval_dump($typemap); + +?> +===DONE=== + +--EXPECT-- +Before: +array(2) refcount(2){ + ["root"]=> + &string(5) "array" refcount(1) + ["document"]=> + &string(5) "array" refcount(1) +} +After: +array(2) refcount(2){ + ["root"]=> + &string(5) "array" refcount(1) + ["document"]=> + &string(5) "array" refcount(1) +} +===DONE===