From 2fdd142f9941a05bdcffb0d6c11662ec333e6e09 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 8 Oct 2019 12:18:59 +0200 Subject: [PATCH] Check for exception after applying stream filters This makes the stream opening actually fail, and avoids assertion failures when we tokenize with EG(exception) set. Also avoid throwing an additional warning after an exception has already been thrown. --- ext/standard/php_fopen_wrapper.c | 5 +++++ ext/standard/tests/file/bug38450_2.phpt | 2 -- ext/standard/tests/file/bug38450_3.phpt | 2 -- .../tests/filters/object_init_failure_2.phpt | 21 +++++++++++++++++++ ext/standard/tests/streams/bug77664.phpt | 2 -- .../tests/streams/user-stream-error.phpt | 2 -- main/streams/streams.c | 8 ++++++- 7 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 ext/standard/tests/filters/object_init_failure_2.phpt diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 06d2b5f28c..b1638342aa 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -374,6 +374,11 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa } efree(pathdup); + if (EG(exception)) { + php_stream_close(stream); + return NULL; + } + return stream; } else { /* invalid php://thingy */ diff --git a/ext/standard/tests/file/bug38450_2.phpt b/ext/standard/tests/file/bug38450_2.phpt index 774de66bfe..33a13da0db 100644 --- a/ext/standard/tests/file/bug38450_2.phpt +++ b/ext/standard/tests/file/bug38450_2.phpt @@ -102,8 +102,6 @@ var_dump($myvar); echo "Done\n"; ?> --EXPECTF-- -Warning: fopen(var://myvar): failed to open stream: "VariableStream::stream_open" call failed in %s on line %d - Fatal error: Uncaught Exception: constructor in %s:%d Stack trace: #0 [internal function]: VariableStream->__construct() diff --git a/ext/standard/tests/file/bug38450_3.phpt b/ext/standard/tests/file/bug38450_3.phpt index 0bcaeb2a89..8a5c696587 100644 --- a/ext/standard/tests/file/bug38450_3.phpt +++ b/ext/standard/tests/file/bug38450_3.phpt @@ -102,8 +102,6 @@ var_dump($myvar); echo "Done\n"; ?> --EXPECTF-- -Warning: fopen(var://myvar): failed to open stream: "VariableStream::stream_open" call failed in %sbug38450_3.php on line %d - Fatal error: Uncaught ArgumentCountError: Too few arguments to function VariableStream::__construct(), 0 passed and exactly 1 expected in %sbug38450_3.php:7 Stack trace: #0 [internal function]: VariableStream->__construct() diff --git a/ext/standard/tests/filters/object_init_failure_2.phpt b/ext/standard/tests/filters/object_init_failure_2.phpt new file mode 100644 index 0000000000..6a1458ff6a --- /dev/null +++ b/ext/standard/tests/filters/object_init_failure_2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Creating the stream filter object may fail (include variation) +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECTF-- +Warning: main(): unable to create or locate filter "sample.filter" in %s on line %d + +Warning: main(): Unable to create filter (sample.filter) in %s on line %d + +Warning: main(): Failed opening '%s' for inclusion (include_path='%s') in %s on line %d +Undefined constant 'FOO' diff --git a/ext/standard/tests/streams/bug77664.phpt b/ext/standard/tests/streams/bug77664.phpt index 6a925417e2..ff2e317026 100644 --- a/ext/standard/tests/streams/bug77664.phpt +++ b/ext/standard/tests/streams/bug77664.phpt @@ -10,8 +10,6 @@ stream_wrapper_register('error',ErrorWrapper::class); file_get_contents('error://test'); ?> --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') diff --git a/ext/standard/tests/streams/user-stream-error.phpt b/ext/standard/tests/streams/user-stream-error.phpt index 5cc87e7360..1bb46f3094 100644 --- a/ext/standard/tests/streams/user-stream-error.phpt +++ b/ext/standard/tests/streams/user-stream-error.phpt @@ -12,8 +12,6 @@ stream_wrapper_register('mystream', 'FailStream'); fopen('mystream://foo', 'r'); echo 'Done'; --EXPECTF-- -Warning: fopen(mystream://foo): failed to open stream: "FailStream::stream_open" call failed in %s%euser-stream-error.php on line %d - Fatal error: Uncaught Error: Call to undefined function _some_undefined_function() in %s%euser-stream-error.php:%d Stack trace: #0 [internal function]: FailStream->stream_open('mystream://foo', 'r', 0, NULL) diff --git a/main/streams/streams.c b/main/streams/streams.c index a2c716e17c..705f3bc633 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -148,10 +148,16 @@ static zend_llist *php_get_wrapper_errors_list(php_stream_wrapper *wrapper) /* {{{ wrapper error reporting */ void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption) { - char *tmp = estrdup(path); + char *tmp; char *msg; int free_msg = 0; + if (EG(exception)) { + /* Don't emit additional warnings if an exception has already been thrown. */ + return; + } + + tmp = estrdup(path); if (wrapper) { zend_llist *err_list = php_get_wrapper_errors_list(wrapper); if (err_list) { -- 2.40.0