@@ -1231,6 +1231,7 @@ ZEND_FUNCTION(get_object_vars)
12311231 HashTable * properties ;
12321232 zend_string * key ;
12331233 zend_object * zobj ;
1234+ zend_ulong num_key ;
12341235
12351236 ZEND_PARSE_PARAMETERS_START (1 , 1 )
12361237 Z_PARAM_OBJECT (obj )
@@ -1257,33 +1258,44 @@ ZEND_FUNCTION(get_object_vars)
12571258 } else {
12581259 array_init_size (return_value , zend_hash_num_elements (properties ));
12591260
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 );
12871299 }
12881300 }
12891301 } ZEND_HASH_FOREACH_END ();
0 commit comments