@@ -1029,11 +1029,50 @@ static inline HashTable *get_ht_for_iap(zval *zv, bool separate) {
1029
1029
return zobj -> handlers -> get_properties (zobj );
1030
1030
}
1031
1031
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
+
1032
1072
/* {{{ Advances array argument's internal pointer to the last element and return it */
1033
1073
PHP_FUNCTION (end )
1034
1074
{
1035
1075
zval * array_zv ;
1036
- zval * entry ;
1037
1076
1038
1077
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1039
1078
Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1047,15 +1086,7 @@ PHP_FUNCTION(end)
1047
1086
zend_hash_internal_pointer_end (array );
1048
1087
1049
1088
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);
1059
1090
}
1060
1091
}
1061
1092
/* }}} */
@@ -1064,7 +1095,6 @@ PHP_FUNCTION(end)
1064
1095
PHP_FUNCTION (prev )
1065
1096
{
1066
1097
zval * array_zv ;
1067
- zval * entry ;
1068
1098
1069
1099
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1070
1100
Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1078,15 +1108,7 @@ PHP_FUNCTION(prev)
1078
1108
zend_hash_move_backwards (array );
1079
1109
1080
1110
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);
1090
1112
}
1091
1113
}
1092
1114
/* }}} */
@@ -1095,7 +1117,6 @@ PHP_FUNCTION(prev)
1095
1117
PHP_FUNCTION (next )
1096
1118
{
1097
1119
zval * array_zv ;
1098
- zval * entry ;
1099
1120
1100
1121
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1101
1122
Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1109,15 +1130,7 @@ PHP_FUNCTION(next)
1109
1130
zend_hash_move_forward (array );
1110
1131
1111
1132
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);
1121
1134
}
1122
1135
}
1123
1136
/* }}} */
@@ -1126,7 +1139,6 @@ PHP_FUNCTION(next)
1126
1139
PHP_FUNCTION (reset )
1127
1140
{
1128
1141
zval * array_zv ;
1129
- zval * entry ;
1130
1142
1131
1143
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1132
1144
Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1140,15 +1152,7 @@ PHP_FUNCTION(reset)
1140
1152
zend_hash_internal_pointer_reset (array );
1141
1153
1142
1154
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);
1152
1156
}
1153
1157
}
1154
1158
/* }}} */
@@ -1157,22 +1161,13 @@ PHP_FUNCTION(reset)
1157
1161
PHP_FUNCTION (current )
1158
1162
{
1159
1163
zval * array_zv ;
1160
- zval * entry ;
1161
1164
1162
1165
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1163
1166
Z_PARAM_ARRAY_OR_OBJECT (array_zv )
1164
1167
ZEND_PARSE_PARAMETERS_END ();
1165
1168
1166
1169
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);
1176
1171
}
1177
1172
/* }}} */
1178
1173
@@ -1186,7 +1181,10 @@ PHP_FUNCTION(key)
1186
1181
ZEND_PARSE_PARAMETERS_END ();
1187
1182
1188
1183
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
+ }
1190
1188
}
1191
1189
/* }}} */
1192
1190
0 commit comments