@@ -1206,99 +1206,109 @@ PHONGO_API void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, b
12061206
12071207#if PHP_VERSION_ID >= 70000
12081208 {
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+ }
12321220
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 ;
12371223
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 )) {
12381227 if (member ) {
12391228 zend_string_release (member );
12401229 }
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 ;
12461237 }
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 );
12481247 }
12491248 } 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 );
12551255 }
1256+
1257+ zend_string_release (string_key );
12561258 } ZEND_HASH_FOREACH_END ();
12571259 }
12581260#else
12591261 zend_hash_internal_pointer_reset_ex (ht_data , & pos );
12601262 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 ;
12671268
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 );
12691270
12701271 if (hash_type == HASH_KEY_NON_EXISTENT ) {
12711272 break ;
12721273 }
12731274
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 ) {
12751276 break ;
12761277 }
12771278
12781279 if (hash_type == HASH_KEY_IS_STRING ) {
12791280 if (ht_data_from_properties ) {
12801281 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 );
12831284
12841285 /* 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 )) {
12861287 continue ;
12871288 }
12881289 } else {
12891290 /* Chop off the \0 from string lengths */
1290- key_len -= 1 ;
1291+ string_key_len -= 1 ;
12911292 }
12921293
12931294 if (flags & PHONGO_BSON_ADD_ID ) {
1294- if (!strncmp (key , "_id" , sizeof ("_id" )- 1 )) {
1295+ if (!strncmp (string_key , "_id" , sizeof ("_id" )- 1 )) {
12951296 flags &= ~PHONGO_BSON_ADD_ID ;
12961297 }
12971298 }
1298- } else {
1299- key_len = bson_uint32_to_string (index , (const char * * )& key , numbuf , sizeof (numbuf ));
13001299 }
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+ }
13021312 }
13031313#endif
13041314
0 commit comments