@@ -1024,11 +1024,50 @@ static inline HashTable *get_ht_for_iap(zval *zv, bool separate) {
10241024 return zobj -> handlers -> get_properties (zobj );
10251025}
10261026
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+
10271067/* {{{ Advances array argument's internal pointer to the last element and return it */
10281068PHP_FUNCTION (end )
10291069{
10301070 zval * array_zv ;
1031- zval * entry ;
10321071
10331072 ZEND_PARSE_PARAMETERS_START (1 , 1 )
10341073 Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1042,15 +1081,7 @@ PHP_FUNCTION(end)
10421081 zend_hash_internal_pointer_end (array );
10431082
10441083 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);
10541085 }
10551086}
10561087/* }}} */
@@ -1059,7 +1090,6 @@ PHP_FUNCTION(end)
10591090PHP_FUNCTION (prev )
10601091{
10611092 zval * array_zv ;
1062- zval * entry ;
10631093
10641094 ZEND_PARSE_PARAMETERS_START (1 , 1 )
10651095 Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1073,15 +1103,7 @@ PHP_FUNCTION(prev)
10731103 zend_hash_move_backwards (array );
10741104
10751105 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);
10851107 }
10861108}
10871109/* }}} */
@@ -1090,7 +1112,6 @@ PHP_FUNCTION(prev)
10901112PHP_FUNCTION (next )
10911113{
10921114 zval * array_zv ;
1093- zval * entry ;
10941115
10951116 ZEND_PARSE_PARAMETERS_START (1 , 1 )
10961117 Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1104,15 +1125,7 @@ PHP_FUNCTION(next)
11041125 zend_hash_move_forward (array );
11051126
11061127 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);
11161129 }
11171130}
11181131/* }}} */
@@ -1121,7 +1134,6 @@ PHP_FUNCTION(next)
11211134PHP_FUNCTION (reset )
11221135{
11231136 zval * array_zv ;
1124- zval * entry ;
11251137
11261138 ZEND_PARSE_PARAMETERS_START (1 , 1 )
11271139 Z_PARAM_ARRAY_OR_OBJECT_EX (array_zv , 0 , 1 )
@@ -1135,15 +1147,7 @@ PHP_FUNCTION(reset)
11351147 zend_hash_internal_pointer_reset (array );
11361148
11371149 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);
11471151 }
11481152}
11491153/* }}} */
@@ -1152,22 +1156,13 @@ PHP_FUNCTION(reset)
11521156PHP_FUNCTION (current )
11531157{
11541158 zval * array_zv ;
1155- zval * entry ;
11561159
11571160 ZEND_PARSE_PARAMETERS_START (1 , 1 )
11581161 Z_PARAM_ARRAY_OR_OBJECT (array_zv )
11591162 ZEND_PARSE_PARAMETERS_END ();
11601163
11611164 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);
11711166}
11721167/* }}} */
11731168
@@ -1181,7 +1176,10 @@ PHP_FUNCTION(key)
11811176 ZEND_PARSE_PARAMETERS_END ();
11821177
11831178 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+ }
11851183}
11861184/* }}} */
11871185
0 commit comments