summaryrefslogtreecommitdiff
path: root/sapi/phpdbg/phpdbg_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/phpdbg/phpdbg_list.c')
-rw-r--r--sapi/phpdbg/phpdbg_list.c185
1 files changed, 139 insertions, 46 deletions
diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c
index c96d8652f0..34e9187f52 100644
--- a/sapi/phpdbg/phpdbg_list.c
+++ b/sapi/phpdbg/phpdbg_list.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2015 The PHP Group |
+ | Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -31,8 +31,9 @@
#include "phpdbg_utils.h"
#include "phpdbg_prompt.h"
#include "php_streams.h"
+#include "zend_exceptions.h"
-ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s, flags) \
PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[12], flags)
@@ -61,9 +62,15 @@ PHPDBG_LIST(lines) /* {{{ */
} break;
case FILE_PARAM: {
- zend_string *file = zend_string_init(param->file.name, strlen(param->file.name), 0);
+ zend_string *file;
+ char resolved_path_buf[MAXPATHLEN];
+ const char *abspath = param->file.name;
+ if (VCWD_REALPATH(abspath, resolved_path_buf)) {
+ abspath = resolved_path_buf;
+ }
+ file = zend_string_init(abspath, strlen(abspath), 0);
phpdbg_list_file(file, param->file.line, 0, 0);
- efree(file);
+ zend_string_release(file);
} break;
phpdbg_default_switch_case();
@@ -110,10 +117,10 @@ PHPDBG_LIST(class) /* {{{ */
if (ce->info.user.filename) {
phpdbg_list_file(ce->info.user.filename, ce->info.user.line_end - ce->info.user.line_start + 1, ce->info.user.line_start, 0);
} else {
- phpdbg_error("list", "type=\"nosource\" class=\"%s\"", "The source of the requested class (%s) cannot be found", ce->name);
+ phpdbg_error("list", "type=\"nosource\" class=\"%s\"", "The source of the requested class (%s) cannot be found", ZSTR_VAL(ce->name));
}
} else {
- phpdbg_error("list", "type=\"internalclass\" class=\"%s\"", "The class requested (%s) is not user defined", ce->name);
+ phpdbg_error("list", "type=\"internalclass\" class=\"%s\"", "The class requested (%s) is not user defined", ZSTR_VAL(ce->name));
}
} else {
phpdbg_error("list", "type=\"notfound\" class=\"%s\"", "The requested class (%s) could not be found", param->str);
@@ -126,16 +133,8 @@ void phpdbg_list_file(zend_string *filename, uint count, int offset, uint highli
{
uint line, lastline;
phpdbg_file_source *data;
- char resolved_path_buf[MAXPATHLEN];
- const char *abspath;
- if (VCWD_REALPATH(filename->val, resolved_path_buf)) {
- abspath = resolved_path_buf;
- } else {
- abspath = filename->val;
- }
-
- if (!(data = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), abspath, strlen(abspath)))) {
+ if (!(data = zend_hash_find_ptr(&PHPDBG_G(file_sources), filename))) {
phpdbg_error("list", "type=\"unknownfile\"", "Could not find information about included file...");
return;
}
@@ -151,7 +150,7 @@ void phpdbg_list_file(zend_string *filename, uint count, int offset, uint highli
lastline = data->lines;
}
- phpdbg_xml("<list %r file=\"%s\">", filename);
+ phpdbg_xml("<list %r file=\"%s\">", ZSTR_VAL(filename));
for (line = offset; line < lastline;) {
uint linestart = data->line[line++];
@@ -181,7 +180,7 @@ void phpdbg_list_function(const zend_function *fbc) /* {{{ */
const zend_op_array *ops;
if (fbc->type != ZEND_USER_FUNCTION) {
- phpdbg_error("list", "type=\"internalfunction\" function=\"%s\"", "The function requested (%s) is not user defined", fbc->common.function_name);
+ phpdbg_error("list", "type=\"internalfunction\" function=\"%s\"", "The function requested (%s) is not user defined", ZSTR_VAL(fbc->common.function_name));
return;
}
@@ -231,43 +230,37 @@ void phpdbg_list_function_byname(const char *str, size_t len) /* {{{ */
efree(func_name);
} /* }}} */
+/* Note: do not free the original file handler, let original compile_file() or caller do that. Caller may rely on its value to check success */
zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
phpdbg_file_source data, *dataptr;
- zend_file_handle fake = {{0}};
+ zend_file_handle fake;
zend_op_array *ret;
- char *filename = (char *)(file->opened_path ? file->opened_path->val : file->filename);
+ char *filename;
uint line;
char *bufptr, *endptr;
- char resolved_path_buf[MAXPATHLEN];
-
- zend_stream_fixup(file, &data.buf, &data.len);
-
- data.filename = filename;
- data.line[0] = 0;
- if (file->handle.stream.mmap.old_closer) {
- /* do not unmap */
- file->handle.stream.closer = file->handle.stream.mmap.old_closer;
+ if (zend_stream_fixup(file, &bufptr, &data.len) == FAILURE) {
+ return PHPDBG_G(compile_file)(file, type);
}
-#if HAVE_MMAP
- if (file->handle.stream.mmap.map) {
- data.map = file->handle.stream.mmap.map;
+ 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);
}
-#endif
+ memset(data.buf + data.len, 0, ZEND_MMAP_AHEAD + 1);
+ data.line[0] = 0;
+ memset(&fake, 0, sizeof(fake));
fake.type = ZEND_HANDLE_MAPPED;
fake.handle.stream.mmap.buf = data.buf;
fake.handle.stream.mmap.len = data.len;
fake.free_filename = 0;
- fake.opened_path = file->opened_path;
fake.filename = filename;
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') {
@@ -276,34 +269,134 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
}
dataptr->lines = ++line;
dataptr->line[line] = endptr - data.buf;
- dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
-
- zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr);
- phpdbg_resolve_pending_file_break(filename);
ret = PHPDBG_G(compile_file)(&fake, type);
+ if (ret == NULL) {
+ efree(data.buf);
+ efree(dataptr);
+
+ fake.opened_path = NULL;
+ zend_file_handle_dtor(&fake);
+
+ return NULL;
+ }
+
+ dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
+ zend_hash_add_ptr(&PHPDBG_G(file_sources), ret->filename, dataptr);
+ phpdbg_resolve_pending_file_break(ZSTR_VAL(ret->filename));
+
fake.opened_path = NULL;
zend_file_handle_dtor(&fake);
return ret;
}
-void phpdbg_free_file_source(phpdbg_file_source *data) {
-#if HAVE_MMAP
- if (data->map) {
- munmap(data->map, data->len + ZEND_MMAP_AHEAD);
- } else
-#endif
+zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) {
+ char *filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename);
+ char resolved_path_buf[MAXPATHLEN];
+ zend_op_array *op_array;
+ phpdbg_file_source *dataptr;
+
+ if (VCWD_REALPATH(filename, resolved_path_buf)) {
+ filename = resolved_path_buf;
+
+ if (file->opened_path) {
+ zend_string_release(file->opened_path);
+ file->opened_path = zend_string_init(filename, strlen(filename), 0);
+ } else {
+ if (file->free_filename) {
+ efree((char *) file->filename);
+ }
+ file->free_filename = 0;
+ file->filename = filename;
+ }
+ }
+
+ op_array = PHPDBG_G(init_compile_file)(file, type);
+
+ if (op_array == NULL) {
+ return NULL;
+ }
+
+ dataptr = zend_hash_find_ptr(&PHPDBG_G(file_sources), op_array->filename);
+ ZEND_ASSERT(dataptr != NULL);
+
+ dataptr->op_array = *op_array;
+ if (dataptr->op_array.refcount) {
+ ++*dataptr->op_array.refcount;
+ }
+
+ return op_array;
+}
+
+zend_op_array *phpdbg_compile_string(zval *source_string, char *filename) {
+ zend_string *fake_name;
+ zend_op_array *op_array;
+ phpdbg_file_source *dataptr;
+ uint line;
+ char *bufptr, *endptr;
+
+ if (PHPDBG_G(flags) & PHPDBG_IN_EVAL) {
+ return PHPDBG_G(compile_string)(source_string, filename);
+ }
+
+ dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * Z_STRLEN_P(source_string));
+ dataptr->buf = estrndup(Z_STRVAL_P(source_string), Z_STRLEN_P(source_string));
+ dataptr->len = Z_STRLEN_P(source_string);
+ dataptr->line[0] = 0;
+ for (line = 0, bufptr = dataptr->buf - 1, endptr = dataptr->buf + dataptr->len; ++bufptr < endptr;) {
+ if (*bufptr == '\n') {
+ dataptr->line[++line] = (uint)(bufptr - dataptr->buf) + 1;
+ }
+ }
+ dataptr->lines = ++line;
+ dataptr->line[line] = endptr - dataptr->buf;
+
+ op_array = PHPDBG_G(compile_string)(source_string, filename);
+
+ if (op_array == NULL) {
+ efree(dataptr->buf);
+ efree(dataptr);
+ return NULL;
+ }
+
+ fake_name = strpprintf(0, "%s%c%p", filename, 0, op_array->opcodes);
+
+ dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
+ zend_hash_add_ptr(&PHPDBG_G(file_sources), fake_name, dataptr);
+
+ zend_string_release(fake_name);
+
+ dataptr->op_array = *op_array;
+ if (dataptr->op_array.refcount) {
+ ++*dataptr->op_array.refcount;
+ }
+
+ return op_array;
+}
+
+void phpdbg_free_file_source(zval *zv) {
+ phpdbg_file_source *data = Z_PTR_P(zv);
+
if (data->buf) {
efree(data->buf);
}
+ destroy_op_array(&data->op_array);
+
efree(data);
}
void phpdbg_init_list(void) {
PHPDBG_G(compile_file) = zend_compile_file;
+ PHPDBG_G(compile_string) = zend_compile_string;
zend_hash_init(&PHPDBG_G(file_sources), 1, NULL, (dtor_func_t) phpdbg_free_file_source, 0);
zend_compile_file = phpdbg_compile_file;
+ zend_compile_string = phpdbg_compile_string;
+}
+
+void phpdbg_list_update(void) {
+ PHPDBG_G(init_compile_file) = zend_compile_file;
+ zend_compile_file = phpdbg_init_compile_file;
}