Skip to content

Commit 69fa652

Browse files
committed
Merge remote-tracking branch 'origin/master' into native-tls
* origin/master: Fix allocator for 64bit zend_long with 32bit long Use intptr_t for zend_intptr_t typedef Fix format strings in zend_alloc Drop zend_long64 in favor of int64_t Removed deprecated fields NEWS cleanup NEWS removing the NEWS entry as we had to revert this fix for now Revert "Merge branch 'PHP-5.5' into PHP-5.6" Revert "fix TS build" Revert "Merge branch 'PHP-5.4' into PHP-5.5" Revert "Bug #67965: Fix blocking behavior in non-blocking crypto streams" Revert "Bug #41631: Fix regression from first attempt (6569db8)" NEWS Fixed Bug #65171 imagescale() fails Fixed bug #68234 Fixed bug #68215 (Behavior of foreach has changed) Revert "Bug #41631: Observe socket read timeouts in SSL streams" PHP-5.6.3 is next update NEWS, 5.6.2 will be a security-only release
2 parents 7f1107d + 53a8584 commit 69fa652

File tree

13 files changed

+198
-147
lines changed

13 files changed

+198
-147
lines changed

Zend/tests/bug68215.phpt

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
--TEST--
2+
Bug #68215 (Behavior of foreach has changed)
3+
--FILE--
4+
<?php
5+
$arr = array(
6+
'a' => array(
7+
'a' => 'apple',
8+
'b' => 'banana',
9+
'c' => 'cranberry',
10+
'd' => 'mango',
11+
'e' => 'pineapple'
12+
),
13+
'b' => array(
14+
'a' => 'apple',
15+
'b' => 'banana',
16+
'c' => 'cranberry',
17+
'd' => 'mango',
18+
'e' => 'pineapple'
19+
),
20+
'c' => 'cranberry',
21+
'd' => 'mango',
22+
'e' => 'pineapple'
23+
);
24+
25+
function test(&$child, $entry)
26+
{
27+
$i = 1;
28+
29+
foreach ($child AS $key => $fruit)
30+
{
31+
if (!is_numeric($key))
32+
{
33+
$child[$i] = $fruit;
34+
unset($child[$key]);
35+
$i++;
36+
}
37+
}
38+
}
39+
40+
$i = 1;
41+
42+
foreach ($arr AS $key => $fruit)
43+
{
44+
$arr[$i] = $fruit;
45+
46+
if (is_array($fruit))
47+
{
48+
test($arr[$i], $fruit);
49+
}
50+
51+
unset($arr[$key]);
52+
$i++;
53+
}
54+
55+
var_dump($arr);
56+
?>
57+
--EXPECT--
58+
array(5) {
59+
[1]=>
60+
array(5) {
61+
[1]=>
62+
string(5) "apple"
63+
[2]=>
64+
string(6) "banana"
65+
[3]=>
66+
string(9) "cranberry"
67+
[4]=>
68+
string(5) "mango"
69+
[5]=>
70+
string(9) "pineapple"
71+
}
72+
[2]=>
73+
array(5) {
74+
[1]=>
75+
string(5) "apple"
76+
[2]=>
77+
string(6) "banana"
78+
[3]=>
79+
string(9) "cranberry"
80+
[4]=>
81+
string(5) "mango"
82+
[5]=>
83+
string(9) "pineapple"
84+
}
85+
[3]=>
86+
string(9) "cranberry"
87+
[4]=>
88+
string(5) "mango"
89+
[5]=>
90+
string(9) "pineapple"
91+
}

