Skip to content

Commit 99f4cbc

Browse files
committed
Merge branch 'v1.1'
2 parents 33b9e5f + b525a9b commit 99f4cbc

File tree

3 files changed

+66
-15
lines changed

3 files changed

+66
-15
lines changed

phongo_compat.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,10 @@
136136
# define Z_ISUNDEF(x) !x
137137
# define phongo_free_object_arg void
138138
# define phongo_zpp_char_len int
139-
# define ZEND_HASH_APPLY_COUNT(ht) (ht)->nApplyCount
139+
# define ZEND_HASH_APPLY_PROTECTION(ht) true
140+
# define ZEND_HASH_GET_APPLY_COUNT(ht) ((ht)->nApplyCount)
141+
# define ZEND_HASH_DEC_APPLY_COUNT(ht) ((ht)->nApplyCount -= 1)
142+
# define ZEND_HASH_INC_APPLY_COUNT(ht) ((ht)->nApplyCount += 1)
140143
# define PHONGO_RETVAL_STRINGL(s, slen) RETVAL_STRINGL(s, slen, 1)
141144
# define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen, 1)
142145
# define PHONGO_RETVAL_STRING(s) RETVAL_STRING(s, 1)

src/bson.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -905,8 +905,8 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
905905
tmp_ht = HASH_OF(obj_data);
906906
#endif
907907

908-
if (tmp_ht) {
909-
ZEND_HASH_APPLY_COUNT(tmp_ht)++;
908+
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
909+
ZEND_HASH_INC_APPLY_COUNT(tmp_ht);
910910
}
911911

912912
/* Persistable objects must always be serialized as BSON documents;
@@ -940,8 +940,8 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
940940
bson_append_array_end(bson, &child);
941941
}
942942

943-
if (tmp_ht) {
944-
ZEND_HASH_APPLY_COUNT(tmp_ht)--;
943+
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
944+
ZEND_HASH_DEC_APPLY_COUNT(tmp_ht);
945945
}
946946
zval_ptr_dtor(&obj_data);
947947
return;
@@ -1014,12 +1014,22 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
10141014

10151015
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Unexpected %s instance: %s", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(object)->name));
10161016
return;
1017-
}
1017+
} else {
1018+
HashTable *tmp_ht = HASH_OF(object);
1019+
1020+
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
1021+
ZEND_HASH_INC_APPLY_COUNT(tmp_ht);
1022+
}
10181023

1019-
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding document");
1020-
bson_append_document_begin(bson, key, key_len, &child);
1021-
phongo_zval_to_bson(object, flags, &child, NULL TSRMLS_CC);
1022-
bson_append_document_end(bson, &child);
1024+
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding document");
1025+
bson_append_document_begin(bson, key, key_len, &child);
1026+
phongo_zval_to_bson(object, flags, &child, NULL TSRMLS_CC);
1027+
bson_append_document_end(bson, &child);
1028+
1029+
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
1030+
ZEND_HASH_DEC_APPLY_COUNT(tmp_ht);
1031+
}
1032+
}
10231033
}
10241034

10251035
static void phongo_bson_append(bson_t *bson, php_phongo_bson_flags_t flags, const char *key, long key_len, zval *entry TSRMLS_DC)
@@ -1067,16 +1077,16 @@ static void phongo_bson_append(bson_t *bson, php_phongo_bson_flags_t flags, cons
10671077
bson_t child;
10681078
HashTable *tmp_ht = HASH_OF(entry);
10691079

1070-
if (tmp_ht) {
1071-
ZEND_HASH_APPLY_COUNT(tmp_ht)++;
1080+
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
1081+
ZEND_HASH_INC_APPLY_COUNT(tmp_ht);
10721082
}
10731083

10741084
bson_append_array_begin(bson, key, key_len, &child);
10751085
phongo_zval_to_bson(entry, flags, &child, NULL TSRMLS_CC);
10761086
bson_append_array_end(bson, &child);
10771087

1078-
if (tmp_ht) {
1079-
ZEND_HASH_APPLY_COUNT(tmp_ht)--;
1088+
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
1089+
ZEND_HASH_DEC_APPLY_COUNT(tmp_ht);
10801090
}
10811091
break;
10821092
}
@@ -1231,7 +1241,7 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
12311241
return;
12321242
}
12331243

1234-
if (!ht_data || ZEND_HASH_APPLY_COUNT(ht_data) > 1) {
1244+
if (!ht_data || ZEND_HASH_GET_APPLY_COUNT(ht_data) > 1) {
12351245
#if PHP_VERSION_ID >= 70000
12361246
if (Z_TYPE_P(data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(data), php_phongo_serializable_ce TSRMLS_CC)) {
12371247
#endif

tests/bson/bson-fromPHP-004.phpt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
BSON\fromPHP(): PHP documents with circular references
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/tools.php';
7+
8+
echo "\nTesting packed array with circular reference\n";
9+
10+
$document = ['x' => 1, 'y' => []];
11+
$document['y'][] = &$document['y'];
12+
echo toJson(fromPHP($document)), "\n";
13+
14+
echo "\nTesting associative array with circular reference\n";
15+
16+
$document = ['x' => 1, 'y' => []];
17+
$document['y']['z'] = &$document['y'];
18+
echo toJson(fromPHP($document)), "\n";
19+
20+
echo "\nTesting object with circular reference\n";
21+
22+
$document = (object) ['x' => 1, 'y' => (object) []];
23+
$document->y->z = &$document->y;
24+
echo toJson(fromPHP($document)), "\n";
25+
26+
?>
27+
===DONE===
28+
<?php exit(0); ?>
29+
--EXPECTF--
30+
Testing packed array with circular reference
31+
{ "x" : 1, "y" : [ [ ] ] }
32+
33+
Testing associative array with circular reference
34+
{ "x" : 1, "y" : { "z" : { } } }
35+
36+
Testing object with circular reference
37+
{ "x" : 1, "y" : { "z" : { } } }
38+
===DONE===

0 commit comments

Comments
 (0)