mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-7.4'
This commit is contained in:
commit
772a158d7a
5 changed files with 94 additions and 51 deletions
18
Zend/tests/foreach_by_ref_repacking_insert.phpt
Normal file
18
Zend/tests/foreach_by_ref_repacking_insert.phpt
Normal file
|
@ -0,0 +1,18 @@
|
|||
--TEST--
|
||||
Perform a packed to hash insert when the iterator is at the end of the array
|
||||
--FILE--
|
||||
|
||||
<?php
|
||||
$a = [];
|
||||
$a[1] = 1;
|
||||
foreach ($a as $k => &$v) {
|
||||
var_dump($v);
|
||||
if ($k == 1) $a[4] = 4;
|
||||
if ($k == 4) $a[2] = 2;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(4)
|
||||
int(2)
|
|
@ -400,10 +400,8 @@ ZEND_API uint32_t zend_array_count(HashTable *ht)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline HashPosition _zend_hash_get_first_pos(const HashTable *ht)
|
||||
static zend_always_inline HashPosition _zend_hash_get_valid_pos(const HashTable *ht, HashPosition pos)
|
||||
{
|
||||
HashPosition pos = 0;
|
||||
|
||||
while (pos < ht->nNumUsed && Z_ISUNDEF(ht->arData[pos].val)) {
|
||||
pos++;
|
||||
}
|
||||
|
@ -412,12 +410,7 @@ static zend_always_inline HashPosition _zend_hash_get_first_pos(const HashTable
|
|||
|
||||
static zend_always_inline HashPosition _zend_hash_get_current_pos(const HashTable *ht)
|
||||
{
|
||||
HashPosition pos = ht->nInternalPointer;
|
||||
|
||||
if (pos == 0) {
|
||||
pos = _zend_hash_get_first_pos(ht);
|
||||
}
|
||||
return pos;
|
||||
return _zend_hash_get_valid_pos(ht, ht->nInternalPointer);
|
||||
}
|
||||
|
||||
ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos(const HashTable *ht)
|
||||
|
@ -1168,6 +1161,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
|
|||
p++;
|
||||
} while (++i < ht->nNumUsed);
|
||||
} else {
|
||||
uint32_t old_num_used = ht->nNumUsed;
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) {
|
||||
uint32_t j = i;
|
||||
|
@ -1224,6 +1218,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
|
|||
HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(i);
|
||||
p++;
|
||||
} while (++i < ht->nNumUsed);
|
||||
|
||||
/* Migrate pointer to one past the end of the array to the new one past the end, so that
|
||||
* newly inserted elements are picked up correctly. */
|
||||
if (UNEXPECTED(HT_HAS_ITERATORS(ht))) {
|
||||
_zend_hash_iterators_update(ht, old_num_used, ht->nNumUsed);
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -2241,7 +2241,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, H
|
|||
{
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
|
||||
*pos = _zend_hash_get_first_pos(ht);
|
||||
*pos = _zend_hash_get_valid_pos(ht, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2269,19 +2269,13 @@ ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, Has
|
|||
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
|
||||
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
*pos = idx;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
idx++;
|
||||
if (idx >= ht->nNumUsed) {
|
||||
|
@ -2324,17 +2318,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPositi
|
|||
/* This function should be made binary safe */
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return HASH_KEY_NON_EXISTENT;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
*str_index = p->key;
|
||||
|
@ -2349,20 +2338,14 @@ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zen
|
|||
|
||||
ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
ZVAL_NULL(key);
|
||||
} else {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
ZVAL_NULL(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
ZVAL_STR_COPY(key, p->key);
|
||||
|
@ -2374,17 +2357,12 @@ ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *h
|
|||
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return HASH_KEY_NON_EXISTENT;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
return HASH_KEY_IS_STRING;
|
||||
|
@ -2398,17 +2376,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, Hash
|
|||
|
||||
ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
return &p->val;
|
||||
} else {
|
||||
|
|
52
ext/spl/tests/bug77903.phpt
Normal file
52
ext/spl/tests/bug77903.phpt
Normal file
|
@ -0,0 +1,52 @@
|
|||
--TEST--
|
||||
Bug #77903: ArrayIterator stops iterating after offsetSet call
|
||||
--FILE--
|
||||
<?php
|
||||
$a = new ArrayIterator();
|
||||
$a->rewind();
|
||||
var_dump($a->valid()); // false
|
||||
var_dump($a->current()); // null
|
||||
$a->offsetSet(1,1);
|
||||
var_dump($a->valid()); // true
|
||||
var_dump($a->current()); // 1
|
||||
$a->next();
|
||||
var_dump($a->valid()); // false
|
||||
var_dump($a->current()); // null
|
||||
$a->offsetSet(4,4);
|
||||
var_dump($a->valid()); // true
|
||||
var_dump($a->current()); // 4
|
||||
$a->next();
|
||||
var_dump($a->valid()); // false
|
||||
var_dump($a->current()); // null
|
||||
$a->next();
|
||||
var_dump($a->valid()); // false
|
||||
var_dump($a->current()); // null
|
||||
$a->offsetSet(2,2);
|
||||
var_dump($a->valid()); // true
|
||||
var_dump($a->current()); // 2
|
||||
$a->next();
|
||||
var_dump($a->valid()); // false
|
||||
var_dump($a->current()); // null
|
||||
$a->next();
|
||||
var_dump($a->valid()); // false
|
||||
var_dump($a->current()); // null
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
NULL
|
||||
bool(true)
|
||||
int(1)
|
||||
bool(false)
|
||||
NULL
|
||||
bool(true)
|
||||
int(4)
|
||||
bool(false)
|
||||
NULL
|
||||
bool(false)
|
||||
NULL
|
||||
bool(true)
|
||||
int(2)
|
||||
bool(false)
|
||||
NULL
|
||||
bool(false)
|
||||
NULL
|
|
@ -1176,11 +1176,11 @@ mysqli.default_port = 3306
|
|||
; http://php.net/mysqli.default-socket
|
||||
mysqli.default_socket =
|
||||
|
||||
; Default host for mysql_connect() (doesn't apply in safe mode).
|
||||
; Default host for mysqli_connect() (doesn't apply in safe mode).
|
||||
; http://php.net/mysqli.default-host
|
||||
mysqli.default_host =
|
||||
|
||||
; Default user for mysql_connect() (doesn't apply in safe mode).
|
||||
; Default user for mysqli_connect() (doesn't apply in safe mode).
|
||||
; http://php.net/mysqli.default-user
|
||||
mysqli.default_user =
|
||||
|
||||
|
|
|
@ -1176,11 +1176,11 @@ mysqli.default_port = 3306
|
|||
; http://php.net/mysqli.default-socket
|
||||
mysqli.default_socket =
|
||||
|
||||
; Default host for mysql_connect() (doesn't apply in safe mode).
|
||||
; Default host for mysql_iconnect() (doesn't apply in safe mode).
|
||||
; http://php.net/mysqli.default-host
|
||||
mysqli.default_host =
|
||||
|
||||
; Default user for mysql_connect() (doesn't apply in safe mode).
|
||||
; Default user for mysql_iconnect() (doesn't apply in safe mode).
|
||||
; http://php.net/mysqli.default-user
|
||||
mysqli.default_user =
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue