From 4a72dd782df3089a0d944a7e51eabebdf1f1abc3 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 25 Feb 2019 14:40:53 +0800 Subject: [PATCH 1/6] Fixed bug #77664 (Segmentation fault when using undefined constant in custom wrapper) --- NEWS | 4 ++++ ext/standard/tests/streams/bug77664.phpt | 19 +++++++++++++++++++ main/streams/userspace.c | 5 ++++- 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/streams/bug77664.phpt diff --git a/NEWS b/NEWS index 4dac16ac25c..37138ed998b 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PHP NEWS . Fixed bug #77652 (Anonymous classes can lose their interface information). (Nikita) +- Standard: + . Fixed bug #77664 (Segmentation fault when using undefined constant in + custom wrapper). (Laruence) + - MySQLi: . Fixed bug #77597 (mysqli_fetch_field hangs scripts). (Nikita) diff --git a/ext/standard/tests/streams/bug77664.phpt b/ext/standard/tests/streams/bug77664.phpt new file mode 100644 index 00000000000..6a925417e2a --- /dev/null +++ b/ext/standard/tests/streams/bug77664.phpt @@ -0,0 +1,19 @@ +--TEST-- +BUG #77664 (Segmentation fault when using undefined constant in custom wrapper) +--FILE-- + +--EXPECTF-- +Warning: file_get_contents(error://test): failed to open stream: operation failed in %sbug77664.php on line %d + +Fatal error: Uncaught Error: Undefined class constant 'self::INVALID' in %sbug77664.php:%d +Stack trace: +#0 %sbug77664.php(%d): file_get_contents('error://test') +#1 {main} + thrown in %sbug77664.php on line %d diff --git a/main/streams/userspace.c b/main/streams/userspace.c index c72c7765f00..4925e41ac32 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -289,7 +289,10 @@ static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php } /* create an instance of our class */ - object_init_ex(object, uwrap->ce); + if (object_init_ex(object, uwrap->ce) == FAILURE) { + ZVAL_UNDEF(object); + return; + } if (context) { add_property_resource(object, "context", context->res); From 3b5475e9ee48c27f7164eb1d9cbe873d2704b571 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 25 Feb 2019 14:42:18 +0800 Subject: [PATCH 2/6] Update NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 175850a6bee..a30c5c7df45 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,10 @@ PHP NEWS - sodium: . Fixed bug #77646 (sign_detached() strings not terminated). (Frank) +- Standard: + . Fixed bug #77664 (Segmentation fault when using undefined constant in + custom wrapper). (Laruence) + 21 Feb 2019, PHP 7.3.3 - Core: From 1c22ace0582fb0a2ec581237fcf1c5b9c41edd04 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 25 Feb 2019 15:00:14 +0800 Subject: [PATCH 3/6] Fixed bug #77660 (Segmentation fault on break 2147483648) --- NEWS | 1 + Zend/tests/bug77660.phpt | 10 ++++++++++ Zend/zend_compile.c | 4 ++-- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/bug77660.phpt diff --git a/NEWS b/NEWS index 37138ed998b..65eb3a98514 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ PHP NEWS ?? ??? 2019, PHP 7.2.17 - Core: + . Fixed bug #77660 (Segmentation fault on break 2147483648). (Laruence) . Fixed bug #77652 (Anonymous classes can lose their interface information). (Nikita) diff --git a/Zend/tests/bug77660.phpt b/Zend/tests/bug77660.phpt new file mode 100644 index 00000000000..94af1f9e2c5 --- /dev/null +++ b/Zend/tests/bug77660.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #77660 (Segmentation fault on break 2147483648) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Cannot 'break' 2147483648 levels in %sbug77660.php on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 06d00153372..d0bece72284 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4508,7 +4508,7 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */ zend_ast *depth_ast = ast->child[0]; zend_op *opline; - int depth; + zend_long depth; ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE); @@ -4535,7 +4535,7 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */ ast->kind == ZEND_AST_BREAK ? "break" : "continue"); } else { if (!zend_handle_loops_and_finally_ex(depth, NULL)) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' %d level%s", + zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' " ZEND_LONG_FMT " level%s", ast->kind == ZEND_AST_BREAK ? "break" : "continue", depth, depth == 1 ? "" : "s"); } From fb3f078eeb4ecb2de783b7ee936dd583e6285d3e Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 25 Feb 2019 15:00:37 +0800 Subject: [PATCH 4/6] Update NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index a30c5c7df45..de09bc7f902 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ PHP NEWS ?? ??? ????, PHP 7.3.4 - Core: + . Fixed bug #77660 (Segmentation fault on break 2147483648). (Laruence) . Fixed bug #77652 (Anonymous classes can lose their interface information). (Nikita) From 4ac954ac3e1217864e592ebb1531b4f0f31e2264 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 25 Feb 2019 15:04:04 +0800 Subject: [PATCH 5/6] Fixed compiler warning --- Zend/zend_compile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index aa1853aff71..90679c8cc95 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4572,12 +4572,12 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */ if (depth == 1) { zend_error(E_WARNING, "\"continue\" targeting switch is equivalent to \"break\". " \ - "Did you mean to use \"continue %d\"?", + "Did you mean to use \"continue " ZEND_LONG_FMT "\"?", depth + 1); } else { zend_error(E_WARNING, - "\"continue %d\" targeting switch is equivalent to \"break %d\". " \ - "Did you mean to use \"continue %d\"?", + "\"continue " ZEND_LONG_FMT "\" targeting switch is equivalent to \"break " ZEND_LONG_FMT "\". " \ + "Did you mean to use \"continue " ZEND_LONG_FMT "\"?", depth, depth, depth + 1); } } From af37d58cf7b77814b93ea97a8dcd2afb46c4424e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 25 Feb 2019 13:00:16 +0100 Subject: [PATCH 6/6] Fix assertion in Exception::getMessage() if $message is a ref And same for other properties. Encountered in Symfony. --- .../exception_getters_with_ref_props.phpt | 30 ++++++++++++++++ Zend/zend_exceptions.c | 36 ++++++++++++------- 2 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 Zend/tests/exception_getters_with_ref_props.phpt diff --git a/Zend/tests/exception_getters_with_ref_props.phpt b/Zend/tests/exception_getters_with_ref_props.phpt new file mode 100644 index 00000000000..d3dcd8326f5 --- /dev/null +++ b/Zend/tests/exception_getters_with_ref_props.phpt @@ -0,0 +1,30 @@ +--TEST-- +Calling exception getters when properties hold references +--FILE-- +message =& $refMsg; + $this->code =& $refCode; + $this->file =& $refFile; + $this->line =& $refLine; + } +} + +$refMsg = "foo"; +$refCode = 0; +$refFile = "foobar"; +$refLine = 42; +$ex = new MyException($refMsg, $refCode, $refFile, $refLine); +var_dump($ex->getMessage()); +var_dump($ex->getCode()); +var_dump($ex->getFile()); +var_dump($ex->getLine()); + +?> +--EXPECT-- +string(3) "foo" +int(0) +string(6) "foobar" +int(42) diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index b4deb29a720..486a5d39080 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -401,11 +401,13 @@ ZEND_METHOD(error_exception, __construct) Get the file in which the exception occurred */ ZEND_METHOD(exception, getFile) { - zval rv; + zval *prop, rv; DEFAULT_0_PARAMS; - ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_FILE)); + prop = GET_PROPERTY(getThis(), ZEND_STR_FILE); + ZVAL_DEREF(prop); + ZVAL_COPY(return_value, prop); } /* }}} */ @@ -413,11 +415,13 @@ ZEND_METHOD(exception, getFile) Get the line in which the exception occurred */ ZEND_METHOD(exception, getLine) { - zval rv; + zval *prop, rv; DEFAULT_0_PARAMS; - ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_LINE)); + prop = GET_PROPERTY(getThis(), ZEND_STR_LINE); + ZVAL_DEREF(prop); + ZVAL_COPY(return_value, prop); } /* }}} */ @@ -425,11 +429,13 @@ ZEND_METHOD(exception, getLine) Get the exception message */ ZEND_METHOD(exception, getMessage) { - zval rv; + zval *prop, rv; DEFAULT_0_PARAMS; - ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_MESSAGE)); + prop = GET_PROPERTY(getThis(), ZEND_STR_MESSAGE); + ZVAL_DEREF(prop); + ZVAL_COPY(return_value, prop); } /* }}} */ @@ -437,11 +443,13 @@ ZEND_METHOD(exception, getMessage) Get the exception code */ ZEND_METHOD(exception, getCode) { - zval rv; + zval *prop, rv; DEFAULT_0_PARAMS; - ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_CODE)); + prop = GET_PROPERTY(getThis(), ZEND_STR_CODE); + ZVAL_DEREF(prop); + ZVAL_COPY(return_value, prop); } /* }}} */ @@ -449,11 +457,13 @@ ZEND_METHOD(exception, getCode) Get the stack trace for the location in which the exception occurred */ ZEND_METHOD(exception, getTrace) { - zval rv; + zval *prop, rv; DEFAULT_0_PARAMS; - ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_TRACE)); + prop = GET_PROPERTY(getThis(), ZEND_STR_TRACE); + ZVAL_DEREF(prop); + ZVAL_COPY(return_value, prop); } /* }}} */ @@ -461,11 +471,13 @@ ZEND_METHOD(exception, getTrace) Get the exception severity */ ZEND_METHOD(error_exception, getSeverity) { - zval rv; + zval *prop, rv; DEFAULT_0_PARAMS; - ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_SEVERITY)); + prop = GET_PROPERTY(getThis(), ZEND_STR_SEVERITY); + ZVAL_DEREF(prop); + ZVAL_COPY(return_value, prop); } /* }}} */