@@ -1019,7 +1019,7 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
1019
1019
zval * obj_data = NULL ;
1020
1020
#endif
1021
1021
bson_t child ;
1022
- HashTable * tmp_ht ;
1022
+
1023
1023
#if PHP_VERSION_ID >= 70000
1024
1024
zend_call_method_with_0_params (object , NULL , NULL , BSON_SERIALIZE_FUNC_NAME , & obj_data );
1025
1025
#else
@@ -1060,16 +1060,6 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
1060
1060
return ;
1061
1061
}
1062
1062
1063
- #if PHP_VERSION_ID >= 70000
1064
- tmp_ht = HASH_OF (& obj_data );
1065
- #else
1066
- tmp_ht = HASH_OF (obj_data );
1067
- #endif
1068
-
1069
- if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1070
- ZEND_HASH_INC_APPLY_COUNT (tmp_ht );
1071
- }
1072
-
1073
1063
/* Persistable objects must always be serialized as BSON documents;
1074
1064
* otherwise, infer based on bsonSerialize()'s return value. */
1075
1065
#if PHP_VERSION_ID >= 70000
@@ -1101,9 +1091,6 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
1101
1091
bson_append_array_end (bson , & child );
1102
1092
}
1103
1093
1104
- if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1105
- ZEND_HASH_DEC_APPLY_COUNT (tmp_ht );
1106
- }
1107
1094
zval_ptr_dtor (& obj_data );
1108
1095
return ;
1109
1096
}
@@ -1176,20 +1163,10 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
1176
1163
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 ));
1177
1164
return ;
1178
1165
} else {
1179
- HashTable * tmp_ht = HASH_OF (object );
1180
-
1181
- if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1182
- ZEND_HASH_INC_APPLY_COUNT (tmp_ht );
1183
- }
1184
-
1185
1166
mongoc_log (MONGOC_LOG_LEVEL_TRACE , MONGOC_LOG_DOMAIN , "encoding document" );
1186
1167
bson_append_document_begin (bson , key , key_len , & child );
1187
1168
phongo_zval_to_bson (object , flags , & child , NULL TSRMLS_CC );
1188
1169
bson_append_document_end (bson , & child );
1189
-
1190
- if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1191
- ZEND_HASH_DEC_APPLY_COUNT (tmp_ht );
1192
- }
1193
1170
}
1194
1171
}
1195
1172
@@ -1238,6 +1215,11 @@ static void phongo_bson_append(bson_t *bson, php_phongo_bson_flags_t flags, cons
1238
1215
bson_t child ;
1239
1216
HashTable * tmp_ht = HASH_OF (entry );
1240
1217
1218
+ if (tmp_ht && ZEND_HASH_GET_APPLY_COUNT (tmp_ht ) > 0 ) {
1219
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected recursion for fieldname \"%s\"" , key );
1220
+ break ;
1221
+ }
1222
+
1241
1223
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1242
1224
ZEND_HASH_INC_APPLY_COUNT (tmp_ht );
1243
1225
}
@@ -1252,9 +1234,25 @@ static void phongo_bson_append(bson_t *bson, php_phongo_bson_flags_t flags, cons
1252
1234
break ;
1253
1235
}
1254
1236
/* break intentionally omitted */
1255
- case IS_OBJECT :
1237
+ case IS_OBJECT : {
1238
+ HashTable * tmp_ht = HASH_OF (entry );
1239
+
1240
+ if (tmp_ht && ZEND_HASH_GET_APPLY_COUNT (tmp_ht ) > 0 ) {
1241
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected recursion for fieldname \"%s\"" , key );
1242
+ break ;
1243
+ }
1244
+
1245
+ if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1246
+ ZEND_HASH_INC_APPLY_COUNT (tmp_ht );
1247
+ }
1248
+
1256
1249
object_to_bson (entry , flags , key , key_len , bson TSRMLS_CC );
1250
+
1251
+ if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1252
+ ZEND_HASH_DEC_APPLY_COUNT (tmp_ht );
1253
+ }
1257
1254
break ;
1255
+ }
1258
1256
1259
1257
#if PHP_VERSION_ID >= 70000
1260
1258
case IS_INDIRECT :
@@ -1285,6 +1283,8 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1285
1283
* properties, we'll need to filter them out later. */
1286
1284
bool ht_data_from_properties = false;
1287
1285
1286
+ ZVAL_UNDEF (& obj_data );
1287
+
1288
1288
switch (Z_TYPE_P (data )) {
1289
1289
case IS_OBJECT :
1290
1290
if (instanceof_function (Z_OBJCE_P (data ), php_phongo_serializable_ce TSRMLS_CC )) {
@@ -1296,7 +1296,7 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1296
1296
1297
1297
if (Z_ISUNDEF (obj_data )) {
1298
1298
/* zend_call_method() failed */
1299
- break ;
1299
+ return ;
1300
1300
}
1301
1301
1302
1302
#if PHP_VERSION_ID >= 70000
@@ -1324,7 +1324,7 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1324
1324
)
1325
1325
);
1326
1326
1327
- break ;
1327
+ goto cleanup ;
1328
1328
}
1329
1329
1330
1330
#if PHP_VERSION_ID >= 70000
@@ -1349,7 +1349,7 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1349
1349
if (instanceof_function (Z_OBJCE_P (data ), php_phongo_type_ce TSRMLS_CC )) {
1350
1350
phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "%s instance %s cannot be serialized as a root element" , ZSTR_VAL (php_phongo_type_ce -> name ), ZSTR_VAL (Z_OBJCE_P (data )-> name ));
1351
1351
1352
- break ;
1352
+ return ;
1353
1353
}
1354
1354
1355
1355
ht_data = Z_OBJ_HT_P (data )-> get_properties (data TSRMLS_CC );
@@ -1364,19 +1364,6 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1364
1364
return ;
1365
1365
}
1366
1366
1367
- if (!ht_data || ZEND_HASH_GET_APPLY_COUNT (ht_data ) > 1 ) {
1368
- #if PHP_VERSION_ID >= 70000
1369
- if (Z_TYPE_P (data ) == IS_OBJECT && instanceof_function (Z_OBJCE_P (data ), php_phongo_serializable_ce TSRMLS_CC )) {
1370
- #endif
1371
- if (!Z_ISUNDEF (obj_data )) {
1372
- zval_ptr_dtor (& obj_data );
1373
- }
1374
- #if PHP_VERSION_ID >= 70000
1375
- }
1376
- #endif
1377
- return ;
1378
- }
1379
-
1380
1367
#if PHP_VERSION_ID >= 70000
1381
1368
{
1382
1369
zend_string * string_key = NULL ;
@@ -1483,15 +1470,11 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1483
1470
}
1484
1471
}
1485
1472
}
1486
- #if PHP_VERSION_ID >= 70000
1487
- if (Z_TYPE_P (data ) == IS_OBJECT && instanceof_function (Z_OBJCE_P (data ), php_phongo_serializable_ce TSRMLS_CC )) {
1488
- #endif
1489
- if (!Z_ISUNDEF (obj_data )) {
1490
- zval_ptr_dtor (& obj_data );
1491
- }
1492
- #if PHP_VERSION_ID >= 70000
1473
+
1474
+ cleanup :
1475
+ if (!Z_ISUNDEF (obj_data )) {
1476
+ zval_ptr_dtor (& obj_data );
1493
1477
}
1494
- #endif
1495
1478
}
1496
1479
1497
1480
/* }}} */
0 commit comments