Skip to content

Commit f77747b

Browse files
committed
Properly propagate url_stat exceptions during include
Make sure we abort operations early, and that we don't emit additional warnings or errors if an exception has been thrown.
1 parent d1537e5 commit f77747b

File tree

7 files changed

+60
-10
lines changed

7 files changed

+60
-10
lines changed

Zend/tests/bug60909_1.phpt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@ set_error_handler(function($errno, $errstr, $errfile, $errline){
1111
require 'notfound.php';
1212
--EXPECTF--
1313
error(require(notfound.php): failed to open stream: %s)
14-
Warning: Uncaught Exception: Foo in %sbug60909_1.php:5
14+
Fatal error: Uncaught Exception: Foo in %sbug60909_1.php:5
1515
Stack trace:
1616
#0 %sbug60909_1.php(8): {closure}(2, 'require(notfoun...', '%s', 8, Array)
1717
#1 %sbug60909_1.php(8): require()
1818
#2 {main}
1919
thrown in %sbug60909_1.php on line 5
2020

21-
Fatal error: main(): Failed opening required 'notfound.php' (include_path='%s') in %sbug60909_1.php on line 8
22-
2321

2422
!!!shutdown!!!
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Make sure exceptions during include/require stating are properly propagated
3+
--FILE--
4+
<?php
5+
6+
class StreamWrapper {
7+
public function url_stat($path, $flags) {
8+
throw new Exception('stat failed');
9+
}
10+
}
11+
12+
stream_wrapper_register('test', StreamWrapper::class);
13+
set_include_path('test://foo:test://bar');
14+
15+
try {
16+
require_once 'doesnt_exist.php';
17+
} catch (Exception $e) {
18+
echo $e->getMessage(), "\n";
19+
}
20+
try {
21+
require 'doesnt_exist.php';
22+
} catch (Exception $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
try {
26+
include_once 'doesnt_exist.php';
27+
} catch (Exception $e) {
28+
echo $e->getMessage(), "\n";
29+
}
30+
try {
31+
include 'doesnt_exist.php';
32+
} catch (Exception $e) {
33+
echo $e->getMessage(), "\n";
34+
}
35+
36+
?>
37+
--EXPECT--
38+
stat failed
39+
stat failed
40+
stat failed
41+
stat failed

Zend/zend_execute.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4192,6 +4192,8 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
41924192
if (zend_hash_exists(&EG(included_files), resolved_path)) {
41934193
goto already_compiled;
41944194
}
4195+
} else if (UNEXPECTED(EG(exception))) {
4196+
break;
41954197
} else if (UNEXPECTED(strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename))) {
41964198
zend_message_dispatcher(
41974199
(type == ZEND_INCLUDE_ONCE) ?

Zend/zend_language_scanner.l

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -637,11 +637,13 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type)
637637
zend_save_lexical_state(&original_lex_state);
638638

639639
if (open_file_for_scanning(file_handle)==FAILURE) {
640-
if (type==ZEND_REQUIRE) {
641-
zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
642-
zend_bailout();
643-
} else {
644-
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
640+
if (!EG(exception)) {
641+
if (type==ZEND_REQUIRE) {
642+
zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
643+
zend_bailout();
644+
} else {
645+
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
646+
}
645647
}
646648
} else {
647649
op_array = zend_compile(ZEND_USER_FUNCTION);

ext/standard/tests/filters/object_init_failure_2.phpt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,4 @@ try {
1616
Warning: main(): unable to create or locate filter "sample.filter" in %s on line %d
1717

1818
Warning: main(): Unable to create filter (sample.filter) in %s on line %d
19-
20-
Warning: main(): Failed opening '%s' for inclusion (include_path='%s') in %s on line %d
2119
Undefined constant 'FOO'

main/fopen_wrappers.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,9 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt
561561
if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL)) {
562562
return zend_string_init(trypath, strlen(trypath), 0);
563563
}
564+
if (EG(exception)) {
565+
return NULL;
566+
}
564567
}
565568
continue;
566569
}
@@ -598,6 +601,9 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt
598601
if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL)) {
599602
return zend_string_init(trypath, strlen(trypath), 0);
600603
}
604+
if (EG(exception)) {
605+
return NULL;
606+
}
601607
}
602608
return NULL;
603609
}

main/streams/streams.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,6 +2074,9 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
20742074
options |= STREAM_ASSUME_REALPATH;
20752075
options &= ~USE_PATH;
20762076
}
2077+
if (EG(exception)) {
2078+
return NULL;
2079+
}
20772080
}
20782081

20792082
path_to_open = path;

0 commit comments

Comments
 (0)