Skip to content

Commit 6ac9e10

Browse files
committed
Merge remote-tracking branch 'origin/str_size_and_int64_56_backport' into str_size_and_int64
* origin/str_size_and_int64_56_backport: (132 commits) force atoll macro usage on windows Enable $ replacement in exif, ldap, pdo_pgsql and tidy See bug #67635 NEWS NEWS improve previous, add message during configure Fixed bug #67635 php links to systemd libraries without using pkg-config Improve fix for #66608 Fixed segfault with empty break New added opcodes don't need to be resloved Update NEWS Update NEWS Update NEWS Fixed bug #66827 Session raises E_NOTICE when session name variable is array implemented copy libs of core exts in phpize mode fix copy the ext dll into the prefix path in phpize mode fix default prefix in phpize mode fix file with zero size usage in phpize mode Update NEWS Fixed bug #66608 (Incorrect behavior with nested "finally" blocks) ... Conflicts: main/php_content_types.c
2 parents e98d429 + 6696cbc commit 6ac9e10

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1047
-196
lines changed

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ sapi/nsapi/nsapi.c ident
2222
sapi/continuity/capi.c ident
2323
Zend/RFCs/002.txt ident
2424
Zend/RFCs/003.txt ident
25+
ext/exif/exif.c ident
26+
ext/ldap/ldap.c ident
27+
ext/pdo_pgsql/pdo_pgsql.c ident
28+
ext/tidy/tidy.c ident
2529
NEWS merge=NEWS
2630
UPGRADING merge=NEWS
2731
UPGRADING.INTERNALS merge=NEWS

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ notifications:
88
email:
99
on_failure: change
1010

11+
cache:
12+
- apt
13+
1114
env:
1215
global:
1316
- MYSQL_TEST_HOST=127.0.0.1
@@ -21,6 +24,12 @@ env:
2124
- ENABLE_MAINTAINER_ZTS=0 ENABLE_DEBUG=0
2225
- ENABLE_MAINTAINER_ZTS=1 ENABLE_DEBUG=1
2326

27+
before_install:
28+
- sudo apt-get update -qq
29+
- sudo apt-get install -y libenchant-dev libaspell-dev libpspell-dev librecode-dev
30+
- sudo cp ./travis/de /var/lib/locales/supported.d/de
31+
- sudo dpkg-reconfigure locales
32+
2433
before_script:
2534
# Compile PHP
2635
- ./travis/compile.sh

Zend/tests/bug66608.phpt

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
--TEST--
2+
Bug #66608 (Incorrect behavior with nested "finally" blocks)
3+
--FILE--
4+
<?php
5+
function bar() {
6+
try {
7+
echo "1\n";
8+
try {
9+
} finally {
10+
try {
11+
} finally {
12+
}
13+
echo "2\n";
14+
}
15+
} finally {
16+
try {
17+
throw new Exception ("");
18+
} catch (Exception $ab) {
19+
echo "3\n";
20+
} finally {
21+
try {
22+
} finally {
23+
echo "4\n";
24+
try {
25+
} finally {
26+
}
27+
echo "5\n";
28+
}
29+
}
30+
echo "6\n";
31+
try {
32+
} finally {
33+
while (1) {
34+
try {
35+
echo "7\n";
36+
break;
37+
} finally {
38+
echo "8\n";
39+
}
40+
echo "bad";
41+
}
42+
echo "9\n";
43+
while (1) {
44+
try {
45+
throw new Exception("");
46+
} catch(Exception $e) {
47+
echo "10\n";
48+
break;
49+
} finally {
50+
echo "11\n";
51+
}
52+
echo "bak\n";
53+
}
54+
}
55+
echo "12\n";
56+
}
57+
echo "13\n";
58+
}
59+
bar();
60+
--EXPECT--
61+
1
62+
2
63+
3
64+
4
65+
5
66+
6
67+
7
68+
8
69+
9
70+
10
71+
11
72+
12
73+
13
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
Constant expressions with arrays
3+
--FILE--
4+
<?php
5+
const a = [1,2,[3,[4]]];
6+
const b = a[0];
7+
const c = a[2][0];
8+
const d = a[2];
9+
const e = ["string" => [1]]["string"][0];
10+
11+
var_dump(b, c, e);
12+
13+
function test ($a = d[1][0]) {
14+
var_dump($a);
15+
}
16+
17+
test();
18+
19+
class foo {
20+
const bar = [1][0];
21+
}
22+
23+
var_dump(foo::bar);
24+
25+
var_dump(a); // Eventually allow that later with array dereferencing of constants
26+
27+
?>
28+
--EXPECTF--
29+
int(1)
30+
int(3)
31+
int(1)
32+
int(4)
33+
int(1)
34+
35+
Fatal error: Arrays are not allowed in constants at run-time in %s on line %d
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Self-referencing constant expression (part of a constant AST)
3+
--XFAIL--
4+
Not yet fixed, to be fixed for PHP 5.6
5+
--FILE--
6+
<?php
7+
class A {
8+
const FOO = [self::BAR];
9+
const BAR = [self::FOO];
10+
}
11+
var_dump(A::FOO);
12+
?>
13+
--EXPECTF--
14+
Fatal error: Cannot declare self-referencing constant 'self::FOO' in %s on line %d
15+

