Skip to content

Commit 443b196

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: JIT x86: Fixed register clobbering in code produced for "$x[$y] %= $z". Fix #81420: ZipArchive::extractTo extracts outside of destination
2 parents 16c98d4 + f0f774a commit 443b196

File tree

5 files changed

+83
-12
lines changed

5 files changed

+83
-12
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4949,6 +4949,9 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
49494949

49504950
if (opcode == ZEND_MOD) {
49514951
result_reg = ZREG_RAX;
4952+
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) {
4953+
| mov aword T1, r0 // save
4954+
}
49524955
} else if (Z_MODE(res_addr) == IS_REG) {
49534956
if ((opline->opcode == ZEND_SL || opline->opcode == ZEND_SR)
49544957
&& opline->op2_type != IS_CONST) {
@@ -5053,18 +5056,23 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
50535056
if (op2_lval == 0) {
50545057
| SET_EX_OPLINE opline, r0
50555058
| jmp ->mod_by_zero
5056-
} else if (op2_lval == -1) {
5057-
| xor Ra(result_reg), Ra(result_reg)
50585059
} else {
50595060
result_reg = ZREG_RDX;
5060-
| GET_ZVAL_LVAL ZREG_RAX, op1_addr
5061-
| GET_ZVAL_LVAL ZREG_RCX, op2_addr
5062-
|.if X64
5063-
| cqo
5064-
|.else
5065-
| cdq
5066-
|.endif
5067-
| idiv Ra(ZREG_RCX)
5061+
if (op2_lval == -1) {
5062+
| xor Ra(result_reg), Ra(result_reg)
5063+
} else {
5064+
| GET_ZVAL_LVAL ZREG_RAX, op1_addr
5065+
| GET_ZVAL_LVAL ZREG_RCX, op2_addr
5066+
|.if X64
5067+
| cqo
5068+
|.else
5069+
| cdq
5070+
|.endif
5071+
| idiv Ra(ZREG_RCX)
5072+
}
5073+
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) {
5074+
| mov r0, aword T1 // restore
5075+
}
50685076
}
50695077
} else {
50705078
if (!op2_range || (op2_range->min <= 0 && op2_range->max >= 0)) {
@@ -5115,6 +5123,9 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
51155123
} else if (Z_MODE(op2_addr) == IS_REG) {
51165124
| idiv Ra(Z_REG(op2_addr))
51175125
}
5126+
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) {
5127+
| mov r0, aword T1 // restore
5128+
}
51185129
}
51195130
} else if (same_ops) {
51205131
| GET_ZVAL_LVAL result_reg, op1_addr

ext/opcache/tests/jit/mod_003.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
JIT MOD: 003
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.protect_memory=1
9+
opcache.jit=function
10+
--EXTENSIONS--
11+
opcache
12+
--FILE--
13+
<?php
14+
class Test {
15+
public $prop = 0;
16+
}
17+
function test1($test) {
18+
$test[0] %= 3;
19+
return $test;
20+
}
21+
function test2($test) {
22+
$test->prop %= 3;
23+
return $test;
24+
}
25+
var_dump(test1([0]));
26+
var_dump(test2(new Test));
27+
?>
28+
--EXPECT--
29+
array(1) {
30+
[0]=>
31+
int(0)
32+
}
33+
object(Test)#1 (1) {
34+
["prop"]=>
35+
int(0)
36+
}

ext/zip/php_zip.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */
9090
return NULL;
9191
}
9292

93-
if (IS_SLASH(path[0])) {
94-
return path + 1;
93+
if (IS_ABSOLUTE_PATH(path, path_len)) {
94+
return path + COPY_WHEN_ABSOLUTE(path) + 1;
9595
}
9696

9797
i = path_len;

ext/zip/tests/bug81420.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Bug #81420 (ZipArchive::extractTo extracts outside of destination)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("zip")) die("skip zip extension not available");
6+
?>
7+
--FILE--
8+
<?php
9+
$zip = new ZipArchive();
10+
$zip->open(__DIR__ . "/bug81420.zip");
11+
$destination = __DIR__ . "/bug81420";
12+
mkdir($destination);
13+
$zip->extractTo($destination);
14+
var_dump(file_exists("$destination/nt1/zzr_noharm.php"));
15+
?>
16+
--CLEAN--
17+
<?php
18+
$destination = __DIR__ . "/bug81420";
19+
@unlink("$destination/nt1/zzr_noharm.php");
20+
@rmdir("$destination/nt1");
21+
@rmdir($destination);
22+
?>
23+
--EXPECT--
24+
bool(true)

ext/zip/tests/bug81420.zip

218 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)