From ac65f6af6ea6e4daa18b473391cf7a842d09349a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 May 2021 15:22:34 +0300 Subject: [PATCH] Fixed bug #81051 (Broken property type handling after incrementing reference) --- NEWS | 2 ++ ext/opcache/jit/zend_jit_helpers.c | 7 +++++ ext/opcache/tests/jit/bug81051.phpt | 43 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 ext/opcache/tests/jit/bug81051.phpt diff --git a/NEWS b/NEWS index fe0fc821fb2..308393bf87c 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ PHP NEWS . Fixed bug #76359 (open_basedir bypass through adding ".."). (cmb) - Opcache: + . Fixed bug #81051 (Broken property type handling after incrementing + reference). (Dmitry) . Fixed bug #80968 (JIT segfault with return from required file). (Dmitry) - Standard: diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 2f84c8f5c34..957f01584fb 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2179,6 +2179,7 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_prop(zval *zptr, zend_prop zend_execute_data *execute_data = EG(current_execute_data); zval z_copy; + ZVAL_DEREF(zptr); binary_op(&z_copy, zptr, value); if (EXPECTED(zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { zval_ptr_dtor(zptr); @@ -2261,6 +2262,7 @@ static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr, zend_property_i zend_execute_data *execute_data = EG(current_execute_data); zval tmp; + ZVAL_DEREF(var_ptr); ZVAL_COPY(&tmp, var_ptr); increment_function(var_ptr); @@ -2283,6 +2285,7 @@ static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr, zend_property_i zend_execute_data *execute_data = EG(current_execute_data); zval tmp; + ZVAL_DEREF(var_ptr); ZVAL_COPY(&tmp, var_ptr); decrement_function(var_ptr); @@ -2309,6 +2312,7 @@ static void ZEND_FASTCALL zend_jit_pre_inc_typed_prop(zval *var_ptr, zend_proper result = &tmp; } + ZVAL_DEREF(var_ptr); ZVAL_COPY(result, var_ptr); increment_function(var_ptr); @@ -2339,6 +2343,7 @@ static void ZEND_FASTCALL zend_jit_pre_dec_typed_prop(zval *var_ptr, zend_proper result = &tmp; } + ZVAL_DEREF(var_ptr); ZVAL_COPY(result, var_ptr); decrement_function(var_ptr); @@ -2364,6 +2369,7 @@ static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_prope { zend_execute_data *execute_data = EG(current_execute_data); + ZVAL_DEREF(var_ptr); ZVAL_COPY(result, var_ptr); increment_function(var_ptr); @@ -2384,6 +2390,7 @@ static void ZEND_FASTCALL zend_jit_post_dec_typed_prop(zval *var_ptr, zend_prope { zend_execute_data *execute_data = EG(current_execute_data); + ZVAL_DEREF(var_ptr); ZVAL_COPY(result, var_ptr); decrement_function(var_ptr); diff --git a/ext/opcache/tests/jit/bug81051.phpt b/ext/opcache/tests/jit/bug81051.phpt new file mode 100644 index 00000000000..3ea3d019ace --- /dev/null +++ b/ext/opcache/tests/jit/bug81051.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #80839: PHP problem with JIT +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +opcache.jit=1205 +--SKIPIF-- + +--FILE-- +buffer = $buffer; + $this->offset = $offset; + } + + public function getUnsignedVarInt() : int{ + return Binary::readUnsignedVarInt($this->buffer, $this->offset); + } + + public function get(int $len) : string{ + return $len === 1 ? $this->buffer[$this->offset++] : substr($this->buffer, ($this->offset += $len) - $len, $len); + } +} +$stream = new BinaryStream(str_repeat("\x01a", 1000)); +var_dump($stream->getUnsignedVarInt()); +var_dump($stream->get(1)); +?> +--EXPECT-- +int(0) +string(1) "a"