@@ -1206,99 +1206,109 @@ PHONGO_API void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, b
1206
1206
1207
1207
#if PHP_VERSION_ID >= 70000
1208
1208
{
1209
- zend_string * key ;
1210
- zend_ulong num_key ;
1211
- zval * value ;
1212
-
1213
- ZEND_HASH_FOREACH_KEY_VAL (ht_data , num_key , key , value ) {
1214
- if (key ) {
1215
- if (Z_TYPE_P (data ) == IS_OBJECT ) {
1216
- zend_string * member = NULL ;
1217
-
1218
- /* Ignore non-public properties */
1219
- if (!instanceof_function (Z_OBJCE_P (data ), php_phongo_serializable_ce ) &&
1220
- !is_public_property (Z_OBJCE_P (data ), key , & member TSRMLS_CC )) {
1221
- if (member ) {
1222
- zend_string_release (member );
1223
- }
1224
- continue ;
1225
- }
1226
-
1227
- if (flags & PHONGO_BSON_ADD_ID ) {
1228
- if (!strncmp (member ? ZSTR_VAL (member ) : ZSTR_VAL (key ), "_id" , sizeof ("_id" )- 1 )) {
1229
- flags &= ~PHONGO_BSON_ADD_ID ;
1230
- }
1231
- }
1209
+ zend_string * string_key = NULL ;
1210
+ zend_ulong num_key = 0 ;
1211
+ zval * value ;
1212
+
1213
+ ZEND_HASH_FOREACH_KEY_VAL (ht_data , num_key , string_key , value ) {
1214
+ /* Ensure we're working with a string key */
1215
+ if (!string_key ) {
1216
+ string_key = zend_long_to_str (num_key );
1217
+ } else {
1218
+ zend_string_addref (string_key );
1219
+ }
1232
1220
1233
- phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID ,
1234
- member ? ZSTR_VAL (member ) : ZSTR_VAL (key ),
1235
- member ? ZSTR_LEN (member ) : ZSTR_LEN (key ),
1236
- value TSRMLS_CC );
1221
+ if (Z_TYPE_P (data ) == IS_OBJECT ) {
1222
+ zend_string * member = NULL ;
1237
1223
1224
+ /* Ignore non-public properties */
1225
+ if (!instanceof_function (Z_OBJCE_P (data ), php_phongo_serializable_ce ) &&
1226
+ !is_public_property (Z_OBJCE_P (data ), string_key , & member TSRMLS_CC )) {
1238
1227
if (member ) {
1239
1228
zend_string_release (member );
1240
1229
}
1241
- } else {
1242
- if (flags & PHONGO_BSON_ADD_ID ) {
1243
- if (!strncmp (ZSTR_VAL (key ), "_id" , sizeof ("_id" )- 1 )) {
1244
- flags &= ~PHONGO_BSON_ADD_ID ;
1245
- }
1230
+ zend_string_release (string_key );
1231
+ continue ;
1232
+ }
1233
+
1234
+ if (flags & PHONGO_BSON_ADD_ID ) {
1235
+ if (!strncmp (member ? ZSTR_VAL (member ) : ZSTR_VAL (string_key ), "_id" , sizeof ("_id" )- 1 )) {
1236
+ flags &= ~PHONGO_BSON_ADD_ID ;
1246
1237
}
1247
- phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID , ZSTR_VAL (key ), ZSTR_LEN (key ), value TSRMLS_CC );
1238
+ }
1239
+
1240
+ phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID ,
1241
+ member ? ZSTR_VAL (member ) : ZSTR_VAL (string_key ),
1242
+ member ? ZSTR_LEN (member ) : ZSTR_LEN (string_key ),
1243
+ value TSRMLS_CC );
1244
+
1245
+ if (member ) {
1246
+ zend_string_release (member );
1248
1247
}
1249
1248
} else {
1250
- char numbuf [32 ];
1251
- const char * skey ;
1252
- unsigned int skey_len = 0 ;
1253
- skey_len = bson_uint32_to_string (num_key , (const char * * )& skey , numbuf , sizeof (numbuf ));
1254
- phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID , skey , skey_len , value TSRMLS_CC );
1249
+ if (flags & PHONGO_BSON_ADD_ID ) {
1250
+ if (!strncmp (ZSTR_VAL (string_key ), "_id" , sizeof ("_id" )- 1 )) {
1251
+ flags &= ~PHONGO_BSON_ADD_ID ;
1252
+ }
1253
+ }
1254
+ phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID , ZSTR_VAL (string_key ), ZSTR_LEN (string_key ), value TSRMLS_CC );
1255
1255
}
1256
+
1257
+ zend_string_release (string_key );
1256
1258
} ZEND_HASH_FOREACH_END ();
1257
1259
}
1258
1260
#else
1259
1261
zend_hash_internal_pointer_reset_ex (ht_data , & pos );
1260
1262
for (;; zend_hash_move_forward_ex (ht_data , & pos )) {
1261
- unsigned int key_len = 0 ;
1262
- uint64_t index = 0 ;
1263
- char numbuf [32 ];
1264
- char * key = NULL ;
1265
- zval * * entry ;
1266
- int hash_type = HASH_KEY_NON_EXISTENT ;
1263
+ char * string_key = NULL ;
1264
+ uint string_key_len = 0 ;
1265
+ ulong num_key = 0 ;
1266
+ zval * * value ;
1267
+ int hash_type ;
1267
1268
1268
- hash_type = zend_hash_get_current_key_ex (ht_data , & key , & key_len , & index , 0 , & pos );
1269
+ hash_type = zend_hash_get_current_key_ex (ht_data , & string_key , & string_key_len , & num_key , 0 , & pos );
1269
1270
1270
1271
if (hash_type == HASH_KEY_NON_EXISTENT ) {
1271
1272
break ;
1272
1273
}
1273
1274
1274
- if (zend_hash_get_current_data_ex (ht_data , (void * * ) & entry , & pos ) == FAILURE ) {
1275
+ if (zend_hash_get_current_data_ex (ht_data , (void * * ) & value , & pos ) == FAILURE ) {
1275
1276
break ;
1276
1277
}
1277
1278
1278
1279
if (hash_type == HASH_KEY_IS_STRING ) {
1279
1280
if (ht_data_from_properties ) {
1280
1281
const char * class_name ;
1281
- zend_unmangle_property_name (key , key_len - 1 , & class_name , (const char * * )& key );
1282
- key_len = strlen (key );
1282
+ zend_unmangle_property_name (string_key , string_key_len - 1 , & class_name , (const char * * )& string_key );
1283
+ string_key_len = strlen (string_key );
1283
1284
1284
1285
/* Ignore non-public properties */
1285
- if (!is_public_property (Z_OBJCE_P (data ), key , key_len TSRMLS_CC )) {
1286
+ if (!is_public_property (Z_OBJCE_P (data ), string_key , string_key_len TSRMLS_CC )) {
1286
1287
continue ;
1287
1288
}
1288
1289
} else {
1289
1290
/* Chop off the \0 from string lengths */
1290
- key_len -= 1 ;
1291
+ string_key_len -= 1 ;
1291
1292
}
1292
1293
1293
1294
if (flags & PHONGO_BSON_ADD_ID ) {
1294
- if (!strncmp (key , "_id" , sizeof ("_id" )- 1 )) {
1295
+ if (!strncmp (string_key , "_id" , sizeof ("_id" )- 1 )) {
1295
1296
flags &= ~PHONGO_BSON_ADD_ID ;
1296
1297
}
1297
1298
}
1298
- } else {
1299
- key_len = bson_uint32_to_string (index , (const char * * )& key , numbuf , sizeof (numbuf ));
1300
1299
}
1301
- phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID , key , key_len , * entry TSRMLS_CC );
1300
+
1301
+ /* Ensure we're working with a string key */
1302
+ if (hash_type == HASH_KEY_IS_LONG ) {
1303
+ spprintf (& string_key , 0 , "%ld" , num_key );
1304
+ string_key_len = strlen (string_key );
1305
+ }
1306
+
1307
+ phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID , string_key , string_key_len , * value TSRMLS_CC );
1308
+
1309
+ if (hash_type == HASH_KEY_IS_LONG ) {
1310
+ efree (string_key );
1311
+ }
1302
1312
}
1303
1313
#endif
1304
1314
0 commit comments