diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 2b9f33a67be74..44ca01796458f 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2655,6 +2655,13 @@ static ZEND_COLD zend_long _zend_jit_throw_dec_prop_error(zend_property_info *pr static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr, zend_property_info *prop_info) { + ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); + + if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY))) { + zend_readonly_property_modification_error(prop_info); + return; + } + zend_execute_data *execute_data = EG(current_execute_data); zval tmp; @@ -2678,6 +2685,13 @@ static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr, zend_property_i static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr, zend_property_info *prop_info) { + ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); + + if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY))) { + zend_readonly_property_modification_error(prop_info); + return; + } + zend_execute_data *execute_data = EG(current_execute_data); zval tmp; @@ -2715,6 +2729,16 @@ static void ZEND_FASTCALL zend_jit_pre_dec_typed_prop(zval *var_ptr, zend_proper static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result) { + ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); + + if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY))) { + zend_readonly_property_modification_error(prop_info); + if (result) { + ZVAL_UNDEF(result); + } + return; + } + zend_execute_data *execute_data = EG(current_execute_data); ZVAL_DEREF(var_ptr); @@ -2736,6 +2760,16 @@ static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_prope static void ZEND_FASTCALL zend_jit_post_dec_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result) { + ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); + + if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY))) { + zend_readonly_property_modification_error(prop_info); + if (result) { + ZVAL_UNDEF(result); + } + return; + } + zend_execute_data *execute_data = EG(current_execute_data); ZVAL_DEREF(var_ptr); diff --git a/ext/opcache/tests/jit/readonly_001.phpt b/ext/opcache/tests/jit/readonly_001.phpt new file mode 100644 index 0000000000000..db56f9a25b045 --- /dev/null +++ b/ext/opcache/tests/jit/readonly_001.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT readonly modification post-inc +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +--FILE-- +bar = 1; + $this->bar++; + } +} + +new Foo(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot modify readonly property Foo::$bar in %s:%d +Stack trace: +#0 %s(%d): Foo->__construct() +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/readonly_002.phpt b/ext/opcache/tests/jit/readonly_002.phpt new file mode 100644 index 0000000000000..aee1902700717 --- /dev/null +++ b/ext/opcache/tests/jit/readonly_002.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT readonly modification pre-inc +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +--FILE-- +bar = 1; + ++$this->bar; + } +} + +new Foo(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot modify readonly property Foo::$bar in %s:%d +Stack trace: +#0 %s(%d): Foo->__construct() +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/readonly_003.phpt b/ext/opcache/tests/jit/readonly_003.phpt new file mode 100644 index 0000000000000..73784919ef944 --- /dev/null +++ b/ext/opcache/tests/jit/readonly_003.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT readonly modification post-inc with result +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +--FILE-- +bar = 1; + var_dump($this->bar++); + } +} + +new Foo(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot modify readonly property Foo::$bar in %s:%d +Stack trace: +#0 %s(%d): Foo->__construct() +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/readonly_004.phpt b/ext/opcache/tests/jit/readonly_004.phpt new file mode 100644 index 0000000000000..50054d2e83ef8 --- /dev/null +++ b/ext/opcache/tests/jit/readonly_004.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT readonly modification pre-inc with result +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +--FILE-- +bar = 1; + var_dump(++$this->bar); + } +} + +new Foo(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot modify readonly property Foo::$bar in %s:%d +Stack trace: +#0 %s(%d): Foo->__construct() +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/readonly_005.phpt b/ext/opcache/tests/jit/readonly_005.phpt new file mode 100644 index 0000000000000..208fee03dbd7d --- /dev/null +++ b/ext/opcache/tests/jit/readonly_005.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT readonly modification post-dec +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +--FILE-- +bar = 1; + $this->bar--; + } +} + +new Foo(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot modify readonly property Foo::$bar in %s:%d +Stack trace: +#0 %s(%d): Foo->__construct() +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/readonly_006.phpt b/ext/opcache/tests/jit/readonly_006.phpt new file mode 100644 index 0000000000000..aceb16399b409 --- /dev/null +++ b/ext/opcache/tests/jit/readonly_006.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT readonly modification pre-dec +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +--FILE-- +bar = 1; + --$this->bar; + } +} + +new Foo(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot modify readonly property Foo::$bar in %s:%d +Stack trace: +#0 %s(%d): Foo->__construct() +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/readonly_007.phpt b/ext/opcache/tests/jit/readonly_007.phpt new file mode 100644 index 0000000000000..9bee61c9a626a --- /dev/null +++ b/ext/opcache/tests/jit/readonly_007.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT readonly modification dec-inc with result +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +--FILE-- +bar = 1; + var_dump($this->bar--); + } +} + +new Foo(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot modify readonly property Foo::$bar in %s:%d +Stack trace: +#0 %s(%d): Foo->__construct() +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/readonly_008.phpt b/ext/opcache/tests/jit/readonly_008.phpt new file mode 100644 index 0000000000000..c38f2cba56e90 --- /dev/null +++ b/ext/opcache/tests/jit/readonly_008.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT readonly modification pre-dec with result +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +--FILE-- +bar = 1; + var_dump(--$this->bar); + } +} + +new Foo(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot modify readonly property Foo::$bar in %s:%d +Stack trace: +#0 %s(%d): Foo->__construct() +#1 {main} + thrown in %s on line %d