@@ -1029,11 +1029,50 @@ static inline HashTable *get_ht_for_iap(zval *zv, bool separate) {
10291029 return zobj -> handlers -> get_properties (zobj );
10301030}
10311031
1032+ static zval * php_array_iter_seek_current (HashTable * array , bool forward_direction )
1033+ {
1034+ zval * entry ;
1035+
1036+ while (true) {
1037+ if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1038+ return NULL ;
1039+ }
1040+
1041+ ZVAL_DEINDIRECT (entry );
1042+
1043+ /* Possible with an uninitialized typed property */
1044+ if (UNEXPECTED (Z_TYPE_P (entry ) == IS_UNDEF )) {
1045+ zend_result result ;
1046+ if (forward_direction ) {
1047+ result = zend_hash_move_forward (array );
1048+ } else {
1049+ result = zend_hash_move_backwards (array );
1050+ }
1051+ if (result != SUCCESS ) {
1052+ return NULL ;
1053+ }
1054+ } else {
1055+ break ;
1056+ }
1057+ }
1058+
1059+ return entry ;
1060+ }
1061+
1062+ static void php_array_iter_return_current (zval * return_value , HashTable * array , bool forward_direction )
1063+ {
1064+ zval * entry = php_array_iter_seek_current (array , forward_direction );
1065+ if (EXPECTED (entry )) {
1066+ RETURN_COPY_DEREF (entry );
1067+ } else {
1068+ RETURN_FALSE ;
1069+ }
1070+ }
1071+
10321072/* {{{ Advances array argument's internal pointer to the last element and return it */
10331073PHP_FUNCTION (end )
10341074{
10351075 zval * array_zv ;
1036- zval * entry ;
10371076
10381077 ZEND_PARSE_PARAMETERS_START (1 , 1 )
10391078 Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1047,15 +1086,7 @@ PHP_FUNCTION(end)
10471086 zend_hash_internal_pointer_end (array );
10481087
10491088 if (USED_RET ()) {
1050- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1051- RETURN_FALSE ;
1052- }
1053-
1054- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1055- entry = Z_INDIRECT_P (entry );
1056- }
1057-
1058- RETURN_COPY_DEREF (entry );
1089+ php_array_iter_return_current (return_value , array , false);
10591090 }
10601091}
10611092/* }}} */
@@ -1064,7 +1095,6 @@ PHP_FUNCTION(end)
10641095PHP_FUNCTION (prev )
10651096{
10661097 zval * array_zv ;
1067- zval * entry ;
10681098
10691099 ZEND_PARSE_PARAMETERS_START (1 , 1 )
10701100 Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1078,15 +1108,7 @@ PHP_FUNCTION(prev)
10781108 zend_hash_move_backwards (array );
10791109
10801110 if (USED_RET ()) {
1081- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1082- RETURN_FALSE ;
1083- }
1084-
1085- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1086- entry = Z_INDIRECT_P (entry );
1087- }
1088-
1089- RETURN_COPY_DEREF (entry );
1111+ php_array_iter_return_current (return_value , array , false);
10901112 }
10911113}
10921114/* }}} */
@@ -1095,7 +1117,6 @@ PHP_FUNCTION(prev)
10951117PHP_FUNCTION (next )
10961118{
10971119 zval * array_zv ;
1098- zval * entry ;
10991120
11001121 ZEND_PARSE_PARAMETERS_START (1 , 1 )
11011122 Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1109,15 +1130,7 @@ PHP_FUNCTION(next)
11091130 zend_hash_move_forward (array );
11101131
11111132 if (USED_RET ()) {
1112- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1113- RETURN_FALSE ;
1114- }
1115-
1116- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1117- entry = Z_INDIRECT_P (entry );
1118- }
1119-
1120- RETURN_COPY_DEREF (entry );
1133+ php_array_iter_return_current (return_value , array , true);
11211134 }
11221135}
11231136/* }}} */
@@ -1126,7 +1139,6 @@ PHP_FUNCTION(next)
11261139PHP_FUNCTION (reset )
11271140{
11281141 zval * array_zv ;
1129- zval * entry ;
11301142
11311143 ZEND_PARSE_PARAMETERS_START (1 , 1 )
11321144 Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1140,15 +1152,7 @@ PHP_FUNCTION(reset)
11401152 zend_hash_internal_pointer_reset (array );
11411153
11421154 if (USED_RET ()) {
1143- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1144- RETURN_FALSE ;
1145- }
1146-
1147- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1148- entry = Z_INDIRECT_P (entry );
1149- }
1150-
1151- RETURN_COPY_DEREF (entry );
1155+ php_array_iter_return_current (return_value , array , true);
11521156 }
11531157}
11541158/* }}} */
@@ -1157,22 +1161,13 @@ PHP_FUNCTION(reset)
11571161PHP_FUNCTION (current )
11581162{
11591163 zval * array_zv ;
1160- zval * entry ;
11611164
11621165 ZEND_PARSE_PARAMETERS_START (1 , 1 )
11631166 Z_PARAM_ARRAY_OR_OBJECT (array_zv )
11641167 ZEND_PARSE_PARAMETERS_END ();
11651168
11661169 HashTable * array = get_ht_for_iap (array_zv , /* separate */ false);
1167- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1168- RETURN_FALSE ;
1169- }
1170-
1171- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1172- entry = Z_INDIRECT_P (entry );
1173- }
1174-
1175- RETURN_COPY_DEREF (entry );
1170+ php_array_iter_return_current (return_value , array , true);
11761171}
11771172/* }}} */
11781173
@@ -1186,7 +1181,10 @@ PHP_FUNCTION(key)
11861181 ZEND_PARSE_PARAMETERS_END ();
11871182
11881183 HashTable * array = get_ht_for_iap (array_zv , /* separate */ false);
1189- zend_hash_get_current_key_zval (array , return_value );
1184+ zval * entry = php_array_iter_seek_current (array , true);
1185+ if (EXPECTED (entry )) {
1186+ zend_hash_get_current_key_zval (array , return_value );
1187+ }
11901188}
11911189/* }}} */
11921190
0 commit comments