Skip to content

Commit 165b07a

Browse files
committed
Change strategy again
1 parent 4542899 commit 165b07a

File tree

2 files changed

+46
-49
lines changed

2 files changed

+46
-49
lines changed

ext/standard/array.c

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,48 +1029,44 @@ static inline HashTable *get_ht_for_iap(zval *zv, bool separate) {
10291029
return zobj->handlers->get_properties(zobj);
10301030
}
10311031

1032-
enum php_array_iter_undef_strategy {
1033-
IA_MOVE_FORWARD,
1034-
IA_MOVE_BACKWARD,
1035-
IA_THROW,
1036-
};
1037-
1038-
static ZEND_COLD void php_array_iter_throw_undef_error(void)
1039-
{
1040-
zend_throw_error(NULL, "Internal iterator points to an uninitialized property");
1041-
}
1042-
1043-
static void php_array_iter_return_current(zval *return_value, HashTable *array, enum php_array_iter_undef_strategy undef_strategy)
1032+
static zval *php_array_iter_seek_current(HashTable *array, bool forward_direction)
10441033
{
10451034
zval *entry;
10461035

10471036
while (true) {
10481037
if ((entry = zend_hash_get_current_data(array)) == NULL) {
1049-
RETURN_FALSE;
1038+
return NULL;
10501039
}
10511040

10521041
ZVAL_DEINDIRECT(entry);
10531042

10541043
/* Possible with an uninitialized typed property */
10551044
if (UNEXPECTED(Z_TYPE_P(entry) == IS_UNDEF)) {
10561045
zend_result result;
1057-
if (undef_strategy == IA_MOVE_FORWARD) {
1046+
if (forward_direction) {
10581047
result = zend_hash_move_forward(array);
1059-
} else if (undef_strategy == IA_MOVE_BACKWARD) {
1060-
result = zend_hash_move_backwards(array);
10611048
} else {
1062-
php_array_iter_throw_undef_error();
1063-
return;
1049+
result = zend_hash_move_backwards(array);
10641050
}
10651051
if (result != SUCCESS) {
1066-
RETURN_FALSE;
1052+
return NULL;
10671053
}
10681054
} else {
10691055
break;
10701056
}
10711057
}
10721058

1073-
RETURN_COPY_DEREF(entry);
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+
}
10741070
}
10751071

10761072
/* {{{ Advances array argument's internal pointer to the last element and return it */
@@ -1090,7 +1086,7 @@ PHP_FUNCTION(end)
10901086
zend_hash_internal_pointer_end(array);
10911087

10921088
if (USED_RET()) {
1093-
php_array_iter_return_current(return_value, array, IA_MOVE_BACKWARD);
1089+
php_array_iter_return_current(return_value, array, false);
10941090
}
10951091
}
10961092
/* }}} */
@@ -1112,7 +1108,7 @@ PHP_FUNCTION(prev)
11121108
zend_hash_move_backwards(array);
11131109

11141110
if (USED_RET()) {
1115-
php_array_iter_return_current(return_value, array, IA_MOVE_BACKWARD);
1111+
php_array_iter_return_current(return_value, array, false);
11161112
}
11171113
}
11181114
/* }}} */
@@ -1134,7 +1130,7 @@ PHP_FUNCTION(next)
11341130
zend_hash_move_forward(array);
11351131

11361132
if (USED_RET()) {
1137-
php_array_iter_return_current(return_value, array, IA_MOVE_FORWARD);
1133+
php_array_iter_return_current(return_value, array, true);
11381134
}
11391135
}
11401136
/* }}} */
@@ -1156,7 +1152,7 @@ PHP_FUNCTION(reset)
11561152
zend_hash_internal_pointer_reset(array);
11571153

11581154
if (USED_RET()) {
1159-
php_array_iter_return_current(return_value, array, IA_MOVE_FORWARD);
1155+
php_array_iter_return_current(return_value, array, true);
11601156
}
11611157
}
11621158
/* }}} */
@@ -1171,7 +1167,7 @@ PHP_FUNCTION(current)
11711167
ZEND_PARSE_PARAMETERS_END();
11721168

11731169
HashTable *array = get_ht_for_iap(array_zv, /* separate */ false);
1174-
php_array_iter_return_current(return_value, array, IA_THROW);
1170+
php_array_iter_return_current(return_value, array, true);
11751171
}
11761172
/* }}} */
11771173

@@ -1185,17 +1181,10 @@ PHP_FUNCTION(key)
11851181
ZEND_PARSE_PARAMETERS_END();
11861182

11871183
HashTable *array = get_ht_for_iap(array_zv, /* separate */ false);
1188-
if (Z_TYPE_P(array_zv) == IS_OBJECT) {
1189-
zval *data = zend_hash_get_current_data(array);
1190-
if (data) {
1191-
ZVAL_DEINDIRECT(data);
1192-
if (Z_ISUNDEF_P(data)) {
1193-
php_array_iter_throw_undef_error();
1194-
RETURN_THROWS();
1195-
}
1196-
}
1184+
zval *entry = php_array_iter_seek_current(array, true);
1185+
if (EXPECTED(entry)) {
1186+
zend_hash_get_current_key_zval(array, return_value);
11971187
}
1198-
zend_hash_get_current_key_zval(array, return_value);
11991188
}
12001189
/* }}} */
12011190

ext/standard/tests/array/gh16905.phpt

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,19 @@ var_dump(next($x));
2828
var_dump(end($x));
2929
var_dump(prev($x));
3030

31-
var_dump(value: key($x));
31+
var_dump(key($x));
32+
var_dump(current($x));
3233

3334
$x = new TestAllUndef;
34-
try {
35-
var_dump(current($x));
36-
} catch (Error $e) {
37-
echo $e->getMessage(), "\n";
38-
}
39-
try {
40-
var_dump(key($x));
41-
} catch (Error $e) {
42-
echo $e->getMessage(), "\n";
43-
}
35+
var_dump(key($x));
36+
var_dump(current($x));
37+
4438
$x->a = 1;
39+
var_dump(key($x));
4540
var_dump(current($x));
41+
reset($x);
4642
var_dump(key($x));
43+
var_dump(current($x));
4744

4845
?>
4946
--EXPECTF--
@@ -72,13 +69,24 @@ Deprecated: key(): Calling key() on an object is deprecated in %s on line %d
7269
string(1) "b"
7370

7471
Deprecated: current(): Calling current() on an object is deprecated in %s on line %d
75-
Internal iterator points to an uninitialized property
72+
int(1)
73+
74+
Deprecated: key(): Calling key() on an object is deprecated in %s on line %d
75+
NULL
76+
77+
Deprecated: current(): Calling current() on an object is deprecated in %s on line %d
78+
bool(false)
7679

7780
Deprecated: key(): Calling key() on an object is deprecated in %s on line %d
78-
Internal iterator points to an uninitialized property
81+
NULL
7982

8083
Deprecated: current(): Calling current() on an object is deprecated in %s on line %d
81-
int(1)
84+
bool(false)
85+
86+
Deprecated: reset(): Calling reset() on an object is deprecated in %s on line %d
8287

8388
Deprecated: key(): Calling key() on an object is deprecated in %s on line %d
8489
string(1) "a"
90+
91+
Deprecated: current(): Calling current() on an object is deprecated in %s on line %d
92+
int(1)

0 commit comments

Comments
 (0)