Zend/tests/generators/bug67497.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Bug #67467: eval with parse error causes segmentation fault in generator
3+
--FILE--
4+
<?php
5+
6+
function gen() {
7+
$a = 1;
8+
yield $a;
9+
}
10+
11+
@eval('abc');
12+
13+
$values = gen();
14+
$values->next();
15+
16+
?>
17+
===DONE===
18+
--EXPECT--
19+
===DONE===

Zend/tests/try_finally_011.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Try finally (segfault with empty break)
3+
--FILE--
4+
<?php
5+
function foo () {
6+
try {
7+
break;
8+
} finally {
9+
}
10+
}
11+
12+
foo();
13+
?>
14+
--EXPECTF--
15+
Fatal error: Cannot break/continue 1 level in %stry_finally_011.php on line %d

Zend/zend_compile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,9 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
868868
#define ZEND_FAST_RET_TO_CATCH 1
869869
#define ZEND_FAST_RET_TO_FINALLY 2
870870

871+
#define ZEND_FAST_CALL_FROM_CATCH 1
872+
#define ZEND_FAST_CALL_FROM_FINALLY 2
873+
871874
END_EXTERN_C()
872875

873876
#define ZEND_CLONE_FUNC_NAME "__clone"

Zend/zend_generators.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
125125
/* A fatal error / die occurred during the generator execution. Trying to clean
126126
* up the stack may not be safe in this case. */
127127
if (CG(unclean_shutdown)) {
128+
generator->execute_data = NULL;
128129
return;
129130
}
130131

Zend/zend_opcode.c

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,49 @@ static void zend_check_finally_breakout(zend_op_array *op_array, zend_uint op_nu
509509
}
510510
}
511511

