@@ -1024,11 +1024,50 @@ static inline HashTable *get_ht_for_iap(zval *zv, bool separate) {
1024
1024
return zobj -> handlers -> get_properties (zobj );
1025
1025
}
1026
1026
1027
+ static zval * php_array_iter_seek_current (HashTable * array , bool forward_direction )
1028
+ {
1029
+ zval * entry ;
1030
+
1031
+ while (true) {
1032
+ if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1033
+ return NULL ;
1034
+ }
1035
+
1036
+ ZVAL_DEINDIRECT (entry );
1037
+
1038
+ /* Possible with an uninitialized typed property */
1039
+ if (UNEXPECTED (Z_TYPE_P (entry ) == IS_UNDEF )) {
1040
+ zend_result result ;
1041
+ if (forward_direction ) {
1042
+ result = zend_hash_move_forward (array );
1043
+ } else {
1044
+ result = zend_hash_move_backwards (array );
1045
+ }
1046
+ if (result != SUCCESS ) {
1047
+ return NULL ;
1048
+ }
1049
+ } else {
1050
+ break ;
1051
+ }
1052
+ }
1053
+
1054
+ return entry ;
1055
+ }
1056
+
1057
+ static void php_array_iter_return_current (zval * return_value , HashTable * array , bool forward_direction )
1058
+ {
1059
+ zval * entry = php_array_iter_seek_current (array , forward_direction );
1060
+ if (EXPECTED (entry )) {
1061
+ RETURN_COPY_DEREF (entry );
1062
+ } else {
1063
+ RETURN_FALSE ;
1064
+ }
1065
+ }
1066
+
1027
1067
/* {{{ Advances array argument's internal pointer to the last element and return it */
1028
1068
PHP_FUNCTION (end )
1029
1069
{
1030
1070
zval * array_zv ;
1031
- zval * entry ;
1032
1071
1033
1072
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1034
1073
Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1042,15 +1081,7 @@ PHP_FUNCTION(end)
1042
1081
zend_hash_internal_pointer_end (array );
1043
1082
1044
1083
if (USED_RET ()) {
1045
- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1046
- RETURN_FALSE ;
1047
- }
1048
-
1049
- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1050
- entry = Z_INDIRECT_P (entry );
1051
- }
1052
-
1053
- RETURN_COPY_DEREF (entry );
1084
+ php_array_iter_return_current (return_value , array , false);
1054
1085
}
1055
1086
}
1056
1087
/* }}} */
@@ -1059,7 +1090,6 @@ PHP_FUNCTION(end)
1059
1090
PHP_FUNCTION (prev )
1060
1091
{
1061
1092
zval * array_zv ;
1062
- zval * entry ;
1063
1093
1064
1094
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1065
1095
Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1073,15 +1103,7 @@ PHP_FUNCTION(prev)
1073
1103
zend_hash_move_backwards (array );
1074
1104
1075
1105
if (USED_RET ()) {
1076
- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1077
- RETURN_FALSE ;
1078
- }
1079
-
1080
- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1081
- entry = Z_INDIRECT_P (entry );
1082
- }
1083
-
1084
- RETURN_COPY_DEREF (entry );
1106
+ php_array_iter_return_current (return_value , array , false);
1085
1107
}
1086
1108
}
1087
1109
/* }}} */
@@ -1090,7 +1112,6 @@ PHP_FUNCTION(prev)
1090
1112
PHP_FUNCTION (next )
1091
1113
{
1092
1114
zval * array_zv ;
1093
- zval * entry ;
1094
1115
1095
1116
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1096
1117
Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1104,15 +1125,7 @@ PHP_FUNCTION(next)
1104
1125
zend_hash_move_forward (array );
1105
1126
1106
1127
if (USED_RET ()) {
1107
- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1108
- RETURN_FALSE ;
1109
- }
1110
-
1111
- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1112
- entry = Z_INDIRECT_P (entry );
1113
- }
1114
-
1115
- RETURN_COPY_DEREF (entry );
1128
+ php_array_iter_return_current (return_value , array , true);
1116
1129
}
1117
1130
}
1118
1131
/* }}} */
@@ -1121,7 +1134,6 @@ PHP_FUNCTION(next)
1121
1134
PHP_FUNCTION (reset )
1122
1135
{
1123
1136
zval * array_zv ;
1124
- zval * entry ;
1125
1137
1126
1138
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1127
1139
Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1135,15 +1147,7 @@ PHP_FUNCTION(reset)
1135
1147
zend_hash_internal_pointer_reset (array );
1136
1148
1137
1149
if (USED_RET ()) {
1138
- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1139
- RETURN_FALSE ;
1140
- }
1141
-
1142
- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1143
- entry = Z_INDIRECT_P (entry );
1144
- }
1145
-
1146
- RETURN_COPY_DEREF (entry );
1150
+ php_array_iter_return_current (return_value , array , true);
1147
1151
}
1148
1152
}
1149
1153
/* }}} */
@@ -1152,22 +1156,13 @@ PHP_FUNCTION(reset)
1152
1156
PHP_FUNCTION (current )
1153
1157
{
1154
1158
zval * array_zv ;
1155
- zval * entry ;
1156
1159
1157
1160
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1158
1161
Z_PARAM_ARRAY_OR_OBJECT (array_zv )
1159
1162
ZEND_PARSE_PARAMETERS_END ();
1160
1163
1161
1164
HashTable * array = get_ht_for_iap (array_zv , /* separate */ false);
1162
- if ((entry = zend_hash_get_current_data (array )) == NULL ) {
1163
- RETURN_FALSE ;
1164
- }
1165
-
1166
- if (Z_TYPE_P (entry ) == IS_INDIRECT ) {
1167
- entry = Z_INDIRECT_P (entry );
1168
- }
1169
-
1170
- RETURN_COPY_DEREF (entry );
1165
+ php_array_iter_return_current (return_value , array , true);
1171
1166
}
1172
1167
/* }}} */
1173
1168
@@ -1181,7 +1176,10 @@ PHP_FUNCTION(key)
1181
1176
ZEND_PARSE_PARAMETERS_END ();
1182
1177
1183
1178
HashTable * array = get_ht_for_iap (array_zv , /* separate */ false);
1184
- zend_hash_get_current_key_zval (array , return_value );
1179
+ zval * entry = php_array_iter_seek_current (array , true);
1180
+ if (EXPECTED (entry )) {
1181
+ zend_hash_get_current_key_zval (array , return_value );
1182
+ }
1185
1183
}
1186
1184
/* }}} */
1187
1185
0 commit comments