@@ -1231,6 +1231,7 @@ ZEND_FUNCTION(get_object_vars)
1231
1231
HashTable * properties ;
1232
1232
zend_string * key ;
1233
1233
zend_object * zobj ;
1234
+ zend_ulong num_key ;
1234
1235
1235
1236
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1236
1237
Z_PARAM_OBJECT (obj )
@@ -1257,33 +1258,44 @@ ZEND_FUNCTION(get_object_vars)
1257
1258
} else {
1258
1259
array_init_size (return_value , zend_hash_num_elements (properties ));
1259
1260
1260
- ZEND_HASH_FOREACH_STR_KEY_VAL_IND (properties , key , value ) {
1261
- if (key ) {
1262
- if (zend_check_property_access (zobj , key ) == SUCCESS ) {
1263
- if (Z_ISREF_P (value ) && Z_REFCOUNT_P (value ) == 1 ) {
1264
- value = Z_REFVAL_P (value );
1265
- }
1266
- if (Z_REFCOUNTED_P (value )) {
1267
- Z_ADDREF_P (value );
1268
- }
1269
- if (ZSTR_VAL (key )[0 ] == 0 ) {
1270
- const char * prop_name , * class_name ;
1271
- size_t prop_len ;
1272
- zend_unmangle_property_name_ex (key , & class_name , & prop_name , & prop_len );
1273
- /* We assume here that a mangled property name is never
1274
- * numeric. This is probably a safe assumption, but
1275
- * theoretically someone might write an extension with
1276
- * private, numeric properties. Well, too bad.
1277
- */
1278
- zend_hash_str_add_new (Z_ARRVAL_P (return_value ), prop_name , prop_len , value );
1279
- } else {
1280
- zend_ulong num_key ;
1281
- if (ZEND_HANDLE_NUMERIC (key , num_key )) {
1282
- zend_hash_index_add_new (Z_ARRVAL_P (return_value ), num_key , value );
1283
- } else {
1284
- zend_hash_add_new (Z_ARRVAL_P (return_value ), key , value );
1285
- }
1286
- }
1261
+ ZEND_HASH_FOREACH_KEY_VAL (properties , num_key , key , value ) {
1262
+ zend_bool unmangle = 0 ;
1263
+ if (Z_TYPE_P (value ) == IS_INDIRECT ) {
1264
+ value = Z_INDIRECT_P (value );
1265
+ if (UNEXPECTED (Z_ISUNDEF_P (value ))) {
1266
+ continue ;
1267
+ }
1268
+
1269
+ ZEND_ASSERT (key );
1270
+ if (zend_check_property_access (zobj , key ) == FAILURE ) {
1271
+ continue ;
1272
+ }
1273
+ unmangle = 1 ;
1274
+ }
1275
+
1276
+ if (Z_ISREF_P (value ) && Z_REFCOUNT_P (value ) == 1 ) {
1277
+ value = Z_REFVAL_P (value );
1278
+ }
1279
+ Z_TRY_ADDREF_P (value );
1280
+
1281
+ if (UNEXPECTED (!key )) {
1282
+ /* This case is only possible due to loopholes, e.g. ArrayObject */
1283
+ zend_hash_index_add (Z_ARRVAL_P (return_value ), num_key , value );
1284
+ } else if (unmangle && ZSTR_VAL (key )[0 ] == 0 ) {
1285
+ const char * prop_name , * class_name ;
1286
+ size_t prop_len ;
1287
+ zend_unmangle_property_name_ex (key , & class_name , & prop_name , & prop_len );
1288
+ /* We assume here that a mangled property name is never
1289
+ * numeric. This is probably a safe assumption, but
1290
+ * theoretically someone might write an extension with
1291
+ * private, numeric properties. Well, too bad.
1292
+ */
1293
+ zend_hash_str_add_new (Z_ARRVAL_P (return_value ), prop_name , prop_len , value );
1294
+ } else {
1295
+ if (ZEND_HANDLE_NUMERIC (key , num_key )) {
1296
+ zend_hash_index_add (Z_ARRVAL_P (return_value ), num_key , value );
1297
+ } else {
1298
+ zend_hash_add_new (Z_ARRVAL_P (return_value ), key , value );
1287
1299
}
1288
1300
}
1289
1301
} ZEND_HASH_FOREACH_END ();
0 commit comments