@@ -1019,15 +1019,16 @@ 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
1026
1026
zend_call_method_with_0_params (& object , NULL , NULL , BSON_SERIALIZE_FUNC_NAME , & obj_data );
1027
1027
#endif
1028
1028
1029
1029
if (Z_ISUNDEF (obj_data )) {
1030
- /* zend_call_method() failed */
1030
+ /* zend_call_method() failed or bsonSerialize() threw an
1031
+ * exception. Either way, there is nothing else to do. */
1031
1032
return ;
1032
1033
}
1033
1034
@@ -1060,16 +1061,6 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
1060
1061
return ;
1061
1062
}
1062
1063
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
1064
/* Persistable objects must always be serialized as BSON documents;
1074
1065
* otherwise, infer based on bsonSerialize()'s return value. */
1075
1066
#if PHP_VERSION_ID >= 70000
@@ -1101,9 +1092,6 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
1101
1092
bson_append_array_end (bson , & child );
1102
1093
}
1103
1094
1104
- if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1105
- ZEND_HASH_DEC_APPLY_COUNT (tmp_ht );
1106
- }
1107
1095
zval_ptr_dtor (& obj_data );
1108
1096
return ;
1109
1097
}
@@ -1176,20 +1164,10 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
1176
1164
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
1165
return ;
1178
1166
} 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
1167
mongoc_log (MONGOC_LOG_LEVEL_TRACE , MONGOC_LOG_DOMAIN , "encoding document" );
1186
1168
bson_append_document_begin (bson , key , key_len , & child );
1187
1169
phongo_zval_to_bson (object , flags , & child , NULL TSRMLS_CC );
1188
1170
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
1171
}
1194
1172
}
1195
1173
@@ -1238,6 +1216,11 @@ static void phongo_bson_append(bson_t *bson, php_phongo_bson_flags_t flags, cons
1238
1216
bson_t child ;
1239
1217
HashTable * tmp_ht = HASH_OF (entry );
1240
1218
1219
+ if (tmp_ht && ZEND_HASH_GET_APPLY_COUNT (tmp_ht ) > 0 ) {
1220
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected recursion for fieldname \"%s\"" , key );
1221
+ break ;
1222
+ }
1223
+
1241
1224
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1242
1225
ZEND_HASH_INC_APPLY_COUNT (tmp_ht );
1243
1226
}
@@ -1252,9 +1235,25 @@ static void phongo_bson_append(bson_t *bson, php_phongo_bson_flags_t flags, cons
1252
1235
break ;
1253
1236
}
1254
1237
/* break intentionally omitted */
1255
- case IS_OBJECT :
1238
+ case IS_OBJECT : {
1239
+ HashTable * tmp_ht = HASH_OF (entry );
1240
+
1241
+ if (tmp_ht && ZEND_HASH_GET_APPLY_COUNT (tmp_ht ) > 0 ) {
1242
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected recursion for fieldname \"%s\"" , key );
1243
+ break ;
1244
+ }
1245
+
1246
+ if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1247
+ ZEND_HASH_INC_APPLY_COUNT (tmp_ht );
1248
+ }
1249
+
1256
1250
object_to_bson (entry , flags , key , key_len , bson TSRMLS_CC );
1251
+
1252
+ if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
1253
+ ZEND_HASH_DEC_APPLY_COUNT (tmp_ht );
1254
+ }
1257
1255
break ;
1256
+ }
1258
1257
1259
1258
#if PHP_VERSION_ID >= 70000
1260
1259
case IS_INDIRECT :
@@ -1285,6 +1284,8 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1285
1284
* properties, we'll need to filter them out later. */
1286
1285
bool ht_data_from_properties = false;
1287
1286
1287
+ ZVAL_UNDEF (& obj_data );
1288
+
1288
1289
switch (Z_TYPE_P (data )) {
1289
1290
case IS_OBJECT :
1290
1291
if (instanceof_function (Z_OBJCE_P (data ), php_phongo_serializable_ce TSRMLS_CC )) {
@@ -1295,8 +1296,9 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1295
1296
#endif
1296
1297
1297
1298
if (Z_ISUNDEF (obj_data )) {
1298
- /* zend_call_method() failed */
1299
- break ;
1299
+ /* zend_call_method() failed or bsonSerialize() threw an
1300
+ * exception. Either way, there is nothing else to do. */
1301
+ return ;
1300
1302
}
1301
1303
1302
1304
#if PHP_VERSION_ID >= 70000
@@ -1324,7 +1326,7 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1324
1326
)
1325
1327
);
1326
1328
1327
- break ;
1329
+ goto cleanup ;
1328
1330
}
1329
1331
1330
1332
#if PHP_VERSION_ID >= 70000
@@ -1349,7 +1351,7 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1349
1351
if (instanceof_function (Z_OBJCE_P (data ), php_phongo_type_ce TSRMLS_CC )) {
1350
1352
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
1353
1352
- break ;
1354
+ return ;
1353
1355
}
1354
1356
1355
1357
ht_data = Z_OBJ_HT_P (data )-> get_properties (data TSRMLS_CC );
@@ -1364,19 +1366,6 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1364
1366
return ;
1365
1367
}
1366
1368
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
1369
#if PHP_VERSION_ID >= 70000
1381
1370
{
1382
1371
zend_string * string_key = NULL ;
@@ -1483,15 +1472,11 @@ void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson
1483
1472
}
1484
1473
}
1485
1474
}
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
1475
+
1476
+ cleanup :
1477
+ if (!Z_ISUNDEF (obj_data )) {
1478
+ zval_ptr_dtor (& obj_data );
1493
1479
}
1494
- #endif
1495
1480
}
1496
1481
1497
1482
/* }}} */
0 commit comments