summaryrefslogtreecommitdiff
path: root/sapi/phpdbg
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2016-12-06 18:30:37 +0100
committerBob Weinand <bobwei9@hotmail.com>2016-12-06 18:30:37 +0100
commit43f88f25bbd40c350a5a255eb1ce687d70471ebc (patch)
tree24beaf09af2a89b020e3df65ee5447c4d236a856 /sapi/phpdbg
parent308cc2e9d4765b3fbdc89ec4479d4d229c640728 (diff)
parent7e12b5da712f603d4ff68c378c0b1f06dcc495db (diff)
downloadphp-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.c10
-rw-r--r--sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.inc6
-rw-r--r--sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt84
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]);
+
+?>