512+
static void zend_adjust_fast_call(zend_op_array *op_array, zend_uint fast_call, zend_uint start, zend_uint end TSRMLS_DC)
513+
{
514+
int i;
515+
zend_uint op_num = 0;
516+
517+
for (i = 0; i < op_array->last_try_catch; i++) {
518+
if (op_array->try_catch_array[i].finally_op > start
519+
&& op_array->try_catch_array[i].finally_end < end) {
520+
op_num = op_array->try_catch_array[i].finally_op;
521+
start = op_array->try_catch_array[i].finally_end;
522+
}
523+
}
524+
525+
if (op_num) {
526+
/* Must be ZEND_FAST_CALL */
527+
ZEND_ASSERT(op_array->opcodes[op_num - 2].opcode == ZEND_FAST_CALL);
528+
op_array->opcodes[op_num - 2].extended_value = ZEND_FAST_CALL_FROM_FINALLY;
529+
op_array->opcodes[op_num - 2].op2.opline_num = fast_call;
530+
}
531+
}
532+
533+
static void zend_resolve_fast_call(zend_op_array *op_array, zend_uint fast_call, zend_uint op_num TSRMLS_DC)
534+
{
535+
int i;
536+
zend_uint finally_op_num = 0;
537+
538+
for (i = 0; i < op_array->last_try_catch; i++) {
539+
if (op_num >= op_array->try_catch_array[i].finally_op
540+
&& op_num < op_array->try_catch_array[i].finally_end) {
541+
finally_op_num = op_array->try_catch_array[i].finally_op;
542+
}
543+
}
544+
545+
if (finally_op_num) {
546+
/* Must be ZEND_FAST_CALL */
547+
ZEND_ASSERT(op_array->opcodes[finally_op_num - 2].opcode == ZEND_FAST_CALL);
548+
if (op_array->opcodes[fast_call].extended_value == 0) {
549+
op_array->opcodes[fast_call].extended_value = ZEND_FAST_CALL_FROM_FINALLY;
550+
op_array->opcodes[fast_call].op2.opline_num = finally_op_num - 2;
551+
}
552+
}
553+
}
554+
512555
static void zend_resolve_finally_call(zend_op_array *op_array, zend_uint op_num, zend_uint dst_num TSRMLS_DC)
513556
{
514557
zend_uint start_op;
@@ -536,11 +579,23 @@ static void zend_resolve_finally_call(zend_op_array *op_array, zend_uint op_num,
536579
opline->opcode = ZEND_FAST_CALL;
537580
SET_UNUSED(opline->op1);
538581
SET_UNUSED(opline->op2);
539-
opline->op1.opline_num = op_array->try_catch_array[i].finally_op;
582+
zend_adjust_fast_call(op_array, start_op,
583+
op_array->try_catch_array[i].finally_op,
584+
op_array->try_catch_array[i].finally_end TSRMLS_CC);
540585
if (op_array->try_catch_array[i].catch_op) {
541-
opline->extended_value = 1;
586+
opline->extended_value = ZEND_FAST_CALL_FROM_CATCH;
542587
opline->op2.opline_num = op_array->try_catch_array[i].catch_op;
588+
opline->op1.opline_num = get_next_op_number(op_array);
589+
/* generate a FAST_CALL to hole CALL_FROM_FINALLY */
590+
opline = get_next_op(op_array TSRMLS_CC);
591+
opline->opcode = ZEND_FAST_CALL;
592+
SET_UNUSED(opline->op1);
593+
SET_UNUSED(opline->op2);
594+
zend_resolve_fast_call(op_array, start_op + 1, op_array->try_catch_array[i].finally_op - 2 TSRMLS_CC);
595+
} else {
596+
zend_resolve_fast_call(op_array, start_op, op_array->try_catch_array[i].finally_op - 2 TSRMLS_CC);
543597
}
598+
opline->op1.opline_num = op_array->try_catch_array[i].finally_op;
544599

545600
/* generate a sequence of FAST_CALL to upward finally block */
546601
while (i > 0) {
@@ -605,10 +660,10 @@ static void zend_resolve_finally_ret(zend_op_array *op_array, zend_uint op_num T
605660

606661
static void zend_resolve_finally_calls(zend_op_array *op_array TSRMLS_DC)
607662
{
608-
zend_uint i;
663+
zend_uint i, j;
609664
zend_op *opline;
610665

611-
for (i = 0; i < op_array->last; i++) {
666+
for (i = 0, j = op_array->last; i < j; i++) {
612667
opline = op_array->opcodes + i;
613668
switch (opline->opcode) {
614669
case ZEND_RETURN:
@@ -623,15 +678,16 @@ static void zend_resolve_finally_calls(zend_op_array *op_array TSRMLS_DC)
623678
zend_brk_cont_element *jmp_to;
624679

625680
nest_levels = Z_IVAL(op_array->literals[opline->op2.constant].constant);
626-
array_offset = opline->op1.opline_num;
627-
do {
628-
jmp_to = &op_array->brk_cont_array[array_offset];
629-
if (nest_levels > 1) {
630-
array_offset = jmp_to->parent;
631-
}
632-
} while (--nest_levels > 0);
633-
zend_resolve_finally_call(op_array, i, opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont TSRMLS_CC);
634-
break;
681+
if ((array_offset = opline->op1.opline_num) != -1) {
682+
do {
683+
jmp_to = &op_array->brk_cont_array[array_offset];
684+
if (nest_levels > 1) {
685+
array_offset = jmp_to->parent;
686+
}
687+
} while (--nest_levels > 0);
688+
zend_resolve_finally_call(op_array, i, opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont TSRMLS_CC);
689+
break;
690+
}
635691
}
636692
case ZEND_GOTO:
637693
if (Z_TYPE(op_array->literals[opline->op2.constant].constant) != IS_INT) {
@@ -644,6 +700,9 @@ static void zend_resolve_finally_calls(zend_op_array *op_array TSRMLS_DC)
644700
case ZEND_JMP:
645701
zend_resolve_finally_call(op_array, i, opline->op1.opline_num TSRMLS_CC);
646702
break;
703+
case ZEND_FAST_CALL:
704+
zend_resolve_fast_call(op_array, i, i TSRMLS_CC);
705+
break;
647706
case ZEND_FAST_RET:
648707
zend_resolve_finally_ret(op_array, i TSRMLS_CC);
649708
break;

Zend/zend_vm_def.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5625,13 +5625,13 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
56255625
{
56265626
USE_OPLINE
56275627

5628-
if (opline->extended_value &&
5628+
if ((opline->extended_value & ZEND_FAST_CALL_FROM_CATCH) &&
56295629
UNEXPECTED(EG(prev_exception) != NULL)) {
56305630
/* in case of unhandled exception jump to catch block instead of finally */
56315631
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
56325632
ZEND_VM_CONTINUE();
56335633
}
5634-
EX(fast_ret) = opline + 1;
5634+
EX(fast_ret) = opline;
56355635
EX(delayed_exception) = NULL;
56365636
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
56375637
ZEND_VM_CONTINUE();
@@ -5640,7 +5640,10 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
56405640
ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY)
56415641
{
56425642
if (EX(fast_ret)) {
5643-
ZEND_VM_SET_OPCODE(EX(fast_ret));
5643+
ZEND_VM_SET_OPCODE(EX(fast_ret) + 1);
5644+
if ((EX(fast_ret)->extended_value & ZEND_FAST_CALL_FROM_FINALLY)) {
5645+
EX(fast_ret) = &EX(op_array)->opcodes[EX(fast_ret)->op2.opline_num];
5646+
}
56445647
ZEND_VM_CONTINUE();
56455648
} else {
56465649
/* special case for unhandled exceptions */

Zend/zend_vm_execute.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,13 +1344,13 @@ static int ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
13441344
{
13451345
USE_OPLINE
13461346

1347-
if (opline->extended_value &&
1347+
if ((opline->extended_value & ZEND_FAST_CALL_FROM_CATCH) &&
13481348
UNEXPECTED(EG(prev_exception) != NULL)) {
13491349
/* in case of unhandled exception jump to catch block instead of finally */
13501350
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
13511351
ZEND_VM_CONTINUE();
13521352
}
1353-
EX(fast_ret) = opline + 1;
1353+
EX(fast_ret) = opline;
13541354
EX(delayed_exception) = NULL;
13551355
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
13561356
ZEND_VM_CONTINUE();
@@ -1359,7 +1359,10 @@ static int ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
13591359
static int ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
13601360
{
13611361
if (EX(fast_ret)) {
1362-
ZEND_VM_SET_OPCODE(EX(fast_ret));
1362+
ZEND_VM_SET_OPCODE(EX(fast_ret) + 1);
1363+
if ((EX(fast_ret)->extended_value & ZEND_FAST_CALL_FROM_FINALLY)) {
1364+
EX(fast_ret) = &EX(op_array)->opcodes[EX(fast_ret)->op2.opline_num];
1365+
}
13631366
ZEND_VM_CONTINUE();
13641367
} else {
13651368
/* special case for unhandled exceptions */

0 commit comments

Comments
 (0)