Zend/zend_alloc.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,11 @@ static void zend_mm_munmap(void *addr, size_t size)
482482
static zend_always_inline int zend_mm_bitset_nts(zend_mm_bitset bitset)
483483
{
484484
#if defined(__GNUC__)
485+
# if SIZEOF_ZEND_LONG == SIZEOF_LONG
485486
return __builtin_ctzl(~bitset);
487+
# else
488+
return __builtin_ctzll(~bitset);
489+
# endif
486490
#elif defined(_WIN32)
487491
unsigned long index;
488492

@@ -519,7 +523,11 @@ static zend_always_inline int zend_mm_bitset_nts(zend_mm_bitset bitset)
519523
static zend_always_inline int zend_mm_bitset_ntz(zend_mm_bitset bitset)
520524
{
521525
#if defined(__GNUC__)
526+
# if SIZEOF_ZEND_LONG == SIZEOF_LONG
522527
return __builtin_ctzl(bitset);
528+
# else
529+
return __builtin_ctzll(bitset);
530+
# endif
523531
#elif defined(_WIN32)
524532
unsigned long index;
525533

@@ -962,9 +970,9 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, int pages_count ZEND_FILE_L
962970
if (heap->real_size + ZEND_MM_CHUNK_SIZE > heap->limit) {
963971
if (heap->overflow == 0) {
964972
#if ZEND_DEBUG
965-
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted at %s:%d (tried to allocate " ZEND_ULONG_FMT " bytes)", heap->limit, __zend_filename, __zend_lineno, size);
973+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
966974
#else
967-
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted (tried to allocate " ZEND_ULONG_FMT " bytes)", heap->limit, ZEND_MM_PAGE_SIZE * pages_count);
975+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, ZEND_MM_PAGE_SIZE * pages_count);
968976
#endif
969977
return NULL;
970978
}
@@ -976,9 +984,9 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, int pages_count ZEND_FILE_L
976984
#if !ZEND_MM_LIMIT
977985
zend_mm_safe_error(heap, "Out of memory");
978986
#elif ZEND_DEBUG
979-
zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
987+
zend_mm_safe_error(heap, "Out of memory (allocated %zu) at %s:%d (tried to allocate %zu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
980988
#else
981-
zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %lu bytes)", heap->real_size, ZEND_MM_PAGE_SIZE * pages_count);
989+
zend_mm_safe_error(heap, "Out of memory (allocated %zu) (tried to allocate %zu bytes)", heap->real_size, ZEND_MM_PAGE_SIZE * pages_count);
982990
#endif
983991
return NULL;
984992
}
@@ -1415,9 +1423,9 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size ZEN
14151423
if (heap->real_size + (new_size - old_size) > heap->limit) {
14161424
if (heap->overflow == 0) {
14171425
#if ZEND_DEBUG
1418-
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted at %s:%d (tried to allocate " ZEND_ULONG_FMT " bytes)", heap->limit, __zend_filename, __zend_lineno, size);
1426+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
14191427
#else
1420-
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted (tried to allocate " ZEND_ULONG_FMT " bytes)", heap->limit, size);
1428+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, size);
14211429
#endif
14221430
return NULL;
14231431
}
@@ -1641,9 +1649,9 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
16411649
if (heap->real_size + new_size > heap->limit) {
16421650
if (heap->overflow == 0) {
16431651
#if ZEND_DEBUG
1644-
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted at %s:%d (tried to allocate %lu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
1652+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
16451653
#else
1646-
zend_mm_safe_error(heap, "Allowed memory size of " ZEND_ULONG_FMT " bytes exhausted (tried to allocate %lu bytes)", heap->limit, size);
1654+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, size);
16471655
#endif
16481656
return NULL;
16491657
}
@@ -1655,9 +1663,9 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
16551663
#if !ZEND_MM_LIMIT
16561664
zend_mm_safe_error(heap, "Out of memory");
16571665
#elif ZEND_DEBUG
1658-
zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
1666+
zend_mm_safe_error(heap, "Out of memory (allocated %zu) at %s:%d (tried to allocate %zu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
16591667
#else
1660-
zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %lu bytes)", heap->real_size, size);
1668+
zend_mm_safe_error(heap, "Out of memory (allocated %zu) (tried to allocate %zu bytes)", heap->real_size, size);
16611669
#endif
16621670
return NULL;
16631671
}

Zend/zend_compile.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,9 @@ typedef union _znode_op {
5959
uint32_t constant;
6060
uint32_t var;
6161
uint32_t num;
62-
zend_ulong hash;
6362
uint32_t opline_num; /* Needs to be signed */
6463
zend_op *jmp_addr;
6564
zval *zv;
66-
void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */
6765
} znode_op;
6866

6967
typedef struct _znode { /* used only during compilation */

Zend/zend_hash.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *p
170170
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
171171

172172
typedef struct _HashPointer {
173-
HashPosition pos;
174-
HashTable *ht;
175-
zend_ulong h;
173+
HashPosition pos;
174+
HashTable *ht;
175+
zend_ulong h;
176+
zend_string *key;
176177
} HashPointer;
177178

178179
#define zend_hash_has_more_elements(ht) \

Zend/zend_multiply.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@
8484
} \
8585
} while (0)
8686

