diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2016-12-06 18:30:37 +0100 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2016-12-06 18:30:37 +0100 |
commit | 43f88f25bbd40c350a5a255eb1ce687d70471ebc (patch) | |
tree | 24beaf09af2a89b020e3df65ee5447c4d236a856 /sapi/phpdbg | |
parent | 308cc2e9d4765b3fbdc89ec4479d4d229c640728 (diff) | |
parent | 7e12b5da712f603d4ff68c378c0b1f06dcc495db (diff) | |
download | php-git-43f88f25bbd40c350a5a255eb1ce687d70471ebc.tar.gz |
Merge branch 'PHP-7.0' into PHP-7.1
Diffstat (limited to 'sapi/phpdbg')
-rw-r--r-- | sapi/phpdbg/phpdbg_list.c | 10 | ||||
-rw-r--r-- | sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc | 6 | ||||
-rw-r--r-- | sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt | 84 |
3 files changed, 95 insertions, 5 deletions
diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c index 5755884ef6..c222972761 100644 --- a/sapi/phpdbg/phpdbg_list.c +++ b/sapi/phpdbg/phpdbg_list.c @@ -236,15 +236,16 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) { phpdbg_file_source data, *dataptr; zend_file_handle fake; zend_op_array *ret; - char *filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename); + char *filename; uint line; char *bufptr, *endptr; - char resolved_path_buf[MAXPATHLEN]; if (zend_stream_fixup(file, &bufptr, &data.len) == FAILURE) { return PHPDBG_G(compile_file)(file, type); } + filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename); + data.buf = emalloc(data.len + ZEND_MMAP_AHEAD + 1); if (data.len > 0) { memcpy(data.buf, bufptr, data.len); @@ -262,9 +263,6 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) { fake.opened_path = file->opened_path; *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data; - if (VCWD_REALPATH(filename, resolved_path_buf)) { - filename = resolved_path_buf; - } for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) { if (*bufptr == '\n') { @@ -324,6 +322,8 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) { return NULL; } + filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename); + dataptr = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), filename, strlen(filename)); ZEND_ASSERT(dataptr != NULL); diff --git a/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc b/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc new file mode 100644 index 0000000000..4f4155715d --- /dev/null +++ b/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc @@ -0,0 +1,6 @@ +<?php + +function foo() +{ + return '<result>'; // line 5 is executable +} diff --git a/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt b/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt new file mode 100644 index 0000000000..0ddbd6f527 --- /dev/null +++ b/sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt @@ -0,0 +1,84 @@ +--TEST-- +Getting executable lines from custom wrappers +--PHPDBG-- +r +q +--EXPECTF-- +[Successful compilation of %s] +prompt> array(1) { + [5]=> + int(0) +} +[Script ended normally] +prompt> +--FILE-- +<?php + +/** + * This example demonstrates how phpdbg_get_executable() behaves differently + * when passed the 'files' option vs without, in the face of some mild abuse + * of stream wrappers. + */ + +/** + * First, we define a stream wrapper that simply maps to a real file on disk. + */ +final class StreamWrapper +{ + public function stream_open( + string $path, + string $mode, + int $options = 0, + string &$openedPath = null + ) : bool { + if ($mode[0] !== 'r') { + return false; + } + + list($scheme, $path) = explode('://', $path, 2); + + $stream = \fopen($path, $mode); + + if ($stream === false) { + return false; + } + + $this->stream = $stream; + + /** + * The $openedPath reference variable is assigned, indicating the + * *actual* path that was opened. This affects the behaviour of + * constants like __FILE__. + */ + $openedPath = \realpath($path); + + return true; + } + + public function stream_read(int $count) : string { return \fread($this->stream, $count); } + public function stream_close() : bool { return \fclose($this->stream); } + public function stream_eof() : bool { return \feof($this->stream); } + public function stream_stat() { return \fstat($this->stream); } + + private $stream = false; +} + +stream_wrapper_register('wrapper', StreamWrapper::class); + +/** + * Next, we include a PHP file that contains executable lines, via the stream + * wrapper. + */ +$filename = __DIR__ . '/phpdbg_get_executable_stream_wrapper.inc'; +require 'wrapper://' . $filename; + +/** + * If we call phpdbg_get_executable() and pass no options, the realpath of the + * included file is present in the array, but indicates no executable lines. + */ +$x = phpdbg_get_executable(); + +// We expect [5 => 0], but got an empty array ... +var_dump($x[$filename]); + +?> |