Skip to content

Commit

Permalink
Fixed issues with foreach related opcodes and finding jump endpoints …
Browse files Browse the repository at this point in the history
…with PHP 7
  • Loading branch information
derickr committed Nov 28, 2015
1 parent 62031cc commit 5134e20
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 22 deletions.
20 changes: 16 additions & 4 deletions srm_oparray.c
Expand Up @@ -142,7 +142,7 @@ static const op_usage opcodes[] = {
#endif
#if defined(ZEND_ENGINE_3)
/* 77 */ { "FE_RESET_R", SPECIAL },
/* 78 */ { "FE_FETCH_R", ALL_USED | OP2_OPNUM },
/* 78 */ { "FE_FETCH_R", ALL_USED | EXT_VAL_JMP },
#else
/* 77 */ { "FE_RESET", SPECIAL },
/* 78 */ { "FE_FETCH", ALL_USED | OP2_OPNUM },
Expand Down Expand Up @@ -225,7 +225,7 @@ static const op_usage opcodes[] = {
/* 123 */ { "TYPE_CHECK", ALL_USED | EXT_VAL },
/* 124 */ { "VERIFY_RETURN_TYPE", ALL_USED },
/* 125 */ { "FE_RESET_RW", SPECIAL },
/* 126 */ { "FE_FETCH_RW", SPECIAL },
/* 126 */ { "FE_FETCH_RW", ALL_USED | EXT_VAL_JMP },
/* 127 */ { "FE_FREE", ALL_USED },
/* 128 */ { "INIT_DYNAMIC_CALL", ALL_USED },
/* 129 */ { "DO_ICALL", ALL_USED },
Expand Down Expand Up @@ -802,6 +802,13 @@ void vld_dump_op(int nr, zend_op * op_ptr, unsigned int base_address, int notdea
vld_printf (stderr, ", ->%d", jmp);
VLD_PRINT(3, " ]");
}
#if PHP_VERSION_ID >= 70000
if (flags & EXT_VAL_JMP) {
VLD_PRINT(3, " EXT_JMP[ ");
vld_printf (stderr, ", ->%d", nr + (op.extended_value / sizeof(zend_op)));
VLD_PRINT(3, " ]");
}
#endif
if (flags & NOP2_OPNUM) {
zend_op next_op = op_ptr[nr+1];
vld_dump_znode (&print_sep, VLD_IS_OPNUM, next_op.op2, base_address, opa, nr TSRMLS_CC);
Expand Down Expand Up @@ -917,10 +924,11 @@ int vld_find_jump(zend_op_array *opa, unsigned int position, long *jmp1, long *j
} else if (opcode.opcode == ZEND_JMPZNZ) {
#if PHP_VERSION_ID >= 70000
*jmp1 = VLD_ZNODE_JMP_LINE(opcode.op2, position, base_address) * sizeof(zend_op);
*jmp2 = position + (opcode.extended_value / sizeof(zend_op));
#else
*jmp1 = VLD_ZNODE_ELEM(opcode.op2, opline_num);
#endif
*jmp2 = opcode.extended_value;
#endif
return 1;
#if PHP_VERSION_ID < 70000
} else if (opcode.opcode == ZEND_BRK || opcode.opcode == ZEND_CONT) {
Expand All @@ -941,7 +949,11 @@ int vld_find_jump(zend_op_array *opa, unsigned int position, long *jmp1, long *j
}
#endif
#if PHP_VERSION_ID >= 70000
} else if (opcode.opcode == ZEND_FE_RESET_R || opcode.opcode == ZEND_FE_RESET_RW || opcode.opcode == ZEND_FE_FETCH_R || opcode.opcode == ZEND_FE_FETCH_RW) {
} else if (opcode.opcode == ZEND_FE_FETCH_R || opcode.opcode == ZEND_FE_FETCH_RW) {
*jmp1 = position + 1;
*jmp2 = position + (opcode.extended_value / sizeof(zend_op));
return 1;
} else if (opcode.opcode == ZEND_FE_RESET_R || opcode.opcode == ZEND_FE_RESET_RW) {
#else
} else if (opcode.opcode == ZEND_FE_RESET || opcode.opcode == ZEND_FE_FETCH) {
#endif
Expand Down
1 change: 1 addition & 0 deletions srm_oparray.h
Expand Up @@ -66,6 +66,7 @@
#define VLD_IS_OPNUM 1<<14
#define VLD_IS_CLASS 1<<15
#define OP2_INCLUDE 1<<16
#define EXT_VAL_JMP 1<<17

typedef struct _op_usage {
char *name;
Expand Down
4 changes: 2 additions & 2 deletions tests/issue00019-php70.phpt
Expand Up @@ -37,11 +37,11 @@ line #* E I O op fetch ext return opera
1 RECV !1
3 2 SUB ~2 !0, !1
3 > RETURN ~2
4* > RETURN null
4 4* > RETURN null

End of function foo

branch: # 0; line: 2- 4; sop: 0; eop: 1; out1: -2
path #1: 0,
branch: # 0; line: 2- 3; sop: 0; eop: 4
branch: # 0; line: 2- 4; sop: 0; eop: 4
path #1: 0,
Expand Up @@ -3,7 +3,10 @@ Test for issue #20
--INI--
vld.active=1
--SKIPIF--
<?php if (PHP_VERSION_ID < 70000) { echo "skip PHP 7 required\n"; } ?>
<?php
if (PHP_VERSION_ID < 70000) { echo "skip PHP 7 required\n"; }
if (PHP_INT_SIZE != 4) { echo "skip 32bit test\n"; }
?>
--FILE--
<?php
$x = 2;
Expand All @@ -14,21 +17,21 @@ $z = "-${x}${x}";
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = -2
filename: %sissue00020-01-php70.php
filename: %sissue00020-01-php70-32bit.php
function name: (null)
number of ops: 10
compiled vars: !0 = $x, !1 = $y, !2 = $z
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 2
3 1 ROPE_INIT 0 ~4 45
2 ROPE_END 0 ~4 ~4, !0
3 ROPE_END 0 ~4 ~4, !0
3 1 ROPE_INIT 3 ~5 '-'
2 ROPE_ADD 1 ~5 ~5, !0
3 ROPE_END 2 ~4 ~5, !0
4 ASSIGN !1, ~4
4 5 ROPE_INIT 0 ~6 45
6 ROPE_END 0 ~6 ~6, !0
7 ROPE_END 0 ~6 ~6, !0
8 ASSIGN !2, ~6
4 5 ROPE_INIT 3 ~8 '-'
6 ROPE_ADD 1 ~8 ~8, !0
7 ROPE_END 2 ~7 ~8, !0
8 ASSIGN !2, ~7
9 > RETURN 1

branch: # 0; line: 2- 4; sop: 0; eop: 9; out1: -2
Expand Down
38 changes: 38 additions & 0 deletions tests/issue00020-01-php70-64bit.phpt
@@ -0,0 +1,38 @@
--TEST--
Test for issue #20
--INI--
vld.active=1
--SKIPIF--
<?php
if (PHP_VERSION_ID < 70000) { echo "skip PHP 7 required\n"; }
if (PHP_INT_SIZE != 8) { echo "skip 64bit test\n"; }
?>
--FILE--
<?php
$x = 2;
$y = "-{$x}{$x}";
$z = "-${x}${x}";
?>
--EXPECTF--
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = -2
filename: %sissue00020-01-php70-64bit.php
function name: (null)
number of ops: 10
compiled vars: !0 = $x, !1 = $y, !2 = $z
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 2
3 1 ROPE_INIT 3 ~5 '-'
2 ROPE_ADD 1 ~5 ~5, !0
3 ROPE_END 2 ~4 ~5, !0
4 ASSIGN !1, ~4
4 5 ROPE_INIT 3 ~9 '-'
6 ROPE_ADD 1 ~9 ~9, !0
7 ROPE_END 2 ~8 ~9, !0
8 ASSIGN !2, ~8
9 > RETURN 1

branch: # 0; line: 2- 4; sop: 0; eop: 9; out1: -2
path #1: 0,
Expand Up @@ -3,7 +3,10 @@ Test for issue #20
--INI--
vld.active=1
--SKIPIF--
<?php if (PHP_VERSION_ID < 70000) { echo "skip PHP 7 required\n"; } ?>
<?php
if (PHP_VERSION_ID < 70000) { echo "skip PHP 7 required\n"; }
if (PHP_INT_SIZE != 4) { echo "skip 32bit test\n"; }
?>
--FILE--
<?php
$x = 2;
Expand All @@ -13,18 +16,18 @@ $z = "-${x}${x}" <=> 1;
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = -2
filename: %sissue00020-02-php70.php
filename: %sissue00020-02-php70-32bit.php
function name: (null)
number of ops: 7
compiled vars: !0 = $x, !1 = $z
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 2
3 1 ROPE_INIT 0 ~3 45
2 ROPE_END 0 ~3 ~3, !0
3 ROPE_END 0 ~3 ~3, !0
4 SPACESHIP ~4 ~3, 1
5 ASSIGN !1, ~4
3 1 ROPE_INIT 3 ~4 '-'
2 ROPE_ADD 1 ~4 ~4, !0
3 ROPE_END 2 ~3 ~4, !0
4 SPACESHIP ~5 ~3, 1
5 ASSIGN !1, ~5
6 > RETURN 1

branch: # 0; line: 2- 3; sop: 0; eop: 6; out1: -2
Expand Down
34 changes: 34 additions & 0 deletions tests/issue00020-02-php70-64bit.phpt
@@ -0,0 +1,34 @@
--TEST--
Test for issue #20
--INI--
vld.active=1
--SKIPIF--
<?php
if (PHP_VERSION_ID < 70000) { echo "skip PHP 7 required\n"; }
if (PHP_INT_SIZE != 8) { echo "skip 64bit test\n"; }
?>
--FILE--
<?php
$x = 2;
$z = "-${x}${x}" <=> 1;
?>
--EXPECTF--
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = -2
filename: %sissue00020-02-php70-64bit.php
function name: (null)
number of ops: 7
compiled vars: !0 = $x, !1 = $z
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 2
3 1 ROPE_INIT 3 ~4 '-'
2 ROPE_ADD 1 ~4 ~4, !0
3 ROPE_END 2 ~3 ~4, !0
4 SPACESHIP ~6 ~3, 1
5 ASSIGN !1, ~6
6 > RETURN 1

branch: # 0; line: 2- 3; sop: 0; eop: 6; out1: -2
path #1: 0,

0 comments on commit 5134e20

Please sign in to comment.