87-
#elif SIZEOF_ZEND_LONG == 4 && defined(HAVE_ZEND_LONG64)
87+
#elif SIZEOF_ZEND_LONG == 4
8888

8989
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
90-
zend_long64 __result = (zend_long64) (a) * (zend_long64) (b); \
90+
int64_t __result = (int64_t) (a) * (int64_t) (b); \
9191
if (__result > ZEND_LONG_MAX || __result < ZEND_LONG_MIN) { \
9292
(dval) = (double) __result; \
9393
(usedval) = 1; \
@@ -117,7 +117,7 @@
117117
static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, int *overflow)
118118
{
119119
size_t res = nmemb;
120-
zend_ulong m_overflow = 0;
120+
size_t m_overflow = 0;
121121

122122
__asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1"
123123
: "=&a"(res), "=&d" (m_overflow)
@@ -206,13 +206,13 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si
206206
return res;
207207
}
208208

209-
#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
209+
#elif SIZEOF_SIZE_T == 4
210210

211211
static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, int *overflow)
212212
{
213-
zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
213+
uint64_t res = (uint64_t) nmemb * (uint64_t) size + (uint64_t) offset;
214214

215-
if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
215+
if (UNEXPECTED(res > UINT64_C(0xFFFFFFFF))) {
216216
*overflow = 1;
217217
return 0;
218218
}

Zend/zend_types.h

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,28 +64,8 @@ typedef enum {
6464
# endif
6565
#endif
6666

67-
#define HAVE_ZEND_LONG64
68-
#ifdef ZEND_WIN32
69-
typedef __int64 zend_long64;
70-
typedef unsigned __int64 zend_ulong64;
71-
#elif SIZEOF_LONG_LONG_INT == 8
72-
typedef long long int zend_long64;
73-
typedef unsigned long long int zend_ulong64;
74-
#elif SIZEOF_LONG_LONG == 8
75-
typedef long long zend_long64;
76-
typedef unsigned long long zend_ulong64;
77-
#else
78-
# undef HAVE_ZEND_LONG64
79-
#endif
80-
81-
/* XXX this won't work on X32 platform */
82-
#ifdef ZEND_ENABLE_ZVAL_LONG64
83-
typedef int64_t zend_intptr_t;
84-
typedef uint64_t zend_uintptr_t;
85-
#else
86-
typedef int32_t zend_intptr_t;
87-
typedef uint32_t zend_uintptr_t;
88-
#endif
67+
typedef intptr_t zend_intptr_t;
68+
typedef uintptr_t zend_uintptr_t;
8969

9070
typedef struct _zend_object_handlers zend_object_handlers;
9171
typedef struct _zend_class_entry zend_class_entry;

Zend/zend_vm_def.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4576,6 +4576,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
45764576
ptr->pos = pos;
45774577
ptr->ht = fe_ht;
45784578
ptr->h = fe_ht->arData[pos].h;
4579+
ptr->key = fe_ht->arData[pos].key;
45794580
is_empty = 0;
45804581
} else {
45814582
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
@@ -4630,8 +4631,11 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
46304631
pos = ptr->h;
46314632
} else {
46324633
pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask];
4633-
while (pos != INVALID_IDX) {
4634-
if (fe_ht->arData[pos].h == ptr->h && pos == ptr->pos) {
4634+
while (1) {
4635+
if (pos == INVALID_IDX) {
4636+
pos = fe_ht->nInternalPointer;
4637+
break;
4638+
} else if (fe_ht->arData[pos].h == ptr->h && fe_ht->arData[pos].key == ptr->key) {
46354639
break;
46364640
}
46374641
pos = Z_NEXT(fe_ht->arData[pos].val);
@@ -4684,6 +4688,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
46844688
Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF));
46854689
fe_ht->nInternalPointer = ptr->pos = pos;
46864690
ptr->h = fe_ht->arData[pos].h;
4691+
ptr->key = fe_ht->arData[pos].key;
46874692
ZEND_VM_INC_OPCODE();
46884693
ZEND_VM_NEXT_OPCODE();
46894694
} else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) {
@@ -4707,8 +4712,11 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
47074712
pos = ptr->h;
47084713
} else {
47094714
pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask];
4710-
while (pos != INVALID_IDX) {
4711-
if (fe_ht->arData[pos].h == ptr->h && pos == ptr->pos) {
4715+
while (1) {
4716+
if (pos == INVALID_IDX) {
4717+
pos = fe_ht->nInternalPointer;
4718+
break;
4719+
} else if (fe_ht->arData[pos].h == ptr->h && fe_ht->arData[pos].key == ptr->key) {
47124720
break;
47134721
}
47144722
pos = Z_NEXT(fe_ht->arData[pos].val);
@@ -4777,6 +4785,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
47774785
zend_check_property_access(zobj, p->key TSRMLS_CC) == FAILURE));
47784786
fe_ht->nInternalPointer = ptr->pos = pos;
47794787
ptr->h = fe_ht->arData[pos].h;
4788+
ptr->key = fe_ht->arData[pos].key;
47804789
ZEND_VM_INC_OPCODE();
47814790
ZEND_VM_NEXT_OPCODE();
47824791
} else {

Zend/zend_vm_execute.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3222,6 +3222,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
32223222
ptr->pos = pos;
32233223
ptr->ht = fe_ht;
32243224
ptr->h = fe_ht->arData[pos].h;
3225+
ptr->key = fe_ht->arData[pos].key;
32253226
is_empty = 0;
32263227
} else {
32273228
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
@@ -10032,6 +10033,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
1003210033
ptr->pos = pos;
1003310034
ptr->ht = fe_ht;
1003410035
ptr->h = fe_ht->arData[pos].h;
10036+
ptr->key = fe_ht->arData[pos].key;
1003510037
is_empty = 0;
1003610038
} else {
1003710039
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
@@ -16747,6 +16749,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
1674716749
ptr->pos = pos;
1674816750
ptr->ht = fe_ht;
1674916751
ptr->h = fe_ht->arData[pos].h;
16752+
ptr->key = fe_ht->arData[pos].key;
1675016753
is_empty = 0;
1675116754
} else {
1675216755
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
@@ -16801,8 +16804,11 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
1680116804
pos = ptr->h;
1680216805
} else {
1680316806
pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask];
16804-
while (pos != INVALID_IDX) {
16805-
if (fe_ht->arData[pos].h == ptr->h && pos == ptr->pos) {
16807+
while (1) {
16808+
if (pos == INVALID_IDX) {
16809+
pos = fe_ht->nInternalPointer;
16810+
break;
16811+
} else if (fe_ht->arData[pos].h == ptr->h && fe_ht->arData[pos].key == ptr->key) {
1680616812
break;
1680716813
}
1680816814
pos = Z_NEXT(fe_ht->arData[pos].val);
@@ -16855,6 +16861,7 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
1685516861
Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF));
1685616862
fe_ht->nInternalPointer = ptr->pos = pos;
1685716863
ptr->h = fe_ht->arData[pos].h;
16864+
ptr->key = fe_ht->arData[pos].key;
1685816865
ZEND_VM_INC_OPCODE();
1685916866
ZEND_VM_NEXT_OPCODE();
1686016867
} else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) {
@@ -16878,8 +16885,11 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
1687816885
pos = ptr->h;
1687916886
} else {
1688016887
pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask];
16881-
while (pos != INVALID_IDX) {
16882-
if (fe_ht->arData[pos].h == ptr->h && pos == ptr->pos) {
16888+
while (1) {
16889+
if (pos == INVALID_IDX) {
16890+
pos = fe_ht->nInternalPointer;
16891+
break;
16892+
} else if (fe_ht->arData[pos].h == ptr->h && fe_ht->arData[pos].key == ptr->key) {
1688316893
break;
1688416894
}
1688516895
pos = Z_NEXT(fe_ht->arData[pos].val);
@@ -16948,6 +16958,7 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
1694816958
zend_check_property_access(zobj, p->key TSRMLS_CC) == FAILURE));
1694916959
fe_ht->nInternalPointer = ptr->pos = pos;
1695016960
ptr->h = fe_ht->arData[pos].h;
16961+
ptr->key = fe_ht->arData[pos].key;
1695116962
ZEND_VM_INC_OPCODE();
1695216963
ZEND_VM_NEXT_OPCODE();
1695316964
} else {
@@ -34388,6 +34399,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
3438834399
ptr->pos = pos;
3438934400
ptr->ht = fe_ht;
3439034401
ptr->h = fe_ht->arData[pos].h;
34402+
ptr->key = fe_ht->arData[pos].key;
3439134403
is_empty = 0;
3439234404
} else {
3439334405
zend_error(E_WARNING, "Invalid argument supplied for foreach()");

0 commit comments

Comments
 (0)