From c35bb34608b3dc0f15296ab5ffddf2d8a594a65a Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 9 Sep 2014 02:15:33 +0200 Subject: [PATCH 001/125] Add webhelper extension and support for loading extensions New phpdbg commands: dl [path] - loads module / Zend extension wait - waits for incoming connection from a phpdbg_webhelper module Webhelper module is a UNIX domain socket to which a SAPI with the phpdbg_webhelper module loaded will write to the socket information about its whole environment. phpdbg can then run the request locally [TODO: write the request back to the sender] --- config.m4 | 20 +- phpdbg.c | 8 +- phpdbg.h | 25 +- phpdbg_cmd.c | 3 - phpdbg_prompt.c | 250 +++++++++++++++++++- phpdbg_prompt.h | 4 +- phpdbg_rinit_hook.c | 88 +++++++ phpdbg_rinit_hook.h | 43 ++++ phpdbg_webdata_transfer.h | 480 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 901 insertions(+), 20 deletions(-) create mode 100644 phpdbg_rinit_hook.c create mode 100644 phpdbg_rinit_hook.h create mode 100644 phpdbg_webdata_transfer.h diff --git a/config.m4 b/config.m4 index d78a439af02..06c7ee098a4 100644 --- a/config.m4 +++ b/config.m4 @@ -3,12 +3,15 @@ dnl $Id$ dnl PHP_ARG_ENABLE(phpdbg, for phpdbg support, -[ --enable-phpdbg Build phpdbg], no, no) +[ --enable-phpdbg Build phpdbg], no, no) + +PHP_ARG_ENABLE(phpdbg-webhelper, for phpdbg web SAPI support, +[ --enable-phpdbg-webhelper Build phpdbg web SAPI support], yes, yes) PHP_ARG_ENABLE(phpdbg-debug, for phpdbg debug build, -[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no) +[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no) -if test "$PHP_PHPDBG" != "no"; then +if test "$BUILD_PHPDBG" == "" && test "$PHP_PHPDBG" != "no"; then AC_HEADER_TIOCGWINSZ AC_DEFINE(HAVE_PHPDBG, 1, [ ]) @@ -18,6 +21,17 @@ if test "$PHP_PHPDBG" != "no"; then AC_DEFINE(PHPDBG_DEBUG, 0, [ ]) fi + if test "$PHP_PHPDBG_WEBHELPER" != "no"; then + if ! test -d ext/phpdbg_webhelper; then + ln -s ../sapi/phpdbg ext/phpdbg_webhelper + fi + if test "$PHP_JSON" != "no"; then + PHP_NEW_EXTENSION(phpdbg_webhelper, phpdbg_rinit_hook.c, $ext_shared) + else + AC_MSG_ERROR(Webhelper extension of phpdbg needs json enabled) + fi + fi + PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c" diff --git a/phpdbg.c b/phpdbg.c index 1fbd18a423a..15da7196b50 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -43,6 +43,10 @@ ZEND_DECLARE_MODULE_GLOBALS(phpdbg); +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("phpdbg.path", "", PHP_INI_SYSTEM | PHP_INI_PERDIR, OnUpdateString, socket_path, zend_phpdbg_globals, phpdbg_globals) +PHP_INI_END() + static zend_bool phpdbg_booted = 0; #if PHP_VERSION_ID >= 50500 @@ -77,6 +81,8 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ { ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL); + REGISTER_INI_ENTRIES(); + #if PHP_VERSION_ID >= 50500 zend_execute_old = zend_execute_ex; zend_execute_ex = phpdbg_execute_ex; @@ -86,7 +92,7 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ #endif REGISTER_STRINGL_CONSTANT("PHPDBG_VERSION", PHPDBG_VERSION, sizeof(PHPDBG_VERSION)-1, CONST_CS|CONST_PERSISTENT); - + REGISTER_LONG_CONSTANT("PHPDBG_FILE", FILE_PARAM, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHPDBG_METHOD", METHOD_PARAM, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHPDBG_LINENO", NUMERIC_PARAM, CONST_CS|CONST_PERSISTENT); diff --git a/phpdbg.h b/phpdbg.h index 2fa2d5093a8..cf47cfc1e4e 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -64,7 +64,7 @@ # include "TSRM.h" #endif -#ifdef HAVE_LIBREADLINE +#ifdef LIBREADLINE # include # include #endif @@ -72,6 +72,16 @@ # include #endif +/* {{{ strings */ +#define PHPDBG_NAME "phpdbg" +#define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */ +#define PHPDBG_URL "http://phpdbg.com" +#define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues" +#define PHPDBG_VERSION "0.4.0" +#define PHPDBG_INIT_FILENAME ".phpdbginit" +/* }}} */ + +#ifndef PHPDBG_WEBHELPER_H #include "phpdbg_lexer.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" @@ -158,15 +168,6 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); # define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_BP_ENABLED) #endif /* }}} */ -/* {{{ strings */ -#define PHPDBG_NAME "phpdbg" -#define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */ -#define PHPDBG_URL "http://phpdbg.com" -#define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues" -#define PHPDBG_VERSION "0.4.0" -#define PHPDBG_INIT_FILENAME ".phpdbginit" -/* }}} */ - /* {{{ output descriptors */ #define PHPDBG_STDIN 0 #define PHPDBG_STDOUT 1 @@ -210,6 +211,8 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) char *buffer; /* buffer */ zend_ulong flags; /* phpdbg flags */ + + char *socket_path; /* phpdbg.path ini setting */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ /* the beginning (= the important part) of the _zend_mm_heap struct defined in Zend/zend_alloc.c @@ -227,4 +230,6 @@ struct _zend_mm_heap { zend_mm_storage *storage; }; +#endif + #endif /* PHPDBG_H */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index a45513bee6b..38b73b6a149 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -792,9 +792,7 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC) PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ { char *cmd = NULL; -#if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT) char buf[PHPDBG_MAX_CMD]; -#endif char *buffer = NULL; if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { @@ -832,7 +830,6 @@ readline: /* note: EOF makes readline write prompt again in local console mode */ readline: if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { - char buf[PHPDBG_MAX_CMD]; if (fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) { cmd = buf; } else goto disconnect; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index d91ef3f3f5c..2940d0a1560 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -23,6 +23,9 @@ #include "zend.h" #include "zend_compile.h" #include "phpdbg.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + #include "phpdbg_help.h" #include "phpdbg_print.h" #include "phpdbg_info.h" @@ -37,6 +40,21 @@ #include "phpdbg_frame.h" #include "phpdbg_lexer.h" #include "phpdbg_parser.h" +#include "phpdbg_webdata_transfer.h" + +#ifdef HAVE_LIBDL +#ifdef PHP_WIN32 +#include "win32/param.h" +#include "win32/winutil.h" +#define GET_DL_ERROR() php_win_err() +#elif defined(NETWARE) +#include +#define GET_DL_ERROR() dlerror() +#else +#include +#define GET_DL_ERROR() DL_ERROR() +#endif +#endif /* {{{ command declarations */ const phpdbg_command_t phpdbg_prompt_commands[] = { @@ -61,14 +79,14 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s"), PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s"), + PHPDBG_COMMAND_D(dl, "load module or zend extension", 0, NULL, "|s"), PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), + PHPDBG_COMMAND_D(wait, "wait for other process", 'W', NULL, 0), PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss"), PHPDBG_END_COMMAND }; /* }}} */ -ZEND_EXTERN_MODULE_GLOBALS(phpdbg); - static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ */ { phpdbg_param_t *name = NULL; @@ -847,6 +865,190 @@ PHPDBG_COMMAND(sh) /* {{{ */ return SUCCESS; } /* }}} */ +static int add_extension_info(zend_module_entry *module TSRMLS_DC) { + phpdbg_write("%s\n", module->name); + return 0; +} + +static int add_zendext_info(zend_extension *ext TSRMLS_DC) { + phpdbg_write("%s\n", ext->name); + return 0; +} + +PHPDBG_API const char *phpdbg_load_module_or_extension(char **path, char **str TSRMLS_DC) { + DL_HANDLE handle; + char *extension_dir; + + extension_dir = INI_STR("extension_dir"); + + if (strchr(*path, '/') != NULL || strchr(*path, DEFAULT_SLASH) != NULL) { + /* path is fine */ + } else if (extension_dir && extension_dir[0]) { + char *libpath; + int extension_dir_len = strlen(extension_dir); + if (IS_SLASH(extension_dir[extension_dir_len-1])) { + spprintf(&libpath, 0, "%s%s", extension_dir, *path); /* SAFE */ + } else { + spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, *path); /* SAFE */ + } + efree(*path); + *path = libpath; + } else { + *str = estrdup("Not a full path given or extension_dir ini setting is not set"); + + return NULL; + } + + handle = DL_LOAD(*path); + + if (!handle) { +#if PHP_WIN32 + char *err = GET_DL_ERROR(); + if (err && (*err != "")) { + *str = estrdup(err); + LocalFree(err); + } else { + *str = estrdup("Unknown reason"); + } +#else + *str = estrdup(GET_DL_ERROR()); + GET_DL_ERROR(); /* free the buffer storing the error */ +#endif + return NULL; + } + +#if ZEND_EXTENSIONS_SUPPORT + do { + zend_extension *new_extension; + zend_extension_version_info *extension_version_info; + + extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info"); + if (!extension_version_info) { + extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "_extension_version_info"); + } + new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry"); + if (!new_extension) { + new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "_zend_extension_entry"); + } + if (!extension_version_info || !new_extension) { + break; + } + if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) { + asprintf(str, "%s requires Zend Engine API version %d, which does not match the installed Zend Engine API version %d", new_extension->name, extension_version_info->zend_extension_api_no, ZEND_EXTENSION_API_NO); + + goto quit; + } else if (strcmp(ZEND_EXTENSION_BUILD_ID, extension_version_info->build_id) && (!new_extension->build_id_check || new_extension->build_id_check(ZEND_EXTENSION_BUILD_ID) != SUCCESS)) { + asprintf(str, "%s was built with configuration %s, whereas running engine is %s", new_extension->name, extension_version_info->build_id, ZEND_EXTENSION_BUILD_ID); + + goto quit; + } + + *str = new_extension->name; + + zend_register_extension(new_extension, handle); + + if (new_extension->startup) { + if (new_extension->startup(new_extension) != SUCCESS) { + asprintf(str, "Unable to startup Zend extension %s", new_extension->name); + + goto quit; + } + zend_append_version_info(new_extension); + } + + return "Zend extension"; + } while (0); +#endif + + do { + zend_module_entry *module_entry; + zend_module_entry *(*get_module)(void); + + get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module"); + if (!get_module) { + get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "_get_module"); + } + + if (!get_module) { + break; + } + + module_entry = get_module(); + + if (strcmp(ZEND_EXTENSION_BUILD_ID, module_entry->build_id)) { + asprintf(str, "%s was built with configuration %s, whereas running engine is %s", module_entry->name, module_entry->build_id, ZEND_EXTENSION_BUILD_ID); + + goto quit; + } + + module_entry->type = MODULE_PERSISTENT; + module_entry->module_number = zend_next_free_module(); + module_entry->handle = handle; + + if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) { + asprintf(str, "Unable to register module %s", module_entry->name); + + goto quit; + } + + if (zend_startup_module_ex(module_entry TSRMLS_CC) == FAILURE) { + asprintf(str, "Unable to startup module %s", module_entry->name); + + goto quit; + } + + if (module_entry->request_startup_func) { + if (module_entry->request_startup_func(MODULE_PERSISTENT, module_entry->module_number TSRMLS_CC) == FAILURE) { + asprintf(str, "Unable to initialize module %s", module_entry->name); + + goto quit; + } + } + + return "module"; + } while (0); + + *str = estrdup("This shared object is nor a Zend extension nor a module"); + +quit: + DL_UNLOAD(handle); + return NULL; +} + +PHPDBG_COMMAND(dl) /* {{{ */ +{ + const char *type; + char *name, *path; + + if (!param || param->type == EMPTY_PARAM) { + phpdbg_notice("Zend extensions"); + zend_llist_apply(&zend_extensions, (llist_apply_func_t) add_zendext_info TSRMLS_CC); + phpdbg_writeln(""); + phpdbg_notice("Modules"); + zend_hash_apply(&module_registry, (apply_func_t) add_extension_info TSRMLS_CC); + } else switch (param->type) { + case STR_PARAM: +#ifdef HAVE_LIBDL + path = estrndup(param->str, param->len); + + if ((type = phpdbg_load_module_or_extension(&path, &name TSRMLS_CC)) == NULL) { + phpdbg_error("Could not load %s, not found or invalid zend extension / module: %s", path, name); + efree(name); + } else { + phpdbg_notice("Successfully loaded the %s %s at path %s", type, name, path); + } + efree(path); +#else + phpdbg_error("Cannot dynamically load %.*s - dynamic modules are not supported", (int) param->len, param->str); +#endif + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + PHPDBG_COMMAND(source) /* {{{ */ { struct stat sb; @@ -991,6 +1193,50 @@ PHPDBG_COMMAND(watch) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_COMMAND(wait) /* {{{ */ +{ + struct sockaddr_un local, remote; + int rlen, len, sr, sl = socket(AF_UNIX, SOCK_STREAM, 0); + unlink(PHPDBG_G(socket_path)); + + local.sun_family = AF_UNIX; + strcpy(local.sun_path, PHPDBG_G(socket_path)); + len = strlen(local.sun_path) + sizeof(local.sun_family); + if (bind(sl, (struct sockaddr *)&local, len) == -1) { + phpdbg_error("Unable to connect to UNIX domain socket at %s defined by phpdbg.path ini setting", PHPDBG_G(socket_path)); + return FAILURE; + } + + chmod(PHPDBG_G(socket_path), 0666); + + listen(sl, 2); + + rlen = sizeof(remote); + sr = accept(sl, (struct sockaddr *) &remote, (socklen_t *) &rlen); + + char msglen[5]; + int recvd = 4; + + do { + recvd -= recv(sr, &(msglen[4 - recvd]), recvd, 0); + } while (recvd > 0); + + recvd = *(size_t *) msglen; + char *data = emalloc(recvd); + + do { + recvd -= recv(sr, &(data[(*(int *) msglen) - recvd]), recvd, 0); + } while (recvd > 0); + + phpdbg_webdata_decompress(data, *(int *) msglen TSRMLS_CC); + + efree(data); + + phpdbg_notice("Successfully imported request data, stopped before executing"); + + return SUCCESS; +} /* }}} */ + int phpdbg_interactive(TSRMLS_D) /* {{{ */ { int ret = SUCCESS; diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index ef648aabeb0..9c8c452669f 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -47,12 +47,14 @@ PHPDBG_COMMAND(clean); PHPDBG_COMMAND(clear); PHPDBG_COMMAND(help); PHPDBG_COMMAND(sh); +PHPDBG_COMMAND(dl); PHPDBG_COMMAND(set); PHPDBG_COMMAND(source); PHPDBG_COMMAND(export); PHPDBG_COMMAND(register); PHPDBG_COMMAND(quit); -PHPDBG_COMMAND(watch); /* }}} */ +PHPDBG_COMMAND(watch); +PHPDBG_COMMAND(wait); /* }}} */ /* {{{ prompt commands */ extern const phpdbg_command_t phpdbg_prompt_commands[]; /* }}} */ diff --git a/phpdbg_rinit_hook.c b/phpdbg_rinit_hook.c new file mode 100644 index 00000000000..d68fd9ac9af --- /dev/null +++ b/phpdbg_rinit_hook.c @@ -0,0 +1,88 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg_rinit_hook.h" +#include "php_ini.h" +#include + +ZEND_DECLARE_MODULE_GLOBALS(phpdbg_webhelper); + +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("phpdbg.auth", "", PHP_INI_SYSTEM | PHP_INI_PERDIR, OnUpdateString, auth, zend_phpdbg_webhelper_globals, phpdbg_webhelper_globals) + STD_PHP_INI_ENTRY("phpdbg.path", "", PHP_INI_SYSTEM | PHP_INI_PERDIR, OnUpdateString, path, zend_phpdbg_webhelper_globals, phpdbg_webhelper_globals) +PHP_INI_END() + +static inline void php_phpdbg_webhelper_globals_ctor(zend_phpdbg_webhelper_globals *pg) /* {{{ */ +{ +} /* }}} */ + +static PHP_MINIT_FUNCTION(phpdbg_webhelper) /* {{{ */ +{ + if (!strcmp(sapi_module.name, PHPDBG_NAME)) { + return SUCCESS; + } + + ZEND_INIT_MODULE_GLOBALS(phpdbg_webhelper, php_phpdbg_webhelper_globals_ctor, NULL); + REGISTER_INI_ENTRIES(); + + return SUCCESS; +} /* }}} */ + +static PHP_RINIT_FUNCTION(phpdbg_webhelper) /* {{{ */ +{ + zval *cookies = PG(http_globals)[TRACK_VARS_COOKIE]; + zval **auth; + + if (!cookies || zend_hash_find(Z_ARRVAL_P(cookies), PHPDBG_NAME "_AUTH_COOKIE", sizeof(PHPDBG_NAME "_AUTH_COOKIE"), (void **) &auth) == FAILURE || Z_STRLEN_PP(auth) != strlen(PHPDBG_WG(auth)) || strcmp(Z_STRVAL_PP(auth), PHPDBG_WG(auth))) { + return SUCCESS; + } + +#ifndef _WIN32 + struct sockaddr_un sock; + int s = socket(AF_UNIX, SOCK_STREAM, 0); + int len = strlen(PHPDBG_WG(path)) + sizeof(sock.sun_family); + sock.sun_family = AF_UNIX; + strcpy(sock.sun_path, PHPDBG_WG(path)); + + if (connect(s, (struct sockaddr *)&sock, len) == -1) { + zend_error(E_ERROR, "Unable to connect to UNIX domain socket at %s defined by phpdbg.path ini setting. Reason: %s", PHPDBG_WG(path), strerror(errno)); + } + + char *msg = NULL; + char msglen[5] = {0}; + phpdbg_webdata_compress(&msg, (int *)msglen TSRMLS_CC); + + send(s, msglen, 4, 0); + send(s, msg, *(int *) msglen, 0); +#endif + + return SUCCESS; +} /* }}} */ + +zend_module_entry phpdbg_webhelper_module_entry = { + STANDARD_MODULE_HEADER, + "phpdbg_webhelper", + NULL, + PHP_MINIT(phpdbg_webhelper), + NULL, + PHP_RINIT(phpdbg_webhelper), + NULL, + NULL, + PHPDBG_VERSION, + STANDARD_MODULE_PROPERTIES +}; diff --git a/phpdbg_rinit_hook.h b/phpdbg_rinit_hook.h new file mode 100644 index 00000000000..1c6e92971e8 --- /dev/null +++ b/phpdbg_rinit_hook.h @@ -0,0 +1,43 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_WEBHELPER_H +#define PHPDBG_WEBHELPER_H + +#define phpdbg_notice(...) + +#include "phpdbg_webdata_transfer.h" + +extern zend_module_entry phpdbg_webhelper_module_entry; +#define phpext_phpdbg_webhelper_ptr &phpdbg_webhelper_module_entry + +#ifdef ZTS +# define PHPDBG_WG(v) TSRMG(phpdbg_webhelper_globals_id, zend_phpdbg_webhelper_globals *, v) +#else +# define PHPDBG_WG(v) (phpdbg_webhelper_globals.v) +#endif + +/* {{{ structs */ +ZEND_BEGIN_MODULE_GLOBALS(phpdbg_webhelper) + char *auth; + char *path; +ZEND_END_MODULE_GLOBALS(phpdbg_webhelper) /* }}} */ + +#endif /* PHPDBG_WEBHELPER_H */ diff --git a/phpdbg_webdata_transfer.h b/phpdbg_webdata_transfer.h new file mode 100644 index 00000000000..4bcfb0c8e2e --- /dev/null +++ b/phpdbg_webdata_transfer.h @@ -0,0 +1,480 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_WEBDATA_TRANSFER_H +#define PHPDBG_WEBDATA_TRANSFER_H + +/* {{{ remote console headers */ +#ifndef _WIN32 +# include +# include +# include +# include +#endif /* }}} */ + +#include "zend.h" +#include "phpdbg.h" +#include "ext/json/php_json.h" +#include "ext/standard/basic_functions.h" + +static inline void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) { + smart_str buf = {0}; + zval array; + HashTable *ht; + /* I really need to change that to an array of zvals... */ + zval zv1, *zvp1 = &zv1; + zval zv2, *zvp2 = &zv2; + zval zv3, *zvp3 = &zv3; + zval zv4, *zvp4 = &zv4; + zval zv5, *zvp5 = &zv5; + zval zv6, *zvp6 = &zv6; + zval zv7, *zvp7 = &zv7; + zval zv8, *zvp8 = &zv8; + + array_init(&array); + ht = Z_ARRVAL(array); + + /* fetch superglobals */ + { + zend_is_auto_global(ZEND_STRL("GLOBALS") TSRMLS_CC); + /* might be JIT */ + zend_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC); + zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC); + zend_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC); + array_init(&zv1); + zend_hash_copy(Z_ARRVAL(zv1), &EG(symbol_table), NULL, (void *) NULL, sizeof(zval *)); + Z_ARRVAL(zv1)->pDestructor = NULL; /* we're operating on a copy! Don't double free zvals */ + zend_hash_del(Z_ARRVAL(zv1), "GLOBALS", sizeof("GLOBALS")); /* do not use the reference to itself in json */ + zend_hash_add(ht, "GLOBALS", sizeof("GLOBALS"), &zvp1, sizeof(zval *), NULL); + } + + /* save php://input */ + { + php_stream *stream; + int len; + char *contents; + + stream = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); + if ((len = php_stream_copy_to_mem(stream, &contents, PHP_STREAM_COPY_ALL, 0)) > 0) { + ZVAL_STRINGL(&zv2, contents, len, 0); + } else { + ZVAL_EMPTY_STRING(&zv2); + } + zend_hash_add(ht, "input", sizeof("input"), &zvp2, sizeof(zval *), NULL); + } + + /* change sapi name */ + { + if (sapi_module.name) { + ZVAL_STRING(&zv6, sapi_module.name, 1); + } else { + Z_TYPE(zv6) = IS_NULL; + } + zend_hash_add(ht, "sapi_name", sizeof("sapi_name"), &zvp6, sizeof(zval *), NULL); + } + + /* handle modules / extensions */ + { + HashPosition position; + zend_module_entry *module; + zend_extension *extension; + zend_llist_position pos; + + array_init(&zv7); + for (zend_hash_internal_pointer_reset_ex(&module_registry, &position); + zend_hash_get_current_data_ex(&module_registry, (void**) &module, &position) == SUCCESS; + zend_hash_move_forward_ex(&module_registry, &position)) { + zval **value = emalloc(sizeof(zval *)); + ALLOC_ZVAL(*value); + ZVAL_STRING(*value, module->name, 1); + zend_hash_next_index_insert(Z_ARRVAL(zv7), value, sizeof(zval *), NULL); + } + zend_hash_add(ht, "modules", sizeof("modules"), &zvp7, sizeof(zval *), NULL); + + array_init(&zv8); + extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos); + while (extension) { + zval **value = emalloc(sizeof(zval *)); + ALLOC_ZVAL(*value); + ZVAL_STRING(*value, extension->name, 1); + zend_hash_next_index_insert(Z_ARRVAL(zv8), value, sizeof(zval *), NULL); + extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos); + } + zend_hash_add(ht, "extensions", sizeof("extensions"), &zvp8, sizeof(zval *), NULL); + } + + /* switch cwd */ + { + char *ret = NULL; + char path[MAXPATHLEN]; + +#if HAVE_GETCWD + ret = VCWD_GETCWD(path, MAXPATHLEN); +#elif HAVE_GETWD + ret = VCWD_GETWD(path); +#endif + if (ret) { + ZVAL_STRING(&zv5, path, 1); + zend_hash_add(ht, "cwd", sizeof("cwd"), &zvp5, sizeof(zval *), NULL); + } + } + + /* get system ini entries */ + { + HashPosition position; + zend_ini_entry *ini_entry; + + array_init(&zv3); + for (zend_hash_internal_pointer_reset_ex(EG(ini_directives), &position); + zend_hash_get_current_data_ex(EG(ini_directives), (void**) &ini_entry, &position) == SUCCESS; + zend_hash_move_forward_ex(EG(ini_directives), &position)) { + zval **value = emalloc(sizeof(zval *)); + if (ini_entry->modified) { + if (!ini_entry->orig_value) { + efree(value); + continue; + } + ALLOC_ZVAL(*value); + ZVAL_STRINGL(*value, ini_entry->orig_value, ini_entry->orig_value_length, 1); + } else { + if (!ini_entry->value) { + efree(value); + continue; + } + ALLOC_ZVAL(*value); + ZVAL_STRINGL(*value, ini_entry->value, ini_entry->value_length, 1); + } + zend_hash_add(Z_ARRVAL(zv3), ini_entry->name, ini_entry->name_length, value, sizeof(zval *), NULL); + } + zend_hash_add(ht, "systemini", sizeof("systemini"), &zvp3, sizeof(zval *), NULL); + } + + /* get perdir ini entries */ + if (EG(modified_ini_directives)) { + HashPosition position; + zend_ini_entry *ini_entry; + + array_init(&zv4); + for (zend_hash_internal_pointer_reset_ex(EG(modified_ini_directives), &position); + zend_hash_get_current_data_ex(EG(modified_ini_directives), (void**) &ini_entry, &position) == SUCCESS; + zend_hash_move_forward_ex(EG(modified_ini_directives), &position)) { + zval **value = emalloc(sizeof(zval *)); + if (!ini_entry->value) { + efree(value); + continue; + } + ALLOC_ZVAL(*value); + ZVAL_STRINGL(*value, ini_entry->value, ini_entry->value_length, 1); + zend_hash_add(Z_ARRVAL(zv4), ini_entry->name, ini_entry->name_length, value, sizeof(zval *), NULL); + } + zend_hash_add(ht, "userini", sizeof("userini"), &zvp4, sizeof(zval *), NULL); + } + + /* encode data */ + php_json_encode(&buf, &array, 0 TSRMLS_CC); + *msg = buf.c; + *len = buf.len; + zval_dtor(&array); +} + +static void phpdbg_rebuild_http_globals_array(int type, const char *name TSRMLS_DC) { + zval **zvpp; + if (PG(http_globals)[type]) { + zval_dtor(PG(http_globals)[type]); + } + if (zend_hash_find(&EG(symbol_table), name, strlen(name) + 1, (void **) &zvpp) == SUCCESS) { + Z_SET_REFCOUNT_PP(zvpp, 2); + PG(http_globals)[type] = *zvpp; + } +} + +/* +static int phpdbg_remove_rearm_autoglobals(zend_auto_global *auto_global TSRMLS_DC) { +// zend_hash_del(&EG(symbol_table), auto_global->name, auto_global->name_len + 1); + + return 1; +}*/ + +typedef struct { + HashTable *ht[2]; + HashPosition pos[2]; +} phpdbg_intersect_ptr; + +static void phpdbg_array_intersect_init(phpdbg_intersect_ptr *info, HashTable *ht1, HashTable *ht2 TSRMLS_DC) { + info->ht[0] = ht1; + info->ht[1] = ht2; + + zend_hash_sort(info->ht[0], zend_qsort, (compare_func_t) string_compare_function, 0 TSRMLS_CC); + zend_hash_sort(info->ht[1], zend_qsort, (compare_func_t) string_compare_function, 0 TSRMLS_CC); + + zend_hash_internal_pointer_reset_ex(info->ht[0], &info->pos[0]); + zend_hash_internal_pointer_reset_ex(info->ht[1], &info->pos[1]); +} + +/* -1 => first array, 0 => both arrays equal, 1 => second array */ +static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) { + int ret; + zval **zvpp[2]; + int invalid = !info->ht[0] + !info->ht[1]; + + if (invalid > 0) { + invalid = !!info->ht[0]; + + if (zend_hash_get_current_data_ex(info->ht[invalid], (void **) ptr, &info->pos[invalid]) == FAILURE) { + *ptr = NULL; + return 0; + } + + zend_hash_move_forward_ex(info->ht[invalid], &info->pos[invalid]); + + return invalid ? -1 : 1; + } + + if (zend_hash_get_current_data_ex(info->ht[0], (void **) &zvpp[0], &info->pos[0]) == FAILURE) { + info->ht[0] = NULL; + return phpdbg_array_intersect(info, ptr); + } + if (zend_hash_get_current_data_ex(info->ht[1], (void **) &zvpp[1], &info->pos[1]) == FAILURE) { + info->ht[1] = NULL; + return phpdbg_array_intersect(info, ptr); + } + + ret = zend_binary_zval_strcmp(*zvpp[0], *zvpp[1]); + + if (ret <= 0) { + *ptr = zvpp[0]; + zend_hash_move_forward_ex(info->ht[0], &info->pos[0]); + } + if (ret >= 0) { + *ptr = zvpp[1]; + zend_hash_move_forward_ex(info->ht[1], &info->pos[1]); + } + + return ret; +} + +static inline void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { + zval *free_zv = NULL; + zval zv, **zvpp; + HashTable *ht; + php_json_decode(&zv, msg, len, 1, 1000 /* enough */ TSRMLS_CC); + ht = Z_ARRVAL(zv); + + /* Reapply symbol table */ + if (zend_hash_find(ht, "GLOBALS", sizeof("GLOBALS"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + zend_hash_clean(&EG(symbol_table)); + EG(symbol_table) = *Z_ARRVAL_PP(zvpp); + + /* Rebuild cookies, env vars etc. from GLOBALS (PG(http_globals)) */ + phpdbg_rebuild_http_globals_array(TRACK_VARS_POST, "_POST" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_GET, "_GET" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_COOKIE, "_COOKIE" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_SERVER, "_SERVER" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_ENV, "_ENV" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_FILES, "_FILES" TSRMLS_CC); + + Z_ADDREF_PP(zvpp); + free_zv = *zvpp; + } + + if (zend_hash_find(ht, "input", sizeof("input"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) { + if (SG(request_info).request_body) { + php_stream_close(SG(request_info).request_body); + } + SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); + php_stream_truncate_set_size(SG(request_info).request_body, 0); + php_stream_write(SG(request_info).request_body, Z_STRVAL_PP(zvpp), Z_STRLEN_PP(zvpp)); + } + + if (zend_hash_find(ht, "cwd", sizeof("cwd"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) { + if (VCWD_CHDIR(Z_STRVAL_PP(zvpp)) == SUCCESS) { + if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) { + efree(BG(CurrentStatFile)); + BG(CurrentStatFile) = NULL; + } + if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) { + efree(BG(CurrentLStatFile)); + BG(CurrentLStatFile) = NULL; + } + } + } + + if (zend_hash_find(ht, "sapi_name", sizeof("sapi_name"), (void **) &zvpp) == SUCCESS && (Z_TYPE_PP(zvpp) == IS_STRING || Z_TYPE_PP(zvpp) == IS_NULL)) { + if (sapi_module.name) { + efree(sapi_module.name); + } + if (Z_TYPE_PP(zvpp) == IS_STRING) { + sapi_module.name = estrndup(Z_STRVAL_PP(zvpp), Z_STRLEN_PP(zvpp)); + } else { + sapi_module.name = NULL; + } + } + + if (zend_hash_find(ht, "modules", sizeof("modules"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + HashPosition position; + phpdbg_intersect_ptr pos; + zval **module; + zend_module_entry *mod; + HashTable zv_registry; + + /* intersect modules, unregister mpdules loaded "too much", announce not yet registered modules (phpdbg_notice) */ + + zend_hash_init(&zv_registry, zend_hash_num_elements(&zv_registry), 0, ZVAL_PTR_DTOR, 0); + for (zend_hash_internal_pointer_reset_ex(&module_registry, &position); + zend_hash_get_current_data_ex(&module_registry, (void **) &mod, &position) == SUCCESS; + zend_hash_move_forward_ex(&module_registry, &position)) { + zval **value = emalloc(sizeof(zval *)); + ALLOC_ZVAL(*value); + ZVAL_STRING(*value, mod->name, 1); + zend_hash_next_index_insert(&zv_registry, value, sizeof(zval *), NULL); + } + + phpdbg_array_intersect_init(&pos, &zv_registry, Z_ARRVAL_PP(zvpp) TSRMLS_CC); + do { + int mode = phpdbg_array_intersect(&pos, &module); + if (mode < 0) { + // loaded module, but not needed + zend_hash_del(&module_registry, Z_STRVAL_PP(module), Z_STRLEN_PP(module) + 1); + } else if (mode > 0) { + // not loaded module + phpdbg_notice("The module %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/module.so", Z_STRLEN_PP(module), Z_STRVAL_PP(module)); + } + } while (module); + + zend_hash_clean(&zv_registry); + } + + if (zend_hash_find(ht, "extensions", sizeof("extensions"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + zend_extension *extension; + zend_llist_position pos; + HashPosition hpos; + zval **name, key; + + extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos); + while (extension) { + extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos); + + /* php_serach_array() body should be in some ZEND_API function */ + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &hpos); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &name, &hpos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &hpos)) { + if (Z_TYPE_PP(name) == IS_STRING && !zend_binary_strcmp(extension->name, strlen(extension->name), Z_STRVAL_PP(name), Z_STRLEN_PP(name))) { + break; + } + } + + if (zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &zvpp, &hpos) == FAILURE) { + /* sigh, breaking the encapsulation, there aren't any functions manipulating the llist at the place of the zend_llist_position */ + zend_llist_element *elm = pos; + if (elm->prev) { + elm->prev->next = elm->next; + } else { + zend_extensions.head = elm->next; + } + if (elm->next) { + elm->next->prev = elm->prev; + } else { + zend_extensions.tail = elm->prev; + } +#if ZEND_EXTENSIONS_SUPPORT + if (extension->shutdown) { + extension->shutdown(extension); + } +#endif + if (zend_extensions.dtor) { + zend_extensions.dtor(elm->data); + } + pefree(elm, zend_extensions.persistent); + zend_extensions.count--; + } else { + zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &hpos); + if (Z_TYPE(key) == IS_LONG) { + zend_hash_index_del(Z_ARRVAL_PP(zvpp), Z_LVAL(key)); + } + } + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &hpos); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &name, &hpos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &hpos)) { + phpdbg_notice("The (zend) extension %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/extension.so", Z_STRLEN_PP(name), Z_STRVAL_PP(name)); + } + } + } + + zend_ini_deactivate(TSRMLS_C); + + if (zend_hash_find(ht, "systemini", sizeof("systemini"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + HashPosition position; + zval **ini_entry; + zend_ini_entry *original_ini; + zval key; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &position); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void**) &ini_entry, &position) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &position)) { + zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &position); + if (Z_TYPE(key) == IS_STRING) { + if (Z_TYPE_PP(ini_entry) == IS_STRING) { + if (zend_hash_find(EG(ini_directives), Z_STRVAL(key), Z_STRLEN(key) + 1, (void **) &original_ini) == SUCCESS) { + if (!original_ini->on_modify || original_ini->on_modify(original_ini, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), original_ini->mh_arg1, original_ini->mh_arg2, original_ini->mh_arg3, ZEND_INI_STAGE_ACTIVATE TSRMLS_CC) == SUCCESS) { + original_ini->value = Z_STRVAL_PP(ini_entry); + original_ini->value_length = Z_STRLEN_PP(ini_entry); + continue; /* don't free the string */ + } + } + } + efree(Z_STRVAL(key)); + } + } + } + + if (zend_hash_find(ht, "userini", sizeof("userini"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + HashPosition position; + zval **ini_entry; + zval key; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &position); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void**) &ini_entry, &position) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &position)) { + zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &position); + if (Z_TYPE(key) == IS_STRING) { + if (Z_TYPE_PP(ini_entry) == IS_STRING) { + zend_alter_ini_entry_ex(Z_STRVAL(key), Z_STRLEN(key) + 1, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), ZEND_INI_PERDIR, ZEND_INI_STAGE_HTACCESS, 1 TSRMLS_CC); + } + efree(Z_STRVAL(key)); + } + } + } + + zval_dtor(&zv); + if (free_zv) { + /* separate freeing to not dtor the symtable too, just the container zval... */ + efree(free_zv); + } + + /* Remove and readd autoglobals */ +/* php_hash_environment(TSRMLS_C); + zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_remove_rearm_autoglobals TSRMLS_CC); + php_startup_auto_globals(TSRMLS_C); + zend_activate_auto_globals(TSRMLS_C); +*/ + /* Reapply raw input */ + /* ??? */ +} + +#endif /* PHPDBG_WEBDATA_TRANSFER_H */ From 554b30389e854270eca46359a72b9d5c177c3dc0 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 10 Sep 2014 15:53:40 +0200 Subject: [PATCH 002/125] Fix segfaults, reorder files and set filename to exec --- config.m4 | 4 +- phpdbg.c | 12 +- phpdbg.h | 11 +- phpdbg_prompt.c | 50 +---- phpdbg_rinit_hook.h | 2 - phpdbg_wait.c | 392 ++++++++++++++++++++++++++++++++ phpdbg_wait.h | 29 +++ phpdbg_webdata_transfer.c | 180 +++++++++++++++ phpdbg_webdata_transfer.h | 455 +------------------------------------- 9 files changed, 625 insertions(+), 510 deletions(-) create mode 100644 phpdbg_wait.c create mode 100644 phpdbg_wait.h create mode 100644 phpdbg_webdata_transfer.c diff --git a/config.m4 b/config.m4 index 06c7ee098a4..a589c320184 100644 --- a/config.m4 +++ b/config.m4 @@ -26,14 +26,14 @@ if test "$BUILD_PHPDBG" == "" && test "$PHP_PHPDBG" != "no"; then ln -s ../sapi/phpdbg ext/phpdbg_webhelper fi if test "$PHP_JSON" != "no"; then - PHP_NEW_EXTENSION(phpdbg_webhelper, phpdbg_rinit_hook.c, $ext_shared) + PHP_NEW_EXTENSION(phpdbg_webhelper, phpdbg_rinit_hook.c phpdbg_webdata_transfer.c, $ext_shared) else AC_MSG_ERROR(Webhelper extension of phpdbg needs json enabled) fi fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_wait.c" if test "$PHP_READLINE" != "no" -o "$PHP_LIBEDIT" != "no"; then PHPDBG_EXTRA_LIBS="$PHP_READLINE_LIBS" diff --git a/phpdbg.c b/phpdbg.c index 15da7196b50..e4868879fdb 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -76,6 +76,8 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->io[PHPDBG_STDOUT] = NULL; pg->io[PHPDBG_STDERR] = NULL; pg->frame.num = 0; + + pg->sapi_name_ptr = NULL; } /* }}} */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ @@ -192,7 +194,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ efree(PHPDBG_G(buffer)); PHPDBG_G(buffer) = NULL; } - + if (PHPDBG_G(exec)) { efree(PHPDBG_G(exec)); PHPDBG_G(exec) = NULL; @@ -1283,6 +1285,8 @@ phpdbg_main: sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); #endif + PHPDBG_G(sapi_name_ptr) = sapi_name; + if (php_request_startup(TSRMLS_C) == SUCCESS) { int i; @@ -1516,10 +1520,10 @@ phpdbg_out: } #endif - if (sapi_name) { - free(sapi_name); + if (PHPDBG_G(sapi_name_ptr)) { + free(PHPDBG_G(sapi_name_ptr)); } - + #ifdef _WIN32 free(bp_tmp_file); #else diff --git a/phpdbg.h b/phpdbg.h index cf47cfc1e4e..7ee0b44afd8 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -72,6 +72,14 @@ # include #endif +/* {{{ remote console headers */ +#ifndef _WIN32 +# include +# include +# include +# include +#endif /* }}} */ + /* {{{ strings */ #define PHPDBG_NAME "phpdbg" #define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */ @@ -81,7 +89,7 @@ #define PHPDBG_INIT_FILENAME ".phpdbginit" /* }}} */ -#ifndef PHPDBG_WEBHELPER_H +#if !defined(PHPDBG_WEBDATA_TRANSFER_H) && !defined(PHPDBG_WEBHELPER_H) #include "phpdbg_lexer.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" @@ -213,6 +221,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) zend_ulong flags; /* phpdbg flags */ char *socket_path; /* phpdbg.path ini setting */ + char *sapi_name_ptr; /* store sapi name to free it if necessary to not leak memory */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ /* the beginning (= the important part) of the _zend_mm_heap struct defined in Zend/zend_alloc.c diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 2940d0a1560..e38a172c468 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -24,8 +24,6 @@ #include "zend_compile.h" #include "phpdbg.h" -ZEND_EXTERN_MODULE_GLOBALS(phpdbg); - #include "phpdbg_help.h" #include "phpdbg_print.h" #include "phpdbg_info.h" @@ -40,7 +38,9 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); #include "phpdbg_frame.h" #include "phpdbg_lexer.h" #include "phpdbg_parser.h" -#include "phpdbg_webdata_transfer.h" +#include "phpdbg_wait.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); #ifdef HAVE_LIBDL #ifdef PHP_WIN32 @@ -1193,50 +1193,6 @@ PHPDBG_COMMAND(watch) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_COMMAND(wait) /* {{{ */ -{ - struct sockaddr_un local, remote; - int rlen, len, sr, sl = socket(AF_UNIX, SOCK_STREAM, 0); - unlink(PHPDBG_G(socket_path)); - - local.sun_family = AF_UNIX; - strcpy(local.sun_path, PHPDBG_G(socket_path)); - len = strlen(local.sun_path) + sizeof(local.sun_family); - if (bind(sl, (struct sockaddr *)&local, len) == -1) { - phpdbg_error("Unable to connect to UNIX domain socket at %s defined by phpdbg.path ini setting", PHPDBG_G(socket_path)); - return FAILURE; - } - - chmod(PHPDBG_G(socket_path), 0666); - - listen(sl, 2); - - rlen = sizeof(remote); - sr = accept(sl, (struct sockaddr *) &remote, (socklen_t *) &rlen); - - char msglen[5]; - int recvd = 4; - - do { - recvd -= recv(sr, &(msglen[4 - recvd]), recvd, 0); - } while (recvd > 0); - - recvd = *(size_t *) msglen; - char *data = emalloc(recvd); - - do { - recvd -= recv(sr, &(data[(*(int *) msglen) - recvd]), recvd, 0); - } while (recvd > 0); - - phpdbg_webdata_decompress(data, *(int *) msglen TSRMLS_CC); - - efree(data); - - phpdbg_notice("Successfully imported request data, stopped before executing"); - - return SUCCESS; -} /* }}} */ - int phpdbg_interactive(TSRMLS_D) /* {{{ */ { int ret = SUCCESS; diff --git a/phpdbg_rinit_hook.h b/phpdbg_rinit_hook.h index 1c6e92971e8..d28be10f8c4 100644 --- a/phpdbg_rinit_hook.h +++ b/phpdbg_rinit_hook.h @@ -21,8 +21,6 @@ #ifndef PHPDBG_WEBHELPER_H #define PHPDBG_WEBHELPER_H -#define phpdbg_notice(...) - #include "phpdbg_webdata_transfer.h" extern zend_module_entry phpdbg_webhelper_module_entry; diff --git a/phpdbg_wait.c b/phpdbg_wait.c new file mode 100644 index 00000000000..d369dedf106 --- /dev/null +++ b/phpdbg_wait.c @@ -0,0 +1,392 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg_wait.h" +#include "phpdbg_prompt.h" +#include "ext/json/php_json.h" +#include "ext/standard/basic_functions.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +static void phpdbg_rebuild_http_globals_array(int type, const char *name TSRMLS_DC) { + zval **zvpp; + if (PG(http_globals)[type]) { + zval_dtor(PG(http_globals)[type]); + } + if (zend_hash_find(&EG(symbol_table), name, strlen(name) + 1, (void **) &zvpp) == SUCCESS) { + Z_SET_REFCOUNT_PP(zvpp, 2); + PG(http_globals)[type] = *zvpp; + } +} + +/* +static int phpdbg_remove_rearm_autoglobals(zend_auto_global *auto_global TSRMLS_DC) { +// zend_hash_del(&EG(symbol_table), auto_global->name, auto_global->name_len + 1); + + return 1; +}*/ + +typedef struct { + HashTable *ht[2]; + HashPosition pos[2]; +} phpdbg_intersect_ptr; + +static int phpdbg_array_data_compare(const void *a, const void *b TSRMLS_DC) { + Bucket *f, *s; + zval result; + zval *first, *second; + + f = *((Bucket **) a); + s = *((Bucket **) b); + + first = *((zval **) f->pData); + second = *((zval **) s->pData); + + if (string_compare_function(&result, first, second TSRMLS_CC) == FAILURE) { + return 0; + } + + if (Z_LVAL(result) < 0) { + return -1; + } else if (Z_LVAL(result) > 0) { + return 1; + } + + return 0; +} + +static void phpdbg_array_intersect_init(phpdbg_intersect_ptr *info, HashTable *ht1, HashTable *ht2 TSRMLS_DC) { + info->ht[0] = ht1; + info->ht[1] = ht2; + + zend_hash_sort(info->ht[0], zend_qsort, (compare_func_t) phpdbg_array_data_compare, 0 TSRMLS_CC); + zend_hash_sort(info->ht[1], zend_qsort, (compare_func_t) phpdbg_array_data_compare, 0 TSRMLS_CC); + + zend_hash_internal_pointer_reset_ex(info->ht[0], &info->pos[0]); + zend_hash_internal_pointer_reset_ex(info->ht[1], &info->pos[1]); +} + +/* -1 => first array, 0 => both arrays equal, 1 => second array */ +static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) { + int ret; + zval **zvpp[2]; + int invalid = !info->ht[0] + !info->ht[1]; + + if (invalid > 0) { + invalid = !info->ht[0]; + + if (zend_hash_get_current_data_ex(info->ht[invalid], (void **) ptr, &info->pos[invalid]) == FAILURE) { + *ptr = NULL; + return 0; + } + + zend_hash_move_forward_ex(info->ht[invalid], &info->pos[invalid]); + + return invalid ? -1 : 1; + } + + if (zend_hash_get_current_data_ex(info->ht[0], (void **) &zvpp[0], &info->pos[0]) == FAILURE) { + info->ht[0] = NULL; + return phpdbg_array_intersect(info, ptr); + } + if (zend_hash_get_current_data_ex(info->ht[1], (void **) &zvpp[1], &info->pos[1]) == FAILURE) { + info->ht[1] = NULL; + return phpdbg_array_intersect(info, ptr); + } + + ret = zend_binary_zval_strcmp(*zvpp[0], *zvpp[1]); + + if (ret <= 0) { + *ptr = zvpp[0]; + zend_hash_move_forward_ex(info->ht[0], &info->pos[0]); + } + if (ret >= 0) { + *ptr = zvpp[1]; + zend_hash_move_forward_ex(info->ht[1], &info->pos[1]); + } + + return ret; +} + +void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { + zval *free_zv = NULL; + zval zv, **zvpp; + HashTable *ht; + php_json_decode(&zv, msg, len, 1, 1000 /* enough */ TSRMLS_CC); + ht = Z_ARRVAL(zv); + + /* Reapply symbol table */ + if (zend_hash_find(ht, "GLOBALS", sizeof("GLOBALS"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + zend_hash_clean(&EG(symbol_table)); + EG(symbol_table) = *Z_ARRVAL_PP(zvpp); + + { + zval **srv; + if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &srv) == SUCCESS && Z_TYPE_PP(srv) == IS_ARRAY) { + zval **script; + if (zend_hash_find(Z_ARRVAL_PP(srv), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &script) == SUCCESS && Z_TYPE_PP(script) == IS_STRING) { + phpdbg_param_t param; + param.str = Z_STRVAL_PP(script); + PHPDBG_COMMAND_HANDLER(exec)(¶m TSRMLS_CC); + } + } + } + + /* Rebuild cookies, env vars etc. from GLOBALS (PG(http_globals)) */ + phpdbg_rebuild_http_globals_array(TRACK_VARS_POST, "_POST" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_GET, "_GET" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_COOKIE, "_COOKIE" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_SERVER, "_SERVER" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_ENV, "_ENV" TSRMLS_CC); + phpdbg_rebuild_http_globals_array(TRACK_VARS_FILES, "_FILES" TSRMLS_CC); + + Z_ADDREF_PP(zvpp); + free_zv = *zvpp; + } + + if (zend_hash_find(ht, "input", sizeof("input"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) { + if (SG(request_info).request_body) { + php_stream_close(SG(request_info).request_body); + } + SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); + php_stream_truncate_set_size(SG(request_info).request_body, 0); + php_stream_write(SG(request_info).request_body, Z_STRVAL_PP(zvpp), Z_STRLEN_PP(zvpp)); + } + + if (zend_hash_find(ht, "cwd", sizeof("cwd"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) { + if (VCWD_CHDIR(Z_STRVAL_PP(zvpp)) == SUCCESS) { + if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) { + efree(BG(CurrentStatFile)); + BG(CurrentStatFile) = NULL; + } + if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) { + efree(BG(CurrentLStatFile)); + BG(CurrentLStatFile) = NULL; + } + } + } + + if (zend_hash_find(ht, "sapi_name", sizeof("sapi_name"), (void **) &zvpp) == SUCCESS && (Z_TYPE_PP(zvpp) == IS_STRING || Z_TYPE_PP(zvpp) == IS_NULL)) { + if (PHPDBG_G(sapi_name_ptr)) { + free(PHPDBG_G(sapi_name_ptr)); + } + if (Z_TYPE_PP(zvpp) == IS_STRING) { + PHPDBG_G(sapi_name_ptr) = sapi_module.name = strdup(Z_STRVAL_PP(zvpp)); + } else { + PHPDBG_G(sapi_name_ptr) = sapi_module.name = NULL; + } + } + + if (zend_hash_find(ht, "modules", sizeof("modules"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + HashPosition position; + phpdbg_intersect_ptr pos; + zval **module; + zend_module_entry *mod; + HashTable zv_registry; + + /* intersect modules, unregister modules loaded "too much", announce not yet registered modules (phpdbg_notice) */ + + zend_hash_init(&zv_registry, zend_hash_num_elements(&module_registry), 0, ZVAL_PTR_DTOR, 0); + for (zend_hash_internal_pointer_reset_ex(&module_registry, &position); + zend_hash_get_current_data_ex(&module_registry, (void **) &mod, &position) == SUCCESS; + zend_hash_move_forward_ex(&module_registry, &position)) { + if (mod->name && (!sapi_module.name || strcmp(sapi_module.name, mod->name))) { + zval **value = emalloc(sizeof(zval *)); + MAKE_STD_ZVAL(*value); + ZVAL_STRING(*value, mod->name, 1); + zend_hash_next_index_insert(&zv_registry, value, sizeof(zval *), NULL); + } + } + + phpdbg_array_intersect_init(&pos, &zv_registry, Z_ARRVAL_PP(zvpp) TSRMLS_CC); + do { + int mode = phpdbg_array_intersect(&pos, &module); + if (mode < 0) { + // loaded module, but not needed + zend_hash_del(&module_registry, Z_STRVAL_PP(module), Z_STRLEN_PP(module) + 1); + } else if (mode > 0) { + // not loaded module + phpdbg_notice("The module %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/module.so", Z_STRLEN_PP(module), Z_STRVAL_PP(module)); + } + } while (module); + + zend_hash_clean(&zv_registry); + } + + if (zend_hash_find(ht, "extensions", sizeof("extensions"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + zend_extension *extension; + zend_llist_position pos; + HashPosition hpos; + zval **name, key; + + extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos); + while (extension) { + extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos); + + /* php_serach_array() body should be in some ZEND_API function */ + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &hpos); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &name, &hpos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &hpos)) { + if (Z_TYPE_PP(name) == IS_STRING && !zend_binary_strcmp(extension->name, strlen(extension->name), Z_STRVAL_PP(name), Z_STRLEN_PP(name))) { + break; + } + } + + if (zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &zvpp, &hpos) == FAILURE) { + /* sigh, breaking the encapsulation, there aren't any functions manipulating the llist at the place of the zend_llist_position */ + zend_llist_element *elm = pos; + if (elm->prev) { + elm->prev->next = elm->next; + } else { + zend_extensions.head = elm->next; + } + if (elm->next) { + elm->next->prev = elm->prev; + } else { + zend_extensions.tail = elm->prev; + } +#if ZEND_EXTENSIONS_SUPPORT + if (extension->shutdown) { + extension->shutdown(extension); + } +#endif + if (zend_extensions.dtor) { + zend_extensions.dtor(elm->data); + } + pefree(elm, zend_extensions.persistent); + zend_extensions.count--; + } else { + zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &hpos); + if (Z_TYPE(key) == IS_LONG) { + zend_hash_index_del(Z_ARRVAL_PP(zvpp), Z_LVAL(key)); + } + } + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &hpos); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &name, &hpos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &hpos)) { + phpdbg_notice("The (zend) extension %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/extension.so", Z_STRLEN_PP(name), Z_STRVAL_PP(name)); + } + } + } + + zend_ini_deactivate(TSRMLS_C); + + if (zend_hash_find(ht, "systemini", sizeof("systemini"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + HashPosition position; + zval **ini_entry; + zend_ini_entry *original_ini; + zval key; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &position); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void**) &ini_entry, &position) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &position)) { + zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &position); + if (Z_TYPE(key) == IS_STRING) { + if (Z_TYPE_PP(ini_entry) == IS_STRING) { + if (zend_hash_find(EG(ini_directives), Z_STRVAL(key), Z_STRLEN(key) + 1, (void **) &original_ini) == SUCCESS) { + if (!original_ini->on_modify || original_ini->on_modify(original_ini, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), original_ini->mh_arg1, original_ini->mh_arg2, original_ini->mh_arg3, ZEND_INI_STAGE_ACTIVATE TSRMLS_CC) == SUCCESS) { + original_ini->value = Z_STRVAL_PP(ini_entry); + original_ini->value_length = Z_STRLEN_PP(ini_entry); + continue; /* don't free the string */ + } + } + } + efree(Z_STRVAL(key)); + } + } + } + + if (zend_hash_find(ht, "userini", sizeof("userini"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { + HashPosition position; + zval **ini_entry; + zval key; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &position); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void**) &ini_entry, &position) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &position)) { + zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &position); + if (Z_TYPE(key) == IS_STRING) { + if (Z_TYPE_PP(ini_entry) == IS_STRING) { + zend_alter_ini_entry_ex(Z_STRVAL(key), Z_STRLEN(key) + 1, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), ZEND_INI_PERDIR, ZEND_INI_STAGE_HTACCESS, 1 TSRMLS_CC); + } + efree(Z_STRVAL(key)); + } + } + } + + zval_dtor(&zv); + if (free_zv) { + /* separate freeing to not dtor the symtable too, just the container zval... */ + efree(free_zv); + } + + /* Remove and readd autoglobals */ +/* php_hash_environment(TSRMLS_C); + zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_remove_rearm_autoglobals TSRMLS_CC); + php_startup_auto_globals(TSRMLS_C); + zend_activate_auto_globals(TSRMLS_C); +*/ + /* Reapply raw input */ + /* ??? */ +} + +PHPDBG_COMMAND(wait) /* {{{ */ +{ + struct sockaddr_un local, remote; + int rlen, len, sr, sl = socket(AF_UNIX, SOCK_STREAM, 0); + unlink(PHPDBG_G(socket_path)); + + local.sun_family = AF_UNIX; + strcpy(local.sun_path, PHPDBG_G(socket_path)); + len = strlen(local.sun_path) + sizeof(local.sun_family); + if (bind(sl, (struct sockaddr *)&local, len) == -1) { + phpdbg_error("Unable to connect to UNIX domain socket at %s defined by phpdbg.path ini setting", PHPDBG_G(socket_path)); + return FAILURE; + } + + chmod(PHPDBG_G(socket_path), 0666); + + listen(sl, 2); + + rlen = sizeof(remote); + sr = accept(sl, (struct sockaddr *) &remote, (socklen_t *) &rlen); + + char msglen[5]; + int recvd = 4; + + do { + recvd -= recv(sr, &(msglen[4 - recvd]), recvd, 0); + } while (recvd > 0); + + recvd = *(size_t *) msglen; + char *data = emalloc(recvd); + + do { + recvd -= recv(sr, &(data[(*(int *) msglen) - recvd]), recvd, 0); + } while (recvd > 0); + + phpdbg_webdata_decompress(data, *(int *) msglen TSRMLS_CC); + + efree(data); + + phpdbg_notice("Successfully imported request data, stopped before executing"); + + return SUCCESS; +} /* }}} */ + diff --git a/phpdbg_wait.h b/phpdbg_wait.h new file mode 100644 index 00000000000..7cf95919ccb --- /dev/null +++ b/phpdbg_wait.h @@ -0,0 +1,29 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_WAIT_H +#define PHPDBG_WAIT_H + +#include "zend.h" +#include "phpdbg.h" + +PHPDBG_COMMAND(wait); + +void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC); + +#endif /* PHPDBG_WAIT_H */ diff --git a/phpdbg_webdata_transfer.c b/phpdbg_webdata_transfer.c new file mode 100644 index 00000000000..49782e59e2d --- /dev/null +++ b/phpdbg_webdata_transfer.c @@ -0,0 +1,180 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg_webdata_transfer.h" +#include "ext/json/php_json.h" + +PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) { + smart_str buf = {0}; + zval array; + HashTable *ht; + /* I really need to change that to an array of zvals... */ + zval zv1, *zvp1 = &zv1; + zval zv2, *zvp2 = &zv2; + zval zv3, *zvp3 = &zv3; + zval zv4, *zvp4 = &zv4; + zval zv5, *zvp5 = &zv5; + zval zv6, *zvp6 = &zv6; + zval zv7, *zvp7 = &zv7; + zval zv8, *zvp8 = &zv8; + + array_init(&array); + ht = Z_ARRVAL(array); + + /* fetch superglobals */ + { + zend_is_auto_global(ZEND_STRL("GLOBALS") TSRMLS_CC); + /* might be JIT */ + zend_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC); + zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC); + zend_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC); + array_init(&zv1); + zend_hash_copy(Z_ARRVAL(zv1), &EG(symbol_table), NULL, (void *) NULL, sizeof(zval *)); + Z_ARRVAL(zv1)->pDestructor = NULL; /* we're operating on a copy! Don't double free zvals */ + zend_hash_del(Z_ARRVAL(zv1), "GLOBALS", sizeof("GLOBALS")); /* do not use the reference to itself in json */ + zend_hash_add(ht, "GLOBALS", sizeof("GLOBALS"), &zvp1, sizeof(zval *), NULL); + } + + /* save php://input */ + { + php_stream *stream; + int len; + char *contents; + + stream = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); + if ((len = php_stream_copy_to_mem(stream, &contents, PHP_STREAM_COPY_ALL, 0)) > 0) { + ZVAL_STRINGL(&zv2, contents, len, 0); + } else { + ZVAL_EMPTY_STRING(&zv2); + } + zend_hash_add(ht, "input", sizeof("input"), &zvp2, sizeof(zval *), NULL); + } + + /* change sapi name */ + { + if (sapi_module.name) { + ZVAL_STRING(&zv6, sapi_module.name, 1); + } else { + Z_TYPE(zv6) = IS_NULL; + } + zend_hash_add(ht, "sapi_name", sizeof("sapi_name"), &zvp6, sizeof(zval *), NULL); + } + + /* handle modules / extensions */ + { + HashPosition position; + zend_module_entry *module; + zend_extension *extension; + zend_llist_position pos; + + array_init(&zv7); + for (zend_hash_internal_pointer_reset_ex(&module_registry, &position); + zend_hash_get_current_data_ex(&module_registry, (void**) &module, &position) == SUCCESS; + zend_hash_move_forward_ex(&module_registry, &position)) { + zval **value = emalloc(sizeof(zval *)); + ALLOC_ZVAL(*value); + ZVAL_STRING(*value, module->name, 1); + zend_hash_next_index_insert(Z_ARRVAL(zv7), value, sizeof(zval *), NULL); + } + zend_hash_add(ht, "modules", sizeof("modules"), &zvp7, sizeof(zval *), NULL); + + array_init(&zv8); + extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos); + while (extension) { + zval **value = emalloc(sizeof(zval *)); + ALLOC_ZVAL(*value); + ZVAL_STRING(*value, extension->name, 1); + zend_hash_next_index_insert(Z_ARRVAL(zv8), value, sizeof(zval *), NULL); + extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos); + } + zend_hash_add(ht, "extensions", sizeof("extensions"), &zvp8, sizeof(zval *), NULL); + } + + /* switch cwd */ + { + char *ret = NULL; + char path[MAXPATHLEN]; + +#if HAVE_GETCWD + ret = VCWD_GETCWD(path, MAXPATHLEN); +#elif HAVE_GETWD + ret = VCWD_GETWD(path); +#endif + if (ret) { + ZVAL_STRING(&zv5, path, 1); + zend_hash_add(ht, "cwd", sizeof("cwd"), &zvp5, sizeof(zval *), NULL); + } + } + + /* get system ini entries */ + { + HashPosition position; + zend_ini_entry *ini_entry; + + array_init(&zv3); + for (zend_hash_internal_pointer_reset_ex(EG(ini_directives), &position); + zend_hash_get_current_data_ex(EG(ini_directives), (void**) &ini_entry, &position) == SUCCESS; + zend_hash_move_forward_ex(EG(ini_directives), &position)) { + zval **value = emalloc(sizeof(zval *)); + if (ini_entry->modified) { + if (!ini_entry->orig_value) { + efree(value); + continue; + } + ALLOC_ZVAL(*value); + ZVAL_STRINGL(*value, ini_entry->orig_value, ini_entry->orig_value_length, 1); + } else { + if (!ini_entry->value) { + efree(value); + continue; + } + ALLOC_ZVAL(*value); + ZVAL_STRINGL(*value, ini_entry->value, ini_entry->value_length, 1); + } + zend_hash_add(Z_ARRVAL(zv3), ini_entry->name, ini_entry->name_length, value, sizeof(zval *), NULL); + } + zend_hash_add(ht, "systemini", sizeof("systemini"), &zvp3, sizeof(zval *), NULL); + } + + /* get perdir ini entries */ + if (EG(modified_ini_directives)) { + HashPosition position; + zend_ini_entry *ini_entry; + + array_init(&zv4); + for (zend_hash_internal_pointer_reset_ex(EG(modified_ini_directives), &position); + zend_hash_get_current_data_ex(EG(modified_ini_directives), (void**) &ini_entry, &position) == SUCCESS; + zend_hash_move_forward_ex(EG(modified_ini_directives), &position)) { + zval **value = emalloc(sizeof(zval *)); + if (!ini_entry->value) { + efree(value); + continue; + } + ALLOC_ZVAL(*value); + ZVAL_STRINGL(*value, ini_entry->value, ini_entry->value_length, 1); + zend_hash_add(Z_ARRVAL(zv4), ini_entry->name, ini_entry->name_length, value, sizeof(zval *), NULL); + } + zend_hash_add(ht, "userini", sizeof("userini"), &zvp4, sizeof(zval *), NULL); + } + + /* encode data */ + php_json_encode(&buf, &array, 0 TSRMLS_CC); + *msg = buf.c; + *len = buf.len; + zval_dtor(&array); +} diff --git a/phpdbg_webdata_transfer.h b/phpdbg_webdata_transfer.h index 4bcfb0c8e2e..d70175ad99d 100644 --- a/phpdbg_webdata_transfer.h +++ b/phpdbg_webdata_transfer.h @@ -19,462 +19,9 @@ #ifndef PHPDBG_WEBDATA_TRANSFER_H #define PHPDBG_WEBDATA_TRANSFER_H -/* {{{ remote console headers */ -#ifndef _WIN32 -# include -# include -# include -# include -#endif /* }}} */ - #include "zend.h" #include "phpdbg.h" -#include "ext/json/php_json.h" -#include "ext/standard/basic_functions.h" -static inline void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) { - smart_str buf = {0}; - zval array; - HashTable *ht; - /* I really need to change that to an array of zvals... */ - zval zv1, *zvp1 = &zv1; - zval zv2, *zvp2 = &zv2; - zval zv3, *zvp3 = &zv3; - zval zv4, *zvp4 = &zv4; - zval zv5, *zvp5 = &zv5; - zval zv6, *zvp6 = &zv6; - zval zv7, *zvp7 = &zv7; - zval zv8, *zvp8 = &zv8; - - array_init(&array); - ht = Z_ARRVAL(array); - - /* fetch superglobals */ - { - zend_is_auto_global(ZEND_STRL("GLOBALS") TSRMLS_CC); - /* might be JIT */ - zend_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC); - zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC); - zend_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC); - array_init(&zv1); - zend_hash_copy(Z_ARRVAL(zv1), &EG(symbol_table), NULL, (void *) NULL, sizeof(zval *)); - Z_ARRVAL(zv1)->pDestructor = NULL; /* we're operating on a copy! Don't double free zvals */ - zend_hash_del(Z_ARRVAL(zv1), "GLOBALS", sizeof("GLOBALS")); /* do not use the reference to itself in json */ - zend_hash_add(ht, "GLOBALS", sizeof("GLOBALS"), &zvp1, sizeof(zval *), NULL); - } - - /* save php://input */ - { - php_stream *stream; - int len; - char *contents; - - stream = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); - if ((len = php_stream_copy_to_mem(stream, &contents, PHP_STREAM_COPY_ALL, 0)) > 0) { - ZVAL_STRINGL(&zv2, contents, len, 0); - } else { - ZVAL_EMPTY_STRING(&zv2); - } - zend_hash_add(ht, "input", sizeof("input"), &zvp2, sizeof(zval *), NULL); - } - - /* change sapi name */ - { - if (sapi_module.name) { - ZVAL_STRING(&zv6, sapi_module.name, 1); - } else { - Z_TYPE(zv6) = IS_NULL; - } - zend_hash_add(ht, "sapi_name", sizeof("sapi_name"), &zvp6, sizeof(zval *), NULL); - } - - /* handle modules / extensions */ - { - HashPosition position; - zend_module_entry *module; - zend_extension *extension; - zend_llist_position pos; - - array_init(&zv7); - for (zend_hash_internal_pointer_reset_ex(&module_registry, &position); - zend_hash_get_current_data_ex(&module_registry, (void**) &module, &position) == SUCCESS; - zend_hash_move_forward_ex(&module_registry, &position)) { - zval **value = emalloc(sizeof(zval *)); - ALLOC_ZVAL(*value); - ZVAL_STRING(*value, module->name, 1); - zend_hash_next_index_insert(Z_ARRVAL(zv7), value, sizeof(zval *), NULL); - } - zend_hash_add(ht, "modules", sizeof("modules"), &zvp7, sizeof(zval *), NULL); - - array_init(&zv8); - extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos); - while (extension) { - zval **value = emalloc(sizeof(zval *)); - ALLOC_ZVAL(*value); - ZVAL_STRING(*value, extension->name, 1); - zend_hash_next_index_insert(Z_ARRVAL(zv8), value, sizeof(zval *), NULL); - extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos); - } - zend_hash_add(ht, "extensions", sizeof("extensions"), &zvp8, sizeof(zval *), NULL); - } - - /* switch cwd */ - { - char *ret = NULL; - char path[MAXPATHLEN]; - -#if HAVE_GETCWD - ret = VCWD_GETCWD(path, MAXPATHLEN); -#elif HAVE_GETWD - ret = VCWD_GETWD(path); -#endif - if (ret) { - ZVAL_STRING(&zv5, path, 1); - zend_hash_add(ht, "cwd", sizeof("cwd"), &zvp5, sizeof(zval *), NULL); - } - } - - /* get system ini entries */ - { - HashPosition position; - zend_ini_entry *ini_entry; - - array_init(&zv3); - for (zend_hash_internal_pointer_reset_ex(EG(ini_directives), &position); - zend_hash_get_current_data_ex(EG(ini_directives), (void**) &ini_entry, &position) == SUCCESS; - zend_hash_move_forward_ex(EG(ini_directives), &position)) { - zval **value = emalloc(sizeof(zval *)); - if (ini_entry->modified) { - if (!ini_entry->orig_value) { - efree(value); - continue; - } - ALLOC_ZVAL(*value); - ZVAL_STRINGL(*value, ini_entry->orig_value, ini_entry->orig_value_length, 1); - } else { - if (!ini_entry->value) { - efree(value); - continue; - } - ALLOC_ZVAL(*value); - ZVAL_STRINGL(*value, ini_entry->value, ini_entry->value_length, 1); - } - zend_hash_add(Z_ARRVAL(zv3), ini_entry->name, ini_entry->name_length, value, sizeof(zval *), NULL); - } - zend_hash_add(ht, "systemini", sizeof("systemini"), &zvp3, sizeof(zval *), NULL); - } - - /* get perdir ini entries */ - if (EG(modified_ini_directives)) { - HashPosition position; - zend_ini_entry *ini_entry; - - array_init(&zv4); - for (zend_hash_internal_pointer_reset_ex(EG(modified_ini_directives), &position); - zend_hash_get_current_data_ex(EG(modified_ini_directives), (void**) &ini_entry, &position) == SUCCESS; - zend_hash_move_forward_ex(EG(modified_ini_directives), &position)) { - zval **value = emalloc(sizeof(zval *)); - if (!ini_entry->value) { - efree(value); - continue; - } - ALLOC_ZVAL(*value); - ZVAL_STRINGL(*value, ini_entry->value, ini_entry->value_length, 1); - zend_hash_add(Z_ARRVAL(zv4), ini_entry->name, ini_entry->name_length, value, sizeof(zval *), NULL); - } - zend_hash_add(ht, "userini", sizeof("userini"), &zvp4, sizeof(zval *), NULL); - } - - /* encode data */ - php_json_encode(&buf, &array, 0 TSRMLS_CC); - *msg = buf.c; - *len = buf.len; - zval_dtor(&array); -} - -static void phpdbg_rebuild_http_globals_array(int type, const char *name TSRMLS_DC) { - zval **zvpp; - if (PG(http_globals)[type]) { - zval_dtor(PG(http_globals)[type]); - } - if (zend_hash_find(&EG(symbol_table), name, strlen(name) + 1, (void **) &zvpp) == SUCCESS) { - Z_SET_REFCOUNT_PP(zvpp, 2); - PG(http_globals)[type] = *zvpp; - } -} - -/* -static int phpdbg_remove_rearm_autoglobals(zend_auto_global *auto_global TSRMLS_DC) { -// zend_hash_del(&EG(symbol_table), auto_global->name, auto_global->name_len + 1); - - return 1; -}*/ - -typedef struct { - HashTable *ht[2]; - HashPosition pos[2]; -} phpdbg_intersect_ptr; - -static void phpdbg_array_intersect_init(phpdbg_intersect_ptr *info, HashTable *ht1, HashTable *ht2 TSRMLS_DC) { - info->ht[0] = ht1; - info->ht[1] = ht2; - - zend_hash_sort(info->ht[0], zend_qsort, (compare_func_t) string_compare_function, 0 TSRMLS_CC); - zend_hash_sort(info->ht[1], zend_qsort, (compare_func_t) string_compare_function, 0 TSRMLS_CC); - - zend_hash_internal_pointer_reset_ex(info->ht[0], &info->pos[0]); - zend_hash_internal_pointer_reset_ex(info->ht[1], &info->pos[1]); -} - -/* -1 => first array, 0 => both arrays equal, 1 => second array */ -static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) { - int ret; - zval **zvpp[2]; - int invalid = !info->ht[0] + !info->ht[1]; - - if (invalid > 0) { - invalid = !!info->ht[0]; - - if (zend_hash_get_current_data_ex(info->ht[invalid], (void **) ptr, &info->pos[invalid]) == FAILURE) { - *ptr = NULL; - return 0; - } - - zend_hash_move_forward_ex(info->ht[invalid], &info->pos[invalid]); - - return invalid ? -1 : 1; - } - - if (zend_hash_get_current_data_ex(info->ht[0], (void **) &zvpp[0], &info->pos[0]) == FAILURE) { - info->ht[0] = NULL; - return phpdbg_array_intersect(info, ptr); - } - if (zend_hash_get_current_data_ex(info->ht[1], (void **) &zvpp[1], &info->pos[1]) == FAILURE) { - info->ht[1] = NULL; - return phpdbg_array_intersect(info, ptr); - } - - ret = zend_binary_zval_strcmp(*zvpp[0], *zvpp[1]); - - if (ret <= 0) { - *ptr = zvpp[0]; - zend_hash_move_forward_ex(info->ht[0], &info->pos[0]); - } - if (ret >= 0) { - *ptr = zvpp[1]; - zend_hash_move_forward_ex(info->ht[1], &info->pos[1]); - } - - return ret; -} - -static inline void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { - zval *free_zv = NULL; - zval zv, **zvpp; - HashTable *ht; - php_json_decode(&zv, msg, len, 1, 1000 /* enough */ TSRMLS_CC); - ht = Z_ARRVAL(zv); - - /* Reapply symbol table */ - if (zend_hash_find(ht, "GLOBALS", sizeof("GLOBALS"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { - zend_hash_clean(&EG(symbol_table)); - EG(symbol_table) = *Z_ARRVAL_PP(zvpp); - - /* Rebuild cookies, env vars etc. from GLOBALS (PG(http_globals)) */ - phpdbg_rebuild_http_globals_array(TRACK_VARS_POST, "_POST" TSRMLS_CC); - phpdbg_rebuild_http_globals_array(TRACK_VARS_GET, "_GET" TSRMLS_CC); - phpdbg_rebuild_http_globals_array(TRACK_VARS_COOKIE, "_COOKIE" TSRMLS_CC); - phpdbg_rebuild_http_globals_array(TRACK_VARS_SERVER, "_SERVER" TSRMLS_CC); - phpdbg_rebuild_http_globals_array(TRACK_VARS_ENV, "_ENV" TSRMLS_CC); - phpdbg_rebuild_http_globals_array(TRACK_VARS_FILES, "_FILES" TSRMLS_CC); - - Z_ADDREF_PP(zvpp); - free_zv = *zvpp; - } - - if (zend_hash_find(ht, "input", sizeof("input"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) { - if (SG(request_info).request_body) { - php_stream_close(SG(request_info).request_body); - } - SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); - php_stream_truncate_set_size(SG(request_info).request_body, 0); - php_stream_write(SG(request_info).request_body, Z_STRVAL_PP(zvpp), Z_STRLEN_PP(zvpp)); - } - - if (zend_hash_find(ht, "cwd", sizeof("cwd"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) { - if (VCWD_CHDIR(Z_STRVAL_PP(zvpp)) == SUCCESS) { - if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) { - efree(BG(CurrentStatFile)); - BG(CurrentStatFile) = NULL; - } - if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) { - efree(BG(CurrentLStatFile)); - BG(CurrentLStatFile) = NULL; - } - } - } - - if (zend_hash_find(ht, "sapi_name", sizeof("sapi_name"), (void **) &zvpp) == SUCCESS && (Z_TYPE_PP(zvpp) == IS_STRING || Z_TYPE_PP(zvpp) == IS_NULL)) { - if (sapi_module.name) { - efree(sapi_module.name); - } - if (Z_TYPE_PP(zvpp) == IS_STRING) { - sapi_module.name = estrndup(Z_STRVAL_PP(zvpp), Z_STRLEN_PP(zvpp)); - } else { - sapi_module.name = NULL; - } - } - - if (zend_hash_find(ht, "modules", sizeof("modules"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { - HashPosition position; - phpdbg_intersect_ptr pos; - zval **module; - zend_module_entry *mod; - HashTable zv_registry; - - /* intersect modules, unregister mpdules loaded "too much", announce not yet registered modules (phpdbg_notice) */ - - zend_hash_init(&zv_registry, zend_hash_num_elements(&zv_registry), 0, ZVAL_PTR_DTOR, 0); - for (zend_hash_internal_pointer_reset_ex(&module_registry, &position); - zend_hash_get_current_data_ex(&module_registry, (void **) &mod, &position) == SUCCESS; - zend_hash_move_forward_ex(&module_registry, &position)) { - zval **value = emalloc(sizeof(zval *)); - ALLOC_ZVAL(*value); - ZVAL_STRING(*value, mod->name, 1); - zend_hash_next_index_insert(&zv_registry, value, sizeof(zval *), NULL); - } - - phpdbg_array_intersect_init(&pos, &zv_registry, Z_ARRVAL_PP(zvpp) TSRMLS_CC); - do { - int mode = phpdbg_array_intersect(&pos, &module); - if (mode < 0) { - // loaded module, but not needed - zend_hash_del(&module_registry, Z_STRVAL_PP(module), Z_STRLEN_PP(module) + 1); - } else if (mode > 0) { - // not loaded module - phpdbg_notice("The module %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/module.so", Z_STRLEN_PP(module), Z_STRVAL_PP(module)); - } - } while (module); - - zend_hash_clean(&zv_registry); - } - - if (zend_hash_find(ht, "extensions", sizeof("extensions"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { - zend_extension *extension; - zend_llist_position pos; - HashPosition hpos; - zval **name, key; - - extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos); - while (extension) { - extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos); - - /* php_serach_array() body should be in some ZEND_API function */ - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &hpos); - zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &name, &hpos) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &hpos)) { - if (Z_TYPE_PP(name) == IS_STRING && !zend_binary_strcmp(extension->name, strlen(extension->name), Z_STRVAL_PP(name), Z_STRLEN_PP(name))) { - break; - } - } - - if (zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &zvpp, &hpos) == FAILURE) { - /* sigh, breaking the encapsulation, there aren't any functions manipulating the llist at the place of the zend_llist_position */ - zend_llist_element *elm = pos; - if (elm->prev) { - elm->prev->next = elm->next; - } else { - zend_extensions.head = elm->next; - } - if (elm->next) { - elm->next->prev = elm->prev; - } else { - zend_extensions.tail = elm->prev; - } -#if ZEND_EXTENSIONS_SUPPORT - if (extension->shutdown) { - extension->shutdown(extension); - } -#endif - if (zend_extensions.dtor) { - zend_extensions.dtor(elm->data); - } - pefree(elm, zend_extensions.persistent); - zend_extensions.count--; - } else { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &hpos); - if (Z_TYPE(key) == IS_LONG) { - zend_hash_index_del(Z_ARRVAL_PP(zvpp), Z_LVAL(key)); - } - } - - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &hpos); - zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &name, &hpos) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &hpos)) { - phpdbg_notice("The (zend) extension %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/extension.so", Z_STRLEN_PP(name), Z_STRVAL_PP(name)); - } - } - } - - zend_ini_deactivate(TSRMLS_C); - - if (zend_hash_find(ht, "systemini", sizeof("systemini"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { - HashPosition position; - zval **ini_entry; - zend_ini_entry *original_ini; - zval key; - - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &position); - zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void**) &ini_entry, &position) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &position)) { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &position); - if (Z_TYPE(key) == IS_STRING) { - if (Z_TYPE_PP(ini_entry) == IS_STRING) { - if (zend_hash_find(EG(ini_directives), Z_STRVAL(key), Z_STRLEN(key) + 1, (void **) &original_ini) == SUCCESS) { - if (!original_ini->on_modify || original_ini->on_modify(original_ini, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), original_ini->mh_arg1, original_ini->mh_arg2, original_ini->mh_arg3, ZEND_INI_STAGE_ACTIVATE TSRMLS_CC) == SUCCESS) { - original_ini->value = Z_STRVAL_PP(ini_entry); - original_ini->value_length = Z_STRLEN_PP(ini_entry); - continue; /* don't free the string */ - } - } - } - efree(Z_STRVAL(key)); - } - } - } - - if (zend_hash_find(ht, "userini", sizeof("userini"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { - HashPosition position; - zval **ini_entry; - zval key; - - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &position); - zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void**) &ini_entry, &position) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &position)) { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &position); - if (Z_TYPE(key) == IS_STRING) { - if (Z_TYPE_PP(ini_entry) == IS_STRING) { - zend_alter_ini_entry_ex(Z_STRVAL(key), Z_STRLEN(key) + 1, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), ZEND_INI_PERDIR, ZEND_INI_STAGE_HTACCESS, 1 TSRMLS_CC); - } - efree(Z_STRVAL(key)); - } - } - } - - zval_dtor(&zv); - if (free_zv) { - /* separate freeing to not dtor the symtable too, just the container zval... */ - efree(free_zv); - } - - /* Remove and readd autoglobals */ -/* php_hash_environment(TSRMLS_C); - zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_remove_rearm_autoglobals TSRMLS_CC); - php_startup_auto_globals(TSRMLS_C); - zend_activate_auto_globals(TSRMLS_C); -*/ - /* Reapply raw input */ - /* ??? */ -} +PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC); #endif /* PHPDBG_WEBDATA_TRANSFER_H */ From cccc75eef9dda2d73c385cc22e2e06b6926111ea Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 10 Sep 2014 17:01:08 +0200 Subject: [PATCH 003/125] Do not unload phpdbg module in any case --- phpdbg_wait.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/phpdbg_wait.c b/phpdbg_wait.c index d369dedf106..f01be306672 100644 --- a/phpdbg_wait.c +++ b/phpdbg_wait.c @@ -18,10 +18,11 @@ #include "phpdbg_wait.h" #include "phpdbg_prompt.h" -#include "ext/json/php_json.h" +#include "ext/json/JSON_parser.h" #include "ext/standard/basic_functions.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +ZEND_EXTERN_MODULE_GLOBALS(json); static void phpdbg_rebuild_http_globals_array(int type, const char *name TSRMLS_DC) { zval **zvpp; @@ -97,7 +98,7 @@ static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) { zend_hash_move_forward_ex(info->ht[invalid], &info->pos[invalid]); - return invalid ? -1 : 1; + return invalid ? 1 : -1; } if (zend_hash_get_current_data_ex(info->ht[0], (void **) &zvpp[0], &info->pos[0]) == FAILURE) { @@ -128,6 +129,12 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { zval zv, **zvpp; HashTable *ht; php_json_decode(&zv, msg, len, 1, 1000 /* enough */ TSRMLS_CC); + + if (JSON_G(error_code) != PHP_JSON_ERROR_NONE) { + phpdbg_error("Malformed JSON was sent to this socket, arborting"); + return; + } + ht = Z_ARRVAL(zv); /* Reapply symbol table */ @@ -205,7 +212,7 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { for (zend_hash_internal_pointer_reset_ex(&module_registry, &position); zend_hash_get_current_data_ex(&module_registry, (void **) &mod, &position) == SUCCESS; zend_hash_move_forward_ex(&module_registry, &position)) { - if (mod->name && (!sapi_module.name || strcmp(sapi_module.name, mod->name))) { + if (mod->name) { zval **value = emalloc(sizeof(zval *)); MAKE_STD_ZVAL(*value); ZVAL_STRING(*value, mod->name, 1); @@ -218,10 +225,14 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { int mode = phpdbg_array_intersect(&pos, &module); if (mode < 0) { // loaded module, but not needed - zend_hash_del(&module_registry, Z_STRVAL_PP(module), Z_STRLEN_PP(module) + 1); + if (strcmp(PHPDBG_NAME, Z_STRVAL_PP(module))) { + zend_hash_del(&module_registry, Z_STRVAL_PP(module), Z_STRLEN_PP(module) + 1); + } } else if (mode > 0) { // not loaded module - phpdbg_notice("The module %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/module.so", Z_STRLEN_PP(module), Z_STRVAL_PP(module)); + if (!sapi_module.name || strcmp(sapi_module.name, Z_STRVAL_PP(module))) { + phpdbg_notice("The module %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/module/%.*s.so", Z_STRLEN_PP(module), Z_STRVAL_PP(module), Z_STRLEN_PP(module), Z_STRVAL_PP(module)); + } } } while (module); From e0e990229dd6e9028dd442f5b1764628f191de02 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 15 Sep 2014 09:58:14 +0200 Subject: [PATCH 004/125] Use full duplex stdin/stdout socket --- phpdbg.c | 212 ++++++++++++++++---------------------------------- phpdbg_help.c | 4 +- 2 files changed, 68 insertions(+), 148 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index c881559e6ed..1e1642fb761 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -714,147 +714,87 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */ #ifndef _WIN32 int phpdbg_open_socket(const char *interface, short port) /* {{{ */ { + int reuse = 1; + struct sockaddr_in address; int fd = socket(AF_INET, SOCK_STREAM, 0); - switch (fd) { - case -1: - return -1; - - default: { - int reuse = 1; - - switch (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse))) { - case -1: - close(fd); - return -2; - - default: { - struct sockaddr_in address; - - memset(&address, 0, sizeof(address)); - - address.sin_port = htons(port); - address.sin_family = AF_INET; - - if ((*interface == '*')) { - address.sin_addr.s_addr = htonl(INADDR_ANY); - } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) { - close(fd); - return -3; - } - - switch (bind(fd, (struct sockaddr *)&address, sizeof(address))) { - case -1: - close(fd); - return -4; - - default: { - listen(fd, 5); - } - } - } - } - } + if (fd == -1) { + return -1; } + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) == -1) { + close(fd); + return -2; + } + + + memset(&address, 0, sizeof(address)); + + address.sin_port = htons(port); + address.sin_family = AF_INET; + + if ((*interface == '*')) { + address.sin_addr.s_addr = htonl(INADDR_ANY); + } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) { + close(fd); + return -3; + } + + if (bind(fd, (struct sockaddr *)&address, sizeof(address)) == -1) { + close(fd); + return -4; + } + + listen(fd, 5); + return fd; } /* }}} */ -static inline void phpdbg_close_sockets(int (*socket)[2], FILE *streams[2]) /* {{{ */ -{ - if ((*socket)[0] >= 0) { - shutdown( - (*socket)[0], SHUT_RDWR); - close((*socket)[0]); +static void phpdbg_remote_close(int socket, FILE *stream) { + if (socket >= 0) { + shutdown(socket, SHUT_RDWR); + close(socket); } - if (streams[0]) { - fclose(streams[0]); + if (stream) { + fclose(stream); } - - if ((*socket)[1] >= 0) { - shutdown( - (*socket)[1], SHUT_RDWR); - close((*socket)[1]); - } - - if (streams[1]) { - fclose(streams[1]); - } -} /* }}} */ +} /* don't inline this, want to debug it easily, will inline when done */ +static int phpdbg_remote_init(const char* address, short port, int *server, int *socket, FILE **stream) { + phpdbg_remote_close(*socket, *stream); -int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*socket)[2], FILE* streams[2]) /* {{{ */ -{ - if (((*listen)[0]) < 0 && ((*listen)[1]) < 0) { - ((*listen)[0]) = phpdbg_open_socket(address, (short)port[0]); - ((*listen)[1]) = phpdbg_open_socket(address, (short)port[1]); - } + *server = phpdbg_open_socket(address, port); - streams[0] = NULL; - streams[1] = NULL; - - if ((*listen)[0] < 0 || (*listen)[1] < 0) { - if ((*listen)[0] < 0) { - phpdbg_rlog(stderr, - "console failed to initialize (stdin) on %s:%d", address, port[0]); - } - - if ((*listen)[1] < 0) { - phpdbg_rlog(stderr, - "console failed to initialize (stdout) on %s:%d", address, port[1]); - } - - if ((*listen)[0] >= 0) { - close((*listen)[0]); - } - - if ((*listen)[1] >= 0) { - close((*listen)[1]); - } + if (*server < 0) { + phpdbg_rlog(stderr, "Initializing connection on %s:%d failed", address, port); return FAILURE; } - phpdbg_close_sockets(socket, streams); - - phpdbg_rlog(stderr, - "accepting connections on %s:%d/%d", address, port[0], port[1]); + phpdbg_rlog(stderr, "accepting connections on %s:%d", address, port); { struct sockaddr_in address; socklen_t size = sizeof(address); char buffer[20] = {0}; - { - memset(&address, 0, size); - (*socket)[0] = accept( - (*listen)[0], (struct sockaddr *) &address, &size); - inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); + memset(&address, 0, size); + *socket = accept(*server, (struct sockaddr *) &address, &size); + inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); - phpdbg_rlog(stderr, "connection (stdin) from %s", buffer); - } - - { - memset(&address, 0, size); - (*socket)[1] = accept( - (*listen)[1], (struct sockaddr *) &address, &size); - inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); - - phpdbg_rlog(stderr, "connection (stdout) from %s", buffer); - } + phpdbg_rlog(stderr, "connection established from %s", buffer); } - dup2((*socket)[0], fileno(stdin)); - dup2((*socket)[1], fileno(stdout)); + dup2(*socket, fileno(stdout)); + dup2(*socket, fileno(stdin)); setbuf(stdout, NULL); - streams[0] = fdopen((*socket)[0], "r"); - streams[1] = fdopen((*socket)[1], "w"); + *stream = fdopen(*socket, "r+"); return SUCCESS; -} /* }}} */ +} void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */ { @@ -938,10 +878,10 @@ int main(int argc, char **argv) /* {{{ */ #ifndef _WIN32 char *address; - int listen[2]; - int server[2]; - int socket[2]; - FILE* streams[2] = {NULL, NULL}; + int listen = -1; + int server = -1; + int socket = -1; + FILE* stream = NULL; #endif #ifdef ZTS @@ -954,14 +894,6 @@ int main(int argc, char **argv) /* {{{ */ signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER; address = strdup("127.0.0.1"); - socket[0] = -1; - socket[1] = -1; - listen[0] = -1; - listen[1] = -1; - server[0] = -1; - server[1] = -1; - streams[0] = NULL; - streams[1] = NULL; #endif #ifdef PHP_WIN32 @@ -1126,20 +1058,12 @@ phpdbg_main: break; #ifndef _WIN32 - /* if you pass a listen port, we will accept input on listen port */ - /* and write output to listen port * 2 */ - - case 'l': { /* set listen ports */ - if (sscanf(php_optarg, "%d/%d", &listen[0], &listen[1]) != 2) { - if (sscanf(php_optarg, "%d", &listen[0]) != 1) { - /* default to hardcoded ports */ - listen[0] = 4000; - listen[1] = 8000; - } else { - listen[1] = (listen[0] * 2); - } + /* if you pass a listen port, we will read and write on listen port */ + case 'l': /* set listen ports */ + if (sscanf(php_optarg, "%d", &listen) != 1) { + listen = 8000; } - } break; + break; case 'a': { /* set bind address */ free(address); @@ -1182,12 +1106,11 @@ phpdbg_main: #ifndef _WIN32 /* setup remote server if necessary */ - if (!cleaning && - (listen[0] > 0 && listen[1] > 0)) { - if (phpdbg_open_sockets(address, listen, &server, &socket, streams) == FAILURE) { - remote = 0; + if (!cleaning && listen > 0) { + if (phpdbg_remote_init(address, listen, &server, &socket, &stream) == FAILURE) { exit(0); } + /* set remote flag to stop service shutting down upon quit */ remote = 1; } @@ -1293,11 +1216,11 @@ phpdbg_main: /* make sure to turn off buffer for ev command */ php_output_activate(TSRMLS_C); php_output_deactivate(TSRMLS_C); - + /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ #ifndef _WIN32 - if (listen[0] < 0) { + if (listen < 0) { #endif #if defined(ZEND_SIGNALS) && !defined(_WIN32) zend_try { zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); } zend_end_try(); @@ -1315,7 +1238,7 @@ phpdbg_main: #ifndef _WIN32 /* setup io here */ - if (streams[0] && streams[1]) { + if (stream) { PHPDBG_G(flags) |= PHPDBG_IS_REMOTE; signal(SIGPIPE, SIG_IGN); @@ -1415,11 +1338,10 @@ phpdbg_interact: if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { /* renegociate connections */ - phpdbg_open_sockets( - address, listen, &server, &socket, streams); + phpdbg_remote_init(address, listen, &server, &socket, &stream); /* set streams */ - if (streams[0] && streams[1]) { + if (stream) { PHPDBG_G(flags) &= ~PHPDBG_IS_QUITTING; } diff --git a/phpdbg_help.c b/phpdbg_help.c index 1e58dc69cad..3244b653ef9 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -386,9 +386,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "bind address using the **-a** option. If **-a** is specied without an argument, then phpdbg " "will bind to all available interfaces. You should be aware of the security implications of " "doing this, so measures should be taken to secure this service if bound to a publicly accessible " -"interface/port." CR CR - -"Specify both stdin and stdout with -lstdin/stdout; by default stdout is stdin * 2." +"interface/port." }, {"phpdbginit", CR From bbeccd74744b06b4fa531e4a4505bf15825d12ef Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 21 Sep 2014 04:17:19 +0200 Subject: [PATCH 005/125] First draft of an xml protocol --- phpdbg.c | 90 +++- phpdbg.h | 36 +- phpdbg_bp.c | 232 +++++----- phpdbg_bp.h | 13 + phpdbg_cmd.c | 223 +++++----- phpdbg_cmd.h | 12 +- phpdbg_frame.c | 55 ++- phpdbg_help.c | 36 +- phpdbg_help.h | 4 +- phpdbg_info.c | 136 ++---- phpdbg_list.c | 50 ++- phpdbg_opcode.c | 24 +- phpdbg_parser.c | 311 +++++++------- phpdbg_parser.h | 39 +- phpdbg_print.c | 73 ++-- phpdbg_prompt.c | 384 +++++++---------- phpdbg_set.c | 82 ++-- phpdbg_utils.c | 1087 ++++++++++++++++++++++++++++++++++++++++++++--- phpdbg_utils.h | 47 +- phpdbg_watch.c | 99 +++-- 20 files changed, 2002 insertions(+), 1031 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 1e1642fb761..b27e774bdd0 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -72,6 +72,9 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->io[PHPDBG_STDOUT] = NULL; pg->io[PHPDBG_STDERR] = NULL; pg->frame.num = 0; + + pg->err_buf.active = 0; + pg->err_buf.type = 0; } /* }}} */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ @@ -86,7 +89,7 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ #endif REGISTER_STRINGL_CONSTANT("PHPDBG_VERSION", PHPDBG_VERSION, sizeof(PHPDBG_VERSION)-1, CONST_CS|CONST_PERSISTENT); - + REGISTER_LONG_CONSTANT("PHPDBG_FILE", FILE_PARAM, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHPDBG_METHOD", METHOD_PARAM, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHPDBG_LINENO", NUMERIC_PARAM, CONST_CS|CONST_PERSISTENT); @@ -186,7 +189,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ efree(PHPDBG_G(buffer)); PHPDBG_G(buffer) = NULL; } - + if (PHPDBG_G(exec)) { efree(PHPDBG_G(exec)); PHPDBG_G(exec) = NULL; @@ -226,7 +229,7 @@ static PHP_FUNCTION(phpdbg_exec) { char *exec = NULL; int exec_len = 0; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &exec, &exec_len) == FAILURE) { return; } @@ -308,7 +311,7 @@ static PHP_FUNCTION(phpdbg_color) { long element = 0L; char *color = NULL; - int color_len = 0; + size_t color_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &element, &color, &color_len) == FAILURE) { return; @@ -329,7 +332,7 @@ static PHP_FUNCTION(phpdbg_color) static PHP_FUNCTION(phpdbg_prompt) { char *prompt = NULL; - int prompt_len = 0; + size_t prompt_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &prompt, &prompt_len) == FAILURE) { return; @@ -426,7 +429,7 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */ * We must not request TSRM before being boot */ if (phpdbg_booted) { - phpdbg_error("%s", message); + phpdbg_error("php", "msg=\"%s\"", "%s", message); switch (PG(last_error_type)) { case E_ERROR: @@ -516,9 +519,39 @@ static void php_sapi_phpdbg_register_vars(zval *track_vars_array TSRMLS_DC) /* { static inline int php_sapi_phpdbg_ub_write(const char *message, unsigned int length TSRMLS_DC) /* {{{ */ { - return phpdbg_write("%s", message); + return phpdbg_script(P_STDOUT, "%.*s", length, message); } /* }}} */ +/* beginning of struct, see main/streams/plain_wrapper.c line 111 */ +typedef struct { + FILE *file; + int fd; +} php_stdio_stream_data; + +static size_t phpdbg_stdiop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) { + php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; + + while (data->fd >= 0) { + struct stat stat[3]; + memset(stat, 0, sizeof(stat)); + if ((fstat(fileno(stderr), &stat[2]) < 0 && fstat(fileno(stdout), &stat[0]) < 0) || fstat(data->fd, &stat[1]) < 0) { + break; + } + + if (stat[0].st_dev == stat[1].st_dev && stat[0].st_ino == stat[1].st_ino) { + phpdbg_script(P_STDOUT, "%.*s", buf, count); + return count; + } + if (stat[2].st_dev == stat[1].st_dev && stat[2].st_ino == stat[1].st_ino) { + phpdbg_script(P_STDERR, "%.*s", buf, count); + return count; + } + break; + } + + return PHPDBG_G(php_stdiop_write)(stream, buf, count TSRMLS_CC); +} + #if PHP_VERSION_ID >= 50700 static inline void php_sapi_phpdbg_flush(void *context TSRMLS_DC) /* {{{ */ { @@ -648,6 +681,7 @@ const opt_struct OPTIONS[] = { /* {{{ */ {'l', 1, "listen"}, {'a', 1, "address-or-any"}, #endif + {'x', 0, "xml output"}, {'V', 0, "version"}, {'-', 0, NULL} }; /* }}} */ @@ -679,17 +713,23 @@ static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */ { /* print blurb */ if (!cleaning) { - phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s", - PHPDBG_VERSION); - phpdbg_writeln("To get help using phpdbg type \"help\" and press enter"); - phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES); + phpdbg_notice("intro", "version=\"%s\"", "Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION); + phpdbg_writeln("intro", "help=\"help\"", "To get help using phpdbg type \"help\" and press enter"); + phpdbg_notice("intro", "report=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES); } else { - phpdbg_notice("Clean Execution Environment"); + if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { + phpdbg_notice(NULL, NULL, "Clean Execution Environment"); + } - phpdbg_writeln("Classes\t\t\t%d", zend_hash_num_elements(EG(class_table))); - phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(EG(function_table))); - phpdbg_writeln("Constants\t\t%d", zend_hash_num_elements(EG(zend_constants))); - phpdbg_writeln("Includes\t\t%d", zend_hash_num_elements(&EG(included_files))); + phpdbg_write("cleaninfo", "classes=\"%d\" functions=\"%d\" constants=\"%d\" includes=\"%d\"", + "Classes %d\n" + "Functions %d\n" + "Constants %d\n" + "Includes %d\n", + zend_hash_num_elements(EG(class_table)), + zend_hash_num_elements(EG(function_table)), + zend_hash_num_elements(EG(zend_constants)), + zend_hash_num_elements(&EG(included_files))); } } /* }}} */ @@ -923,7 +963,7 @@ phpdbg_main: } if (!bp_tmp_file) { - phpdbg_error("Unable to create temporary file"); + phpdbg_error("tmpfile", "", "Unable to create temporary file"); return 1; } #else @@ -1073,6 +1113,10 @@ phpdbg_main: } break; #endif + case 'x': + flags |= PHPDBG_WRITE_XML; + break; + case 'V': { sapi_startup(phpdbg); phpdbg->startup(phpdbg); @@ -1249,6 +1293,11 @@ phpdbg_main: PHPDBG_G(io)[PHPDBG_STDOUT] = stdout; PHPDBG_G(io)[PHPDBG_STDERR] = stderr; +#ifndef _WIN32 + PHPDBG_G(php_stdiop_write) = php_stream_stdio_ops.write; + php_stream_stdio_ops.write = phpdbg_stdiop_write; +#endif + if (exec) { /* set execution context */ PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC); PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec)); @@ -1259,8 +1308,7 @@ phpdbg_main: if (oplog_file) { /* open oplog */ PHPDBG_G(oplog) = fopen(oplog_file, "w+"); if (!PHPDBG_G(oplog)) { - phpdbg_error( - "Failed to open oplog %s", oplog_file); + phpdbg_error("oplog", "path=\"%s\"", "Failed to open oplog %s", oplog_file); } free(oplog_file); } @@ -1271,7 +1319,7 @@ phpdbg_main: phpdbg_set_color_ex(PHPDBG_COLOR_NOTICE, PHPDBG_STRL("green") TSRMLS_CC); /* set default prompt */ - phpdbg_set_prompt(PROMPT TSRMLS_CC); + phpdbg_set_prompt(PHPDBG_DEFAULT_PROMPT TSRMLS_CC); /* Make stdin, stdout and stderr accessible from PHP scripts */ phpdbg_register_file_handles(TSRMLS_C); @@ -1373,7 +1421,7 @@ phpdbg_out: #ifdef _WIN32 } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) { - phpdbg_error("Access violation (Segementation fault) encountered\ntrying to abort cleanly..."); + phpdbg_error("segfault", "", "Access violation (Segementation fault) encountered\ntrying to abort cleanly..."); } phpdbg_out: #endif diff --git a/phpdbg.h b/phpdbg.h index 2fa2d5093a8..bb0b8e2aa51 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -64,7 +64,7 @@ # include "TSRM.h" #endif -#ifdef HAVE_LIBREADLINE +#ifdef LIBREADLINE # include # include #endif @@ -74,6 +74,7 @@ #include "phpdbg_lexer.h" #include "phpdbg_cmd.h" +#include "phpdbg_bp.h" #include "phpdbg_utils.h" #include "phpdbg_btree.h" #include "phpdbg_watch.h" @@ -95,19 +96,6 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); BEGIN: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE */ -/* {{{ tables */ -#define PHPDBG_BREAK_FILE 0 -#define PHPDBG_BREAK_SYM 1 -#define PHPDBG_BREAK_OPLINE 2 -#define PHPDBG_BREAK_METHOD 3 -#define PHPDBG_BREAK_COND 4 -#define PHPDBG_BREAK_OPCODE 5 -#define PHPDBG_BREAK_FUNCTION_OPLINE 6 -#define PHPDBG_BREAK_METHOD_OPLINE 7 -#define PHPDBG_BREAK_FILE_OPLINE 8 -#define PHPDBG_BREAK_MAP 9 -#define PHPDBG_BREAK_TABLES 10 /* }}} */ - /* {{{ flags */ #define PHPDBG_HAS_FILE_BP (1<<1) #define PHPDBG_HAS_SYM_BP (1<<2) @@ -145,8 +133,9 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); #define PHPDBG_IS_BP_ENABLED (1<<26) #define PHPDBG_IS_REMOTE (1<<27) #define PHPDBG_IS_DISCONNECTED (1<<28) +#define PHPDBG_WRITE_XML (1<<29) -#define PHPDBG_SHOW_REFCOUNTS (1<<29) +#define PHPDBG_SHOW_REFCOUNTS (1<<30) #define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE) #define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) @@ -165,6 +154,7 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); #define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues" #define PHPDBG_VERSION "0.4.0" #define PHPDBG_INIT_FILENAME ".phpdbginit" +#define PHPDBG_DEFAULT_PROMPT "prompt>" /* }}} */ /* {{{ output descriptors */ @@ -180,7 +170,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable registered; /* registered */ HashTable seek; /* seek oplines */ phpdbg_frame_t frame; /* frame */ - zend_uint last_line; /* last executed line */ + uint32_t last_line; /* last executed line */ phpdbg_lexer_data lexer; /* lexer data */ phpdbg_param_t *parser_stack; /* param stack during lexer / parser phase */ @@ -204,6 +194,20 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) FILE *oplog; /* opline log */ FILE *io[PHPDBG_IO_FDS]; /* io */ +#ifndef _WIN32 + size_t (*php_stdiop_write)(php_stream *, const char *, size_t TSRMLS_DC); +#endif + int in_script_xml; /* in output mode */ + struct { + zend_bool active; + int type; + FILE *fp; + char *tag; + char *msg; + int msglen; + char *xml; + int xmllen; + } err_buf; /* error buffer */ char *prompt[2]; /* prompt */ const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */ diff --git a/phpdbg_bp.c b/phpdbg_bp.c index a18316a2285..dbe1da63ddc 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -43,8 +43,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut */ static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC) { - zend_hash_index_update( - &PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id), (void**) &table, sizeof(void*), NULL); + zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id), (void**) &table, sizeof(void*), NULL); } #define PHPDBG_BREAK_MAPPING(id, table) _phpdbg_break_mapping(id, table TSRMLS_CC) @@ -97,8 +96,8 @@ PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */ HashTable **table = NULL; for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]); - zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table, &position[0]) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) { + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void **) &table, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) { phpdbg_breakbase_t *brake; for (zend_hash_internal_pointer_reset_ex((*table), &position[1]); @@ -117,13 +116,11 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ zend_ulong id = 0L; if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) { - phpdbg_notice( - "Exporting %d breakpoints", - zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])); + phpdbg_notice("exportbreakpoint", "count=\"%d\"", "Exporting %d breakpoints", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])); /* this only looks like magic, it isn't */ for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]); - zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table, &position[0]) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) { + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void **) &table, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) { phpdbg_breakbase_t *brake; zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id, 0, &position[0]); @@ -223,18 +220,18 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML { php_stream_statbuf ssb; char realpath[MAXPATHLEN]; - + if (php_stream_stat_path(path, &ssb) != FAILURE) { if (ssb.sb.st_mode & (S_IFREG|S_IFLNK)) { HashTable *broken; phpdbg_breakfile_t new_break; size_t path_len = 0L; - + if (VCWD_REALPATH(path, realpath)) { path = realpath; } path_len = strlen(path); - + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len, (void**)&broken) == FAILURE) { HashTable breaks; @@ -253,22 +250,21 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML new_break.filename = estrndup(path, path_len); new_break.line = line_num; - zend_hash_index_update( - broken, line_num, (void**)&new_break, sizeof(phpdbg_breakfile_t), NULL); + zend_hash_index_update( broken, line_num, (void**)&new_break, sizeof(phpdbg_breakfile_t), NULL); - phpdbg_notice("Breakpoint #%d added at %s:%ld", + phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line); PHPDBG_BREAK_MAPPING(new_break.id, broken); } else { - phpdbg_error("Breakpoint at %s:%ld exists", path, line_num); + phpdbg_error("breakpoint", "type=\"exists\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num); } } else { - phpdbg_error("Cannot set breakpoint in %s, it is not a regular file", path); + phpdbg_error("breakpoint", "type=\"notregular\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path); } } else { - phpdbg_error("Cannot stat %s, it does not exist", path); + phpdbg_error("breakpoint", "type=\"nofile\" file=\"%s\"", "Cannot stat %s, it does not exist", path); } } /* }}} */ @@ -285,12 +281,12 @@ PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len T zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol, name_len, &new_break, sizeof(phpdbg_breaksymbol_t), NULL); - phpdbg_notice("Breakpoint #%d added at %s", + phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" function=\"%s\"", "Breakpoint #%d added at %s", new_break.id, new_break.symbol); PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); } else { - phpdbg_notice("Breakpoint exists at %s", name); + phpdbg_error("breakpoint", "type=\"exists\" function=\"%s\"", "Breakpoint exists at %s", name); } } /* }}} */ @@ -324,12 +320,12 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char zend_hash_update(class_table, lcname, func_len, &new_break, sizeof(phpdbg_breakmethod_t), NULL); - phpdbg_notice("Breakpoint #%d added at %s::%s", + phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" method=\"%s::%s\"", "Breakpoint #%d added at %s::%s", new_break.id, class_name, func_name); PHPDBG_BREAK_MAPPING(new_break.id, class_table); } else { - phpdbg_notice("Breakpoint exists at %s::%s", class_name, func_name); + phpdbg_error("breakpoint", "type=\"exists\" method=\"%s::%s\"", "Breakpoint exists at %s::%s", class_name, func_name); } efree(lcname); @@ -350,11 +346,11 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, &new_break, sizeof(phpdbg_breakline_t), NULL); - phpdbg_notice("Breakpoint #%d added at %#lx", + phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx", new_break.id, new_break.opline); PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); } else { - phpdbg_notice("Breakpoint exists at %#lx", opline); + phpdbg_error("breakpoint", "type=\"exists\" opline=\"%#lx\"", "Breakpoint exists at %#lx", opline); } } /* }}} */ @@ -363,11 +359,11 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o phpdbg_breakline_t opline_break; if (op_array->last <= brake->opline_num) { if (brake->class_name == NULL) { - phpdbg_error("There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" maxoplinenum=\"%d\" function=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num); } else if (brake->func_name == NULL) { - phpdbg_error("There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" maxoplinenum=\"%d\" file=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num); } else { - phpdbg_error("There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" maxoplinenum=\"%d\" method=\"%s::%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num); } return FAILURE; @@ -423,7 +419,7 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC zend_hash_internal_pointer_end(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); zend_hash_get_current_data(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void **)&opline_break); - phpdbg_notice("Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)", + phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" symbol=\"%s\" num=\"%ld\" opline=\"%#lx\"", "Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)", brake->id, brake->class_name?brake->class_name:"", brake->class_name&&brake->func_name?"::":"", @@ -474,7 +470,7 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML if (zend_hash_find(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len + 1, (void **)&func) == FAILURE) { if (new_break->class_name != NULL && new_break->func_name != NULL) { - phpdbg_error("Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name); + phpdbg_error("breakpoint", "type=\"nomethod\" method=\"%s::%s\"", "Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name); return 2; } return FAILURE; @@ -482,9 +478,9 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML if (func->type != ZEND_USER_FUNCTION) { if (new_break->class_name == NULL) { - phpdbg_error("%s is not an user defined function, no oplines exist", new_break->func_name); + phpdbg_error("breakpoint", "type=\"internalfunction\" function=\"%s\"", "%s is not an user defined function, no oplines exist", new_break->func_name); } else { - phpdbg_error("%s::%s is not an user defined method, no oplines exist", new_break->class_name, new_break->func_name); + phpdbg_error("breakpoint", "type=\"internalfunction\" method=\"%s::%s\"", "%s::%s is not an user defined method, no oplines exist", new_break->class_name, new_break->func_name); } return 2; } @@ -512,11 +508,11 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { case FAILURE: - phpdbg_notice("Pending breakpoint #%d at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); + phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" method=\"%::%s\" num=\"%ld\"", "Pending breakpoint #%d at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); break; case SUCCESS: - phpdbg_notice("Breakpoint #%d added at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); + phpdbg_notice("breakpoint", "id=\"%d\" method=\"%::%s\" num=\"%ld\"", "Breakpoint #%d added at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); break; case 2: @@ -542,7 +538,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha } if (zend_hash_index_exists(method_table, opline)) { - phpdbg_notice("Breakpoint already exists for %s::%s#%ld", new_break.class_name, new_break.func_name, opline); + phpdbg_error("breakpoint", "type=\"exists\" method=\"%s\" num=\"%ld\"", "Breakpoint already exists for %s::%s#%ld", new_break.class_name, new_break.func_name, opline); efree((char*)new_break.func_name); efree((char*)new_break.class_name); PHPDBG_G(bp_count)--; @@ -571,11 +567,11 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { case FAILURE: - phpdbg_notice("Pending breakpoint #%d at %s#%ld", new_break.id, new_break.func_name, opline); + phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" function=\"%s\" num=\"%ld\"", "Pending breakpoint #%d at %s#%ld", new_break.id, new_break.func_name, opline); break; case SUCCESS: - phpdbg_notice("Breakpoint #%d added at %s#%ld", new_break.id, new_break.func_name, opline); + phpdbg_notice("breakpoint", "id=\"%d\" function=\"%s\" num=\"%ld\"", "Breakpoint #%d added at %s#%ld", new_break.id, new_break.func_name, opline); break; case 2: @@ -592,7 +588,7 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend } if (zend_hash_index_exists(func_table, opline)) { - phpdbg_notice("Breakpoint already exists for %s#%ld", new_break.func_name, opline); + phpdbg_error("breakpoint", "type=\"exists\" function=\"%s\" num=\"%ld\"", "Breakpoint already exists for %s#%ld", new_break.func_name, opline); efree((char*)new_break.func_name); PHPDBG_G(bp_count)--; return; @@ -620,11 +616,11 @@ PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong o switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { case FAILURE: - phpdbg_notice("Pending breakpoint #%d at %s:%ld", new_break.id, new_break.class_name, opline); + phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" file=\"%s\" num=\"%ld\"", "Pending breakpoint #%d at %s:%ld", new_break.id, new_break.class_name, opline); break; case SUCCESS: - phpdbg_notice("Breakpoint #%d added at %s:%ld", new_break.id, new_break.class_name, opline); + phpdbg_notice("breakpoint", "id=\"%d\" file=\"%s\" num=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.class_name, opline); break; case 2: @@ -641,7 +637,7 @@ PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong o } if (zend_hash_index_exists(file_table, opline)) { - phpdbg_notice("Breakpoint already exists for %s:%ld", new_break.class_name, opline); + phpdbg_error("breakpoint", "type=\"exists\" file=\"%s\" num=\"%d\"", "Breakpoint already exists for %s:%ld", new_break.class_name, opline); efree((char*)new_break.class_name); PHPDBG_G(bp_count)--; return; @@ -660,8 +656,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len T zend_ulong hash = zend_hash_func(name, name_len); if (zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash)) { - phpdbg_notice( - "Breakpoint exists for %s", name); + phpdbg_error("breakpoint", "type=\"exists\" opcode=\"%s\"", "Breakpoint exists for %s", name); return; } @@ -674,7 +669,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len T PHPDBG_G(flags) |= PHPDBG_HAS_OPCODE_BP; - phpdbg_notice("Breakpoint #%d added at %s", new_break.id, name); + phpdbg_notice("breakpoint", "id=\"%d\" opcode=\"%s\"", "Breakpoint #%d added at %s", new_break.id, name); PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]); } /* }}} */ @@ -691,16 +686,17 @@ PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRML zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t), NULL); - phpdbg_notice("Breakpoint #%d added at %#lx", - new_break.id, new_break.opline); + phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx", new_break.id, new_break.opline); PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); + } else { + phpdbg_error("breakpoint", "type=\"exists\" opline=\"%#lx\"", "Breakpoint exists for opline %#lx", (zend_ulong) opline); } } /* }}} */ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, const phpdbg_param_t *param, const char *expr, size_t expr_len, zend_ulong hash TSRMLS_DC) /* {{{ */ { phpdbg_breakcond_t new_break; - zend_uint cops = CG(compiler_options); + uint32_t cops = CG(compiler_options); zval pv; PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_COND); @@ -729,8 +725,7 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0'; Z_TYPE(pv) = IS_STRING; - new_break.ops = zend_compile_string( - &pv, "Conditional Breakpoint Code" TSRMLS_CC); + new_break.ops = zend_compile_string(&pv, "Conditional Breakpoint Code" TSRMLS_CC); zval_dtor(&pv); @@ -739,14 +734,12 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co &PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break, sizeof(phpdbg_breakcond_t), (void**)&brake); - phpdbg_notice("Conditional breakpoint #%d added %s/%p", - brake->id, brake->code, brake->ops); + phpdbg_notice("breakpoint", "id=\"%d\" expression=\"%s\" ptr=\"%p\"", "Conditional breakpoint #%d added %s/%p", brake->id, brake->code, brake->ops); PHPDBG_G(flags) |= PHPDBG_HAS_COND_BP; PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_COND]); } else { - phpdbg_error( - "Failed to compile code for expression %s", expr); + phpdbg_error("compile", "expression=\"%s\"", "Failed to compile code for expression %s", expr); efree((char*)new_break.code); PHPDBG_G(bp_count)--; } @@ -762,7 +755,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l phpdbg_create_conditional_break( &new_break, NULL, expr, expr_len, expr_hash TSRMLS_CC); } else { - phpdbg_notice("Conditional break %s exists", expr); + phpdbg_error("breakpoint", "type=\"exists\" expression=\"%s\"", "Conditional break %s exists", expr); } } /* }}} */ @@ -771,21 +764,18 @@ PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param TSRMLS_DC) phpdbg_breakcond_t new_break; phpdbg_param_t *condition; zend_ulong hash = 0L; - + if (param->next) { condition = param->next; hash = zend_inline_hash_func(condition->str, condition->len); - + if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash)) { - phpdbg_create_conditional_break( - &new_break, param, - condition->str, condition->len, hash TSRMLS_CC); + phpdbg_create_conditional_break(&new_break, param, condition->str, condition->len, hash TSRMLS_CC); } else { - phpdbg_notice( - "Conditional break %s exists at the specified location", condition->str); - } + phpdbg_notice("breakpoint", "type=\"exists\" arg=\"%s\"", "Conditional break %s exists at the specified location", condition->str); + } } - + } /* }}} */ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */ @@ -970,7 +960,6 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void*)&bp, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { zval *retval = NULL; - int orig_interactive = CG(interactive); zval **orig_retval = EG(return_value_ptr_ptr); zend_op_array *orig_ops = EG(active_op_array); zend_op **orig_opline = EG(opline_ptr); @@ -995,8 +984,6 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut zend_rebuild_symbol_table(TSRMLS_C); } - CG(interactive) = 0; - zend_try { PHPDBG_G(flags) |= PHPDBG_IN_COND_BP; zend_execute(EG(active_op_array) TSRMLS_CC); @@ -1008,8 +995,6 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut breakpoint = SUCCESS; } } zend_catch { - CG(interactive) = orig_interactive; - EG(no_extensions)=1; EG(return_value_ptr_ptr) = orig_retval; EG(active_op_array) = orig_ops; @@ -1017,8 +1002,6 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP; } zend_end_try(); - CG(interactive) = orig_interactive; - EG(no_extensions)=1; EG(return_value_ptr_ptr) = orig_retval; EG(active_op_array) = orig_ops; @@ -1092,7 +1075,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ if ((brake = phpdbg_find_breakbase_ex(num, &table, &position TSRMLS_CC))) { char *key; - zend_uint klen; + uint32_t klen; zend_ulong idx; int type = brake->type; char *name = NULL; @@ -1148,10 +1131,10 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ break; } - phpdbg_notice("Deleted breakpoint #%ld", num); + phpdbg_notice("breakpoint", "deleted=\"deleted\" id=\"%ld\"", "Deleted breakpoint #%ld", num); PHPDBG_BREAK_UNMAPPING(num); } else { - phpdbg_error("Failed to find breakpoint #%ld", num); + phpdbg_error("breakpoint", "type=\"nobreakpoint\" id=\"%ld\"", "Failed to find breakpoint #%ld", num); } } /* }}} */ @@ -1189,7 +1172,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* switch (brake->type) { case PHPDBG_BREAK_FILE: { - phpdbg_notice("Breakpoint #%d at %s:%ld, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d at %s:%ld, hits: %lu", ((phpdbg_breakfile_t*)brake)->id, ((phpdbg_breakfile_t*)brake)->filename, ((phpdbg_breakfile_t*)brake)->line, @@ -1197,7 +1180,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_SYM: { - phpdbg_notice("Breakpoint #%d in %s() at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" function=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s() at %s:%u, hits: %lu", ((phpdbg_breaksymbol_t*)brake)->id, ((phpdbg_breaksymbol_t*)brake)->symbol, zend_get_executed_filename(TSRMLS_C), @@ -1206,7 +1189,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_OPLINE: { - phpdbg_notice("Breakpoint #%d in %#lx at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%#lx\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %#lx at %s:%u, hits: %lu", ((phpdbg_breakline_t*)brake)->id, ((phpdbg_breakline_t*)brake)->opline, zend_get_executed_filename(TSRMLS_C), @@ -1215,7 +1198,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_METHOD_OPLINE: { - phpdbg_notice("Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" method=\"%s::%s\" opline=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->func_name, @@ -1226,7 +1209,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_FUNCTION_OPLINE: { - phpdbg_notice("Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%lu\" function=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num, @@ -1236,9 +1219,8 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_FILE_OPLINE: { - phpdbg_notice("Breakpoint #%d in %s:%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in #%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, - ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->opline_num, zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C), @@ -1246,7 +1228,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_OPCODE: { - phpdbg_notice("Breakpoint #%d in %s at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" opcode=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s at %s:%u, hits: %lu", ((phpdbg_breakop_t*)brake)->id, ((phpdbg_breakop_t*)brake)->name, zend_get_executed_filename(TSRMLS_C), @@ -1255,7 +1237,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_METHOD: { - phpdbg_notice("Breakpoint #%d in %s::%s() at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" method=\"%s::%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s::%s() at %s:%u, hits: %lu", ((phpdbg_breakmethod_t*)brake)->id, ((phpdbg_breakmethod_t*)brake)->class_name, ((phpdbg_breakmethod_t*)brake)->func_name, @@ -1267,7 +1249,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* case PHPDBG_BREAK_COND: { if (((phpdbg_breakcond_t*)brake)->paramed) { char *param; - phpdbg_notice("Conditional breakpoint #%d: at %s if %s %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" location=\"%s\" eval=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Conditional breakpoint #%d: at %s if %s at %s:%u, hits: %lu", ((phpdbg_breakcond_t*)brake)->id, phpdbg_param_tostring(&((phpdbg_breakcond_t*)brake)->param, ¶m TSRMLS_CC), ((phpdbg_breakcond_t*)brake)->code, @@ -1277,7 +1259,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* if (param) free(param); } else { - phpdbg_notice("Conditional breakpoint #%d: on %s == true %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" eval=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Conditional breakpoint #%d: on %s == true at %s:%u, hits: %lu", ((phpdbg_breakcond_t*)brake)->id, ((phpdbg_breakcond_t*)brake)->code, zend_get_executed_filename(TSRMLS_C), @@ -1289,7 +1271,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* default: { unknown: - phpdbg_notice("Unknown breakpoint at %s:%u", + phpdbg_notice("breakpoint", "id=\"\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Unknown breakpoint at %s:%u", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C)); } @@ -1350,17 +1332,19 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ { + phpdbg_xml(""); + switch (type) { case PHPDBG_BREAK_SYM: if ((PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP)) { HashPosition position; phpdbg_breaksymbol_t *brake; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Function Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Function Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position)) { - phpdbg_writeln("#%d\t\t%s%s", + phpdbg_writeln("function", "id=\"%d\" name=\"%s\" disabled=\"%s\"", "#%d\t\t%s%s", brake->id, brake->symbol, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } @@ -1370,11 +1354,11 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *class_table; char *class_name = NULL; - zend_uint class_len = 0; + uint32_t class_len = 0; zend_ulong class_idx = 0L; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Method Breakpoints:"); + phpdbg_out(SEPARATE); + phpdbg_out("Method Breakpoints:"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**) &class_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) { @@ -1386,7 +1370,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]); zend_hash_get_current_data_ex(class_table, (void**)&brake, &position[1]) == SUCCESS; zend_hash_move_forward_ex(class_table, &position[1])) { - phpdbg_writeln("#%d\t\t%s::%s%s", + phpdbg_writeln("method", "id=\"%d\" name=\"%s::%s\" disabled=\"%s\"", "#%d\t\t%s::%s%s", brake->id, brake->class_name, brake->func_name, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } @@ -1399,8 +1383,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *points; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("File Breakpoints:"); + phpdbg_out(SEPARATE); + phpdbg_out("File Breakpoints:"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**) &points, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) { @@ -1409,7 +1393,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ for (zend_hash_internal_pointer_reset_ex(points, &position[1]); zend_hash_get_current_data_ex(points, (void**)&brake, &position[1]) == SUCCESS; zend_hash_move_forward_ex(points, &position[1])) { - phpdbg_writeln("#%d\t\t%s:%lu%s", + phpdbg_writeln("file", "id=\"%d\" name=\"%s\" line=\"%lu\" disabled=\"%s\"", "#%d\t\t%s:%lu%s", brake->id, brake->filename, brake->line, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } @@ -1421,8 +1405,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakline_t *brake; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Opline Breakpoints:"); + phpdbg_out(SEPARATE); + phpdbg_out("Opline Breakpoints:"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) { @@ -1430,7 +1414,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ case PHPDBG_BREAK_METHOD_OPLINE: case PHPDBG_BREAK_FUNCTION_OPLINE: case PHPDBG_BREAK_FILE_OPLINE: - phpdbg_writeln("#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline, + phpdbg_out("opline", "id=\"%d\" num=\"%#lx\" type=\"%s\" disabled=\"%s\"", "#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline, brake->type == PHPDBG_BREAK_METHOD_OPLINE?"method": brake->type == PHPDBG_BREAK_FUNCTION_OPLINE?"function": brake->type == PHPDBG_BREAK_FILE_OPLINE?"file": @@ -1439,7 +1423,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ break; default: - phpdbg_writeln("#%d\t\t%#lx", brake->id, brake->opline); + phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" disabled=\"%s\"", "#%d\t\t%#lx%s", brake->id, brake->opline, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); break; } } @@ -1449,11 +1433,11 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[3]; HashTable *class_table, *method_table; char *class_name = NULL, *method_name = NULL; - zend_uint class_len = 0, method_len = 0; + uint32_t class_len = 0, method_len = 0; zend_ulong class_idx = 0L, method_idx = 0L; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Method opline Breakpoints:"); + phpdbg_out(SEPARATE); + phpdbg_out("Method opline Breakpoints:"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) { @@ -1473,7 +1457,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ for (zend_hash_internal_pointer_reset_ex(method_table, &position[2]); zend_hash_get_current_data_ex(method_table, (void**)&brake, &position[2]) == SUCCESS; zend_hash_move_forward_ex(method_table, &position[2])) { - phpdbg_writeln("#%d\t\t%s::%s opline %ld%s", + phpdbg_writeln("methodopline", "id=\"%d\" name=\"%s::%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s::%s opline %ld%s", brake->id, brake->class_name, brake->func_name, brake->opline_num, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } @@ -1488,11 +1472,11 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *function_table; char *function_name = NULL; - zend_uint function_len = 0; + uint32_t function_len = 0; zend_ulong function_idx = 0L; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Function opline Breakpoints:"); + phpdbg_out(SEPARATE); + phpdbg_out("Function opline Breakpoints:"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) { @@ -1505,7 +1489,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ for (zend_hash_internal_pointer_reset_ex(function_table, &position[1]); zend_hash_get_current_data_ex(function_table, (void**)&brake, &position[1]) == SUCCESS; zend_hash_move_forward_ex(function_table, &position[1])) { - phpdbg_writeln("#%d\t\t%s opline %ld%s", + phpdbg_writeln("functionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s", brake->id, brake->func_name, brake->opline_num, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } @@ -1518,11 +1502,11 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *file_table; char *file_name = NULL; - zend_uint file_len = 0; + uint32_t file_len = 0; zend_ulong file_idx = 0L; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("File opline Breakpoints:"); + phpdbg_out(SEPARATE); + phpdbg_out("File opline Breakpoints:"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) { @@ -1535,7 +1519,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ for (zend_hash_internal_pointer_reset_ex(file_table, &position[1]); zend_hash_get_current_data_ex(file_table, (void**)&brake, &position[1]) == SUCCESS; zend_hash_move_forward_ex(file_table, &position[1])) { - phpdbg_writeln("#%d\t\t%s opline %ld%s", + phpdbg_writeln("fileopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s", brake->id, brake->class_name, brake->opline_num, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } @@ -1547,15 +1531,15 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakcond_t *brake; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Conditional Breakpoints:"); + phpdbg_out(SEPARATE); + phpdbg_out("Conditional Breakpoints:"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { if (brake->paramed) { switch (brake->param.type) { case STR_PARAM: - phpdbg_writeln("#%d\t\tat %s if %s%s", + phpdbg_writeln("evalfunction", "id=\"%d\" name=\"%s\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s if %s%s", brake->id, brake->param.str, brake->code, @@ -1563,7 +1547,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ break; case NUMERIC_FUNCTION_PARAM: - phpdbg_writeln("#%d\t\tat %s#%ld if %s%s", + phpdbg_writeln("evalfunctionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s#%ld if %s%s", brake->id, brake->param.str, brake->param.num, @@ -1572,7 +1556,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ break; case METHOD_PARAM: - phpdbg_writeln("#%d\t\tat %s::%s if %s%s", + phpdbg_writeln("evalmethod", "id=\"%d\" name=\"%s::%s\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s::%s if %s%s", brake->id, brake->param.method.class, brake->param.method.name, @@ -1581,7 +1565,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ break; case NUMERIC_METHOD_PARAM: - phpdbg_writeln("#%d\t\tat %s::%s#%ld if %s%s", + phpdbg_writeln("evalmethodopline", "id=\"%d\" name=\"%s::%s\" num=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s::%s#%ld if %s%s", brake->id, brake->param.method.class, brake->param.method.name, @@ -1591,7 +1575,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ break; case FILE_PARAM: - phpdbg_writeln("#%d\t\tat %s:%lu if %s%s", + phpdbg_writeln("evalfile", "id=\"%d\" name=\"%s\" line=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s:%lu if %s%s", brake->id, brake->param.file.name, brake->param.file.line, @@ -1600,7 +1584,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ break; case ADDR_PARAM: - phpdbg_writeln("#%d\t\tat #%lx if %s%s", + phpdbg_writeln("evalopline", "id=\"%d\" opline=\"%#lx\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat #%lx if %s%s", brake->id, brake->param.addr, brake->code, @@ -1608,11 +1592,11 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ break; default: - phpdbg_error("Invalid parameter type for conditional breakpoint"); + phpdbg_error("eval", "type=\"invalidparameter\"", "Invalid parameter type for conditional breakpoint"); return; } } else { - phpdbg_writeln("#%d\t\tif %s%s", + phpdbg_writeln("eval", "id=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tif %s%s", brake->id, brake->code, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } @@ -1623,15 +1607,17 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakop_t *brake; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Opcode Breakpoints:"); + phpdbg_out(SEPARATE); + phpdbg_out("Opcode Breakpoints:"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) { - phpdbg_writeln("#%d\t\t%s%s", + phpdbg_writeln("opcode", "id=\"%d\" name=\"%s\" disabled=\"%s\"", "#%d\t\t%s%s", brake->id, brake->name, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } } break; } + + phpdbg_xml(""); } /* }}} */ diff --git a/phpdbg_bp.h b/phpdbg_bp.h index 97980e7ed78..a6227cba6c9 100644 --- a/phpdbg_bp.h +++ b/phpdbg_bp.h @@ -21,6 +21,19 @@ #ifndef PHPDBG_BP_H #define PHPDBG_BP_H +/* {{{ defines */ +#define PHPDBG_BREAK_FILE 0 +#define PHPDBG_BREAK_SYM 1 +#define PHPDBG_BREAK_OPLINE 2 +#define PHPDBG_BREAK_METHOD 3 +#define PHPDBG_BREAK_COND 4 +#define PHPDBG_BREAK_OPCODE 5 +#define PHPDBG_BREAK_FUNCTION_OPLINE 6 +#define PHPDBG_BREAK_METHOD_OPLINE 7 +#define PHPDBG_BREAK_FILE_OPLINE 8 +#define PHPDBG_BREAK_MAP 9 +#define PHPDBG_BREAK_TABLES 10 /* }}} */ + /* {{{ */ typedef struct _zend_op *phpdbg_opline_ptr_t; /* }}} */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index a45513bee6b..587007e9008 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -39,7 +39,7 @@ static inline const char *phpdbg_command_name(const phpdbg_command_t *command, c memcpy(&buffer[pos], command->name, command->name_len); pos += command->name_len; buffer[pos] = 0; - + return buffer; } @@ -231,12 +231,12 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des case STACK_PARAM: /* nope */ break; - + case STR_PARAM: dest->str = estrndup(src->str, src->len); dest->len = src->len; break; - + case OP_PARAM: dest->str = estrndup(src->str, src->len); dest->len = src->len; @@ -276,7 +276,7 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des break; case EMPTY_PARAM: { /* do nothing */ } break; - + default: { /* not yet */ } @@ -291,7 +291,7 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) / case STACK_PARAM: /* nope */ break; - + case STR_PARAM: hash += zend_inline_hash_func(param->str, param->len); break; @@ -329,7 +329,7 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) / break; case EMPTY_PARAM: { /* do nothing */ } break; - + default: { /* not yet */ } @@ -347,7 +347,7 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa /* nope, or yep */ return 1; break; - + case NUMERIC_FUNCTION_PARAM: if (l->num != r->num) { break; @@ -402,7 +402,7 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa case EMPTY_PARAM: return 1; - + default: { /* not yet */ } @@ -419,43 +419,43 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) case STR_PARAM: fprintf(stderr, "%s STR_PARAM(%s=%lu)\n", msg, param->str, param->len); break; - + case ADDR_PARAM: fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); break; - + case NUMERIC_FILE_PARAM: fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#%lu)\n", msg, param->file.name, param->file.line); break; - + case FILE_PARAM: fprintf(stderr, "%s FILE_PARAM(%s:%lu)\n", msg, param->file.name, param->file.line); break; - + case METHOD_PARAM: fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); break; - + case NUMERIC_METHOD_PARAM: fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); break; - + case NUMERIC_FUNCTION_PARAM: fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%ld)\n", msg, param->str, param->num); break; - + case NUMERIC_PARAM: fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); break; - + case COND_PARAM: fprintf(stderr, "%s COND_PARAM(%s=%lu)\n", msg, param->str, param->len); break; - + case OP_PARAM: fprintf(stderr, "%s OP_PARAM(%s=%lu)\n", msg, param->str, param->len); break; - + default: { /* not yet */ } @@ -467,13 +467,13 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { if (stack && stack->next) { phpdbg_param_t *remove = stack->next; - + while (remove) { phpdbg_param_t *next = NULL; - + if (remove->next) next = remove->next; - + switch (remove->type) { case NUMERIC_METHOD_PARAM: case METHOD_PARAM: @@ -487,29 +487,30 @@ PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { case STR_PARAM: case OP_PARAM: if (remove->str) - free(remove->str); + free(remove->str); break; - + case NUMERIC_FILE_PARAM: case FILE_PARAM: if (remove->file.name) free(remove->file.name); break; - + default: { /* nothing */ } } - + free(remove); remove = NULL; - + if (next) - remove = next; + remove = next; else break; } } - + + stack->next = NULL; } /* }}} */ @@ -537,30 +538,29 @@ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) stack->len++; } /* }}} */ -PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC) { +PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack TSRMLS_DC) { if (command) { char buffer[128] = {0,}; const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL; const char *arg = command->args; size_t least = 0L, - received = 0L, - current = 0L; + received = 0L, + current = 0L; zend_bool optional = 0; - + /* check for arg spec */ if (!(arg) || !(*arg)) { if (!top) { return SUCCESS; } - - asprintf(why, - "The command \"%s\" expected no arguments", + + phpdbg_error("command", "type=\"toomanyargs\" command=\"%s\" expected=\"0\"", "The command \"%s\" expected no arguments", phpdbg_command_name(command, buffer)); return FAILURE; } - + least = 0L; - + /* count least amount of arguments */ while (arg && *arg) { if (arg[0] == '|') { @@ -569,21 +569,19 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param least++; arg++; } - + arg = command->args; #define verify_arg(e, a, t) if (!(a)) { \ if (!optional) { \ - asprintf(why, \ - "The command \"%s\" expected %s and got nothing at parameter %lu", \ + phpdbg_error("command", "type=\"noarg\" command=\"%s\" expected=\"%s\" num=\"%lu\"", "The command \"%s\" expected %s and got nothing at parameter %lu", \ phpdbg_command_name(command, buffer), \ (e), \ current); \ return FAILURE;\ } \ } else if ((a)->type != (t)) { \ - asprintf(why, \ - "The command \"%s\" expected %s and got %s at parameter %lu", \ + phpdbg_error("command", "type=\"wrongarg\" command=\"%s\" expected=\"%s\" got=\"%s\" num=\"%lu\"", "The command \"%s\" expected %s and got %s at parameter %lu", \ phpdbg_command_name(command, buffer), \ (e),\ phpdbg_get_param_type((a) TSRMLS_CC), \ @@ -593,14 +591,14 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param while (arg && *arg) { current++; - + switch (*arg) { case '|': { current--; optional = 1; arg++; } continue; - + case 'i': verify_arg("raw input", top, STR_PARAM); break; case 's': verify_arg("string", top, STR_PARAM); break; case 'n': verify_arg("number", top, NUMERIC_PARAM); break; @@ -610,14 +608,14 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param case 'c': verify_arg("condition", top, COND_PARAM); break; case 'o': verify_arg("opcode", top, OP_PARAM); break; case 'b': verify_arg("boolean", top, NUMERIC_PARAM); break; - + case '*': { /* do nothing */ } break; } - + if (top ) { top = top->next; } else break; - + received++; arg++; } @@ -625,26 +623,25 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param #undef verify_arg if ((received < least)) { - asprintf(why, - "The command \"%s\" expected at least %lu arguments (%s) and received %lu", + phpdbg_error("command", "type=\"toofewargs\" command=\"%s\" expected=\"%d\" argtypes=\"%s\" got=\"%d\"", "The command \"%s\" expected at least %lu arguments (%s) and received %lu", phpdbg_command_name(command, buffer), least, - command->args, + command->args, received); return FAILURE; } } - + return SUCCESS; } /* {{{ */ -PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why) { +PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top TSRMLS_DC) { const phpdbg_command_t *command = commands; phpdbg_param_t *name = *top; const phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; ulong matches = 0L; - + while (command && command->name && command->handler) { if ((name->len == 1) || (command->name_len >= name->len)) { /* match single letter alias */ @@ -654,85 +651,79 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * matches++; } } else { - /* match full, case insensitive, command name */ if (strncasecmp(command->name, name->str, name->len) == SUCCESS) { if (matches < 3) { - /* only allow abbreviating commands that can be aliased */ if (((name->len != command->name_len) && command->alias) || (name->len == command->name_len)) { matched[matches] = command; matches++; } - - + /* exact match */ if (name->len == command->name_len) break; - } else break; + } else { + break; + } } } } - + command++; } - + switch (matches) { - case 0: { + case 0: if (parent) { - asprintf( - why, - "The command \"%s %s\" could not be found", - parent->name, name->str); - } else asprintf( - why, - "The command \"%s\" could not be found", - name->str); - } return parent; - - case 1: { + phpdbg_error("command", "type=\"notfound\" command=\"%s\" subcommand=\"%s\"", "The command \"%s %s\" could not be found", + parent->name, name->str); + } else { + phpdbg_error("command", "type=\"notfound\" command=\"%s\"", "The command \"%s\" could not be found", + name->str); + } + return parent; + + case 1: (*top) = (*top)->next; command = matched[0]; - } break; - + break; + default: { char *list = NULL; - zend_uint it = 0; + uint32_t it = 0; size_t pos = 0; - + while (it < matches) { if (!list) { - list = malloc( - matched[it]->name_len + 1 + - ((it+1) < matches ? sizeof(", ")-1 : 0)); + list = emalloc(matched[it]->name_len + 1 + ((it + 1) < matches ? sizeof(", ") - 1 : 0)); } else { - list = realloc(list, - (pos + matched[it]->name_len) + 1 + - ((it+1) < matches ? sizeof(", ")-1 : 0)); + list = erealloc(list, (pos + matched[it]->name_len) + 1 + ((it + 1) < matches ? sizeof(", ") - 1 : 0)); } memcpy(&list[pos], matched[it]->name, matched[it]->name_len); pos += matched[it]->name_len; - if ((it+1) < matches) { - memcpy(&list[pos], ", ", sizeof(", ")-1); + if ((it + 1) < matches) { + memcpy(&list[pos], ", ", sizeof(", ") - 1); pos += (sizeof(", ") - 1); } - + list[pos] = 0; it++; } - - asprintf( - why, - "The command \"%s\" is ambigious, matching %lu commands (%s)", + + /* ", " separated matches */ + phpdbg_error("command", "type=\"ambiguous\" command=\"%s\" matches=\"%lu\" matched=\"%s\"", "The command \"%s\" is ambigious, matching %lu commands (%s)", name->str, matches, list); - free(list); - } return NULL; + efree(list); + + return NULL; + } } if (command->subs && (*top) && ((*top)->type == STR_PARAM)) { - return phpdbg_stack_resolve(command->subs, command, top, why); + return phpdbg_stack_resolve(command->subs, command, top TSRMLS_CC); } else { return command; } @@ -741,55 +732,51 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * } /* }}} */ /* {{{ */ -PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC) { +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack TSRMLS_DC) { phpdbg_param_t *top = NULL; const phpdbg_command_t *handler = NULL; - + if (stack->type != STACK_PARAM) { - asprintf( - why, "The passed argument was not a stack !!"); + phpdbg_error("command", "type=\"nostack\"", "The passed argument was not a stack !"); return FAILURE; } - + if (!stack->len) { - asprintf( - why, "The stack contains nothing !!"); + phpdbg_error("command", "type=\"emptystack\"", "The stack contains nothing !"); return FAILURE; } - + top = (phpdbg_param_t*) stack->next; - + switch (top->type) { case EVAL_PARAM: return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); case RUN_PARAM: return PHPDBG_COMMAND_HANDLER(run)(top TSRMLS_CC); - + case SHELL_PARAM: return PHPDBG_COMMAND_HANDLER(sh)(top TSRMLS_CC); - + case STR_PARAM: { - handler = phpdbg_stack_resolve( - phpdbg_prompt_commands, NULL, &top, why); - + handler = phpdbg_stack_resolve(phpdbg_prompt_commands, NULL, &top TSRMLS_CC); + if (handler) { - if (phpdbg_stack_verify(handler, &top, why TSRMLS_CC) == SUCCESS) { + if (phpdbg_stack_verify(handler, &top TSRMLS_CC) == SUCCESS) { return handler->handler(top TSRMLS_CC); } } } return FAILURE; - + default: - asprintf( - why, "The first parameter makes no sense !!"); + phpdbg_error("command", "type=\"invalidcommand\"", "The first parameter makes no sense !"); return FAILURE; } - + return SUCCESS; } /* }}} */ -PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ +PHPDBG_API char *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ { char *cmd = NULL; #if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT) @@ -804,8 +791,8 @@ PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ } if (buffered == NULL) { -disconnect: if (0) { +disconnect: PHPDBG_G(flags) |= (PHPDBG_IS_QUITTING|PHPDBG_IS_DISCONNECTED); zend_bailout(); return NULL; @@ -813,13 +800,13 @@ disconnect: #if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT) if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { - if (!phpdbg_write("%s", phpdbg_get_prompt(TSRMLS_C))) { + if (!phpdbg_out("%s", phpdbg_get_prompt(TSRMLS_C))) { goto disconnect; } } - + /* note: EOF is ignored */ -readline: +readline: if (!fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) { /* the user has gone away */ if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { @@ -847,7 +834,7 @@ readline: } #endif } else cmd = buffered; - + buffer = estrdup(cmd); #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT) @@ -878,7 +865,7 @@ readline: buffer = estrdup(PHPDBG_G(buffer)); } } - + return buffer; } /* }}} */ diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 571d065f59d..43905606135 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -98,7 +98,7 @@ struct _phpdbg_command_t { phpdbg_command_handler_t handler; /* Command handler */ const phpdbg_command_t *subs; /* Sub Commands */ char *args; /* Argument Spec */ - const phpdbg_command_t *parent; /* Parent Command */ + const phpdbg_command_t *parent; /* Parent Command */ }; /* }}} */ @@ -106,7 +106,7 @@ struct _phpdbg_command_t { #define PHPDBG_STRL(s) s, sizeof(s)-1 #define PHPDBG_MAX_CMD 500 #define PHPDBG_FRAME(v) (PHPDBG_G(frame).v) -#define PHPDBG_EX(v) (EG(current_execute_data)->v) +#define PHPDBG_EX(v) (EG(current_execute_data)->v) typedef struct { int num; @@ -133,9 +133,9 @@ PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); * Stack Management */ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param); -PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why); -PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC); -PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC); +PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top TSRMLS_DC); +PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack TSRMLS_DC); +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack TSRMLS_DC); PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack); /* @@ -175,7 +175,7 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) */ #define phpdbg_default_switch_case() \ default: \ - phpdbg_error("Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); \ + phpdbg_error("command", "type=\"wrongarg\" got=\"%s\"", "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); \ break #endif /* PHPDBG_CMD_H */ diff --git a/phpdbg_frame.c b/phpdbg_frame.c index a235fe8cb04..8c7b1084ea9 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -52,7 +52,7 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ int i = 0; if (PHPDBG_FRAME(num) == frame) { - phpdbg_notice("Already in frame #%d", frame); + phpdbg_notice("frame", "id=\"%d\"", "Already in frame #%d", frame); return; } @@ -67,7 +67,7 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ } if (execute_data == NULL) { - phpdbg_error("No frame #%d", frame); + phpdbg_error("frame", "type=\"maxnum\" id=\"%d\"", "No frame #%d", frame); return; } @@ -90,7 +90,7 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ EG(called_scope) = PHPDBG_EX(current_called_scope); } - phpdbg_notice("Switched to frame #%d", frame); + phpdbg_notice("frame", "id=\"%d\"", "Switched to frame #%d", frame); phpdbg_list_file( zend_get_executed_filename(TSRMLS_C), 3, @@ -114,14 +114,19 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ (void **)&class); } else { zend_get_object_classname(*class, (const char **)&Z_STRVAL_PP(class), - (zend_uint *)&Z_STRLEN_PP(class) TSRMLS_CC); + (uint32_t *)&Z_STRLEN_PP(class) TSRMLS_CC); } if (is_class == SUCCESS) { zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type); } - phpdbg_write("%s%s%s(", + phpdbg_xml(" symbol=\"%s%s%s\"", + is_class == FAILURE?"":Z_STRVAL_PP(class), + is_class == FAILURE?"":Z_STRVAL_PP(type), + Z_STRVAL_PP(funcname) + ); + phpdbg_out("%s%s%s(", is_class == FAILURE?"":Z_STRVAL_PP(class), is_class == FAILURE?"":Z_STRVAL_PP(type), Z_STRVAL_PP(funcname) @@ -136,29 +141,41 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ int j = 0, m = func ? func->common.num_args : 0; zend_bool is_variadic = 0; + phpdbg_xml(">"); + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { if (j) { - phpdbg_write(", "); + phpdbg_out(", "); } + phpdbg_xml("= 50600 is_variadic = arginfo[j].is_variadic; #endif - phpdbg_write("%s=%s", + phpdbg_xml(" variadic=\"%s\" name=\"%s\"", is_variadic ? "variadic" : "", arginfo[j].name); + + phpdbg_out("%s=%s", arginfo[j].name, is_variadic ? "[": ""); } ++j; + phpdbg_xml(">"); + zend_print_flat_zval_r(*argstmp TSRMLS_CC); zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); + + phpdbg_xml(""); } if (is_variadic) { - phpdbg_write("]"); + phpdbg_out("]"); } + phpdbg_xml(""); + } else { + phpdbg_xml(" />"); } - phpdbg_write(")"); + phpdbg_out(")"); } void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ @@ -171,9 +188,11 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ int user_defined; if (limit < 0) { - phpdbg_error("Invalid backtrace size %d", limit); + phpdbg_error("backtrace", "type=\"minnum\"", "Invalid backtrace size %d", limit); } + phpdbg_xml(""); + zend_fetch_debug_backtrace( &zbacktrace, 0, 0, limit TSRMLS_CC); @@ -186,21 +205,25 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position) == FAILURE) { - phpdbg_write("frame #%d: {main} at %s:%ld", i, Z_STRVAL_PP(file), Z_LVAL_PP(line)); + phpdbg_write("frame", "id=\"%d\" symbol=\"{main}\" file=\"%s\" line=\"%d\"", "frame #%d: {main} at %s:%ld", i, Z_STRVAL_PP(file), Z_LVAL_PP(line)); break; } if (user_defined == SUCCESS) { - phpdbg_write("frame #%d: ", i++); + phpdbg_xml(" "); + phpdbg_xml(" "); phpdbg_dump_prototype(tmp TSRMLS_CC); - phpdbg_writeln(" (internal function)"); + phpdbg_out(" (internal function)\n"); } } - phpdbg_writeln(EMPTY); + phpdbg_out("\n"); zval_dtor(&zbacktrace); + + phpdbg_xml(""); } /* }}} */ diff --git a/phpdbg_help.c b/phpdbg_help.c index 3244b653ef9..5ff7712d2d3 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -61,6 +61,11 @@ void pretty_print(char *text TSRMLS_DC) unsigned int last_blank_count = 0; /* printable char offset of last blank char */ unsigned int line_count = 0; /* number printable chars on current line */ + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + phpdbg_xml("", text); + return; + } + /* First pass calculates a safe size for the pretty print version */ for (p = text; *p; p++) { if (UNEXPECTED(p[0] == '*') && p[1] == '*') { @@ -128,10 +133,10 @@ void pretty_print(char *text TSRMLS_DC) *q++ = '\0'; if ((q-new)>size) { - phpdbg_error("Output overrun of %lu bytes", ((q-new) - size)); + phpdbg_error("help", "overrun=\"%lu\"", "Output overrun of %lu bytes", ((q-new) - size)); } - phpdbg_write("%s\n", new); + phpdbg_out("%s", new); efree(new); } /* }}} */ @@ -201,7 +206,7 @@ static int get_command( return num_matches; -} /* }}} */ +} /* }}} */ PHPDBG_COMMAND(help) /* {{{ */ { @@ -231,7 +236,7 @@ PHPDBG_COMMAND(help) /* {{{ */ pretty_print(get_help("duplicate!" TSRMLS_CC) TSRMLS_CC); return SUCCESS; } else { - phpdbg_error("Internal help error, non-unique alias \"%c\"", param->str[0]); + phpdbg_error("help", "type=\"ambiguousalias\" alias=\"%s\"", "Internal help error, non-unique alias \"%c\"", param->str[0]); return FAILURE; } @@ -259,34 +264,41 @@ PHPDBG_HELP(aliases) /* {{{ */ int len; /* Print out aliases for all commands except help as this one comes last */ - phpdbg_writeln("Below are the aliased, short versions of all supported commands"); + phpdbg_writeln("help", "", "Below are the aliased, short versions of all supported commands"); + phpdbg_xml(""); for(c = phpdbg_prompt_commands; c->name; c++) { if (c->alias && c->alias != 'h') { - phpdbg_writeln(" %c %-20s %s", c->alias, c->name, c->tip); + phpdbg_writeln("command", "name=\"%s\" alias=\"%c\" tip=\"%s\"", " %c %-20s %s", c->alias, c->name, c->tip); if (c->subs) { len = 20 - 1 - c->name_len; for(c_sub = c->subs; c_sub->alias; c_sub++) { if (c_sub->alias) { - phpdbg_writeln(" %c %c %s %-*s %s", - c->alias, c_sub->alias, (char *)c->name, len, c_sub->name, c_sub->tip); + phpdbg_writeln("subcommand", "parent_alias=\"%c\" alias=\"%c\" parent=\"%s\" name=\"%-*s\" tip=\"%s\"", " %c %c %s %-*s %s", + c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip); } } } } } + phpdbg_xml(""); + /* Print out aliases for help as this one comes last, with the added text on how aliases are used */ get_command("h", 1, &c, phpdbg_prompt_commands TSRMLS_CC); - phpdbg_writeln(" %c %-20s %s\n", c->alias, c->name, c->tip); + phpdbg_writeln("aliasinfo", "alias=\"%c\" name=\"%-*s\" tip=\"%s\"", " %c %-20s %s\n", c->alias, c->name, c->tip); + + phpdbg_xml(""); len = 20 - 1 - c->name_len; for(c_sub = c->subs; c_sub->alias; c_sub++) { if (c_sub->alias) { - phpdbg_writeln(" %c %c %s %-*s %s", + phpdbg_writeln("alias", "parent_alias=\"%c\" alias=\"%c\" parent=\"%s\" name=\"%-*s\" tip=\"%s\"", " %c %c %s %-*s %s", c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip); } } + phpdbg_xml(""); + pretty_print(get_help("aliases!" TSRMLS_CC) TSRMLS_CC); return SUCCESS; } /* }}} */ @@ -362,7 +374,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **-c** **-c**/my/php.ini Set php.ini file to load" CR " **-d** **-d**memory_limit=4G Set a php.ini directive" CR " **-n** Disable default php.ini" CR -" **-q** Supress welcome banner" CR +" **-q** Suppress welcome banner" CR " **-v** Enable oplog output" CR " **-s** Enable stepping" CR " **-b** Disable colour" CR @@ -543,7 +555,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P break ZEND_ADD" CR " $P b ZEND_ADD" CR -" Break on any occurence of the opcode ZEND_ADD" CR CR +" Break on any occurrence of the opcode ZEND_ADD" CR CR " $P break del 2" CR " $P b ~ 2" CR diff --git a/phpdbg_help.h b/phpdbg_help.h index 16a1e771e37..4a433fda6cf 100644 --- a/phpdbg_help.h +++ b/phpdbg_help.h @@ -35,9 +35,9 @@ PHPDBG_HELP(aliases); extern const phpdbg_command_t phpdbg_help_commands[]; #define phpdbg_help_header() \ - phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION); + phpdbg_notice("version", "version=\"%s\"", "Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION); #define phpdbg_help_footer() \ - phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES); + phpdbg_notice("issues", "url=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES); typedef struct _phpdbg_help_text_t { char *key; diff --git a/phpdbg_info.c b/phpdbg_info.c index 97f88bfa1ec..258d14a44a8 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -62,13 +62,13 @@ PHPDBG_INFO(files) /* {{{ */ HashPosition pos; char *fname; - phpdbg_notice("Included files: %d", + phpdbg_notice("includedfilecount", "num=\"%d\"", "Included files: %d", zend_hash_num_elements(&EG(included_files))); zend_hash_internal_pointer_reset_ex(&EG(included_files), &pos); while (zend_hash_get_current_key_ex(&EG(included_files), &fname, NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { - phpdbg_writeln("File: %s", fname); + phpdbg_writeln("includedfile", "name=\"%s\"", "File: %s", fname); zend_hash_move_forward_ex(&EG(included_files), &pos); } @@ -78,10 +78,10 @@ PHPDBG_INFO(files) /* {{{ */ PHPDBG_INFO(error) /* {{{ */ { if (PG(last_error_message)) { - phpdbg_writeln("Last error: %s at %s line %d", + phpdbg_writeln("lasterror", "error=\"%s\" file=\"%s\" line=\"%d\"", "Last error: %s at %s line %d", PG(last_error_message), PG(last_error_file), PG(last_error_lineno)); } else { - phpdbg_notice("No error found!"); + phpdbg_notice("lasterror", "error=\"\"", "No error found!"); } return SUCCESS; } /* }}} */ @@ -94,7 +94,7 @@ PHPDBG_INFO(vars) /* {{{ */ zval **data; if (!EG(active_op_array)) { - phpdbg_error("No active op array!"); + phpdbg_error("inactive", "type=\"op_array\"", "No active op array!"); return SUCCESS; } @@ -102,7 +102,7 @@ PHPDBG_INFO(vars) /* {{{ */ zend_rebuild_symbol_table(TSRMLS_C); if (!EG(active_symbol_table)) { - phpdbg_error("No active symbol table!"); + phpdbg_error("inactive", "type=\"symbol_table\"", "No active symbol table!"); return SUCCESS; } } @@ -122,28 +122,24 @@ PHPDBG_INFO(vars) /* {{{ */ { zend_op_array *ops = EG(active_op_array); - + if (ops->function_name) { if (ops->scope) { - phpdbg_notice( - "Variables in %s::%s() (%d)", ops->scope->name, ops->function_name, zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "method=\"%s::%s\" count=\"%d\"", "Variables in %s::%s() (%d)", ops->scope->name, ops->function_name, zend_hash_num_elements(&vars)); } else { - phpdbg_notice( - "Variables in %s() (%d)", ops->function_name, zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "function=\"%s\" count=\"%d\"", "Variables in %s() (%d)", ops->function_name, zend_hash_num_elements(&vars)); } } else { if (ops->filename) { - phpdbg_notice( - "Variables in %s (%d)", ops->filename, zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "file=\"%s\" count=\"%d\"", "Variables in %s (%d)", ops->filename, zend_hash_num_elements(&vars)); } else { - phpdbg_notice( - "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "opline=\"%p\" count=\"%d\"", "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars)); } } } if (zend_hash_num_elements(&vars)) { - phpdbg_writeln("Address\t\tRefs\tType\t\tVariable"); + phpdbg_out("Address\t\tRefs\tType\t\tVariable"); for (zend_hash_internal_pointer_reset_ex(&vars, &pos); zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS; zend_hash_move_forward_ex(&vars, &pos)) { @@ -152,50 +148,20 @@ PHPDBG_INFO(vars) /* {{{ */ zend_hash_get_current_key_ex(&vars, &var, NULL, NULL, 0, &pos); if (*data) { - phpdbg_write( - "%p\t%d\t", - *data, - Z_REFCOUNT_PP(data)); - - switch (Z_TYPE_PP(data)) { - case IS_STRING: phpdbg_write("(string)\t"); break; - case IS_LONG: phpdbg_write("(integer)\t"); break; - case IS_DOUBLE: phpdbg_write("(float)\t"); break; - case IS_RESOURCE: phpdbg_write("(resource)\t"); break; - case IS_ARRAY: phpdbg_write("(array)\t"); break; - case IS_OBJECT: phpdbg_write("(object)\t"); break; - case IS_NULL: phpdbg_write("(null)\t"); break; - } + phpdbg_writeln("variable", "address=\"%p\" refcount=\"%d\" type=\"%s\"", "%p\t%d\t(%s)", *data, Z_REFCOUNT_PP(data), zend_zval_type_name(*data)); if (Z_TYPE_PP(data) == IS_RESOURCE) { int type; - phpdbg_writeln( - "%s$%s", Z_ISREF_PP(data) ? "&": "", var); - if (zend_list_find(Z_RESVAL_PP(data), &type)) { - phpdbg_write( - "|-------(typeof)------> (%s)", - zend_rsrc_list_get_rsrc_type(type TSRMLS_CC)); - } else { - phpdbg_write( - "|-------(typeof)------> (unknown)"); - } - phpdbg_writeln(EMPTY); + phpdbg_writeln("variabledetails", "refstatus=\"%s\" name=\"%s\" type=\"%s\"", "%s$%s\n|-------(typeof)------> (%s)\n", Z_ISREF_PP(data) ? "&": "", var, zend_list_find(Z_RESVAL_PP(data), &type) ? zend_rsrc_list_get_rsrc_type(type TSRMLS_CC) : "unknown"); } else if (Z_TYPE_PP(data) == IS_OBJECT) { - phpdbg_writeln( - "%s$%s", Z_ISREF_PP(data) ? "&": "", var); - phpdbg_write( - "|-----(instanceof)----> (%s)", Z_OBJCE_PP(data)->name); - phpdbg_writeln(EMPTY); + phpdbg_writeln("variabledetails", "refstatus=\"%s\" name=\"%s\" instanceof=\"%s\"", "%s$%s\n|-----(instanceof)----> (%s)\n", Z_ISREF_PP(data) ? "&": "", var, Z_OBJCE_PP(data)->name); } else { - phpdbg_write( - "%s$%s", Z_ISREF_PP(data) ? "&": "", var); + phpdbg_writeln("variabledetails", "refstatus=\"%s\" name=\"%s\"", "%s$%s", Z_ISREF_PP(data) ? "&": "", var); } } else { - phpdbg_write( - "n/a\tn/a\tn/a\t$%s", var); + phpdbg_writeln("variable", "address=\"\" type=\"unknown\" name=\"%s\"", "n/a\tn/a\tn/a\t$%s", var); } - phpdbg_writeln(EMPTY); } } @@ -212,34 +178,29 @@ PHPDBG_INFO(literal) /* {{{ */ if (ops->function_name) { if (ops->scope) { - phpdbg_notice( - "Literal Constants in %s::%s() (%d)", ops->scope->name, ops->function_name, count); + phpdbg_notice("literalinfo", "method=\"%s::%s\" count=\"%d\"", "Literal Constants in %s::%s() (%d)", ops->scope->name, ops->function_name, count); } else { - phpdbg_notice( - "Literal Constants in %s() (%d)", ops->function_name, count); + phpdbg_notice("literalinfo", "function=\"%s\" count=\"%d\"", "Literal Constants in %s() (%d)", ops->function_name, count); } } else { if (ops->filename) { - phpdbg_notice( - "Literal Constants in %s (%d)", ops->filename, count); + phpdbg_notice("literalinfo", "file=\"%s\" count=\"%d\"", "Literal Constants in %s (%d)", ops->filename, count); } else { - phpdbg_notice( - "Literal Constants @ %p (%d)", ops, count); + phpdbg_notice("literalinfo", "opline=\"%p\" count=\"%d\"", "Literal Constants @ %p (%d)", ops, count); } } while (literal < ops->last_literal) { if (Z_TYPE(ops->literals[literal].constant) != IS_NULL) { - phpdbg_write("|-------- C%u -------> [", literal); + phpdbg_write("literal", "id=\"%u\"", "|-------- C%u -------> [", literal); zend_print_zval( &ops->literals[literal].constant, 0); - phpdbg_write("]"); - phpdbg_writeln(EMPTY); + phpdbg_out("]\n"); } literal++; } } else { - phpdbg_error("Not executing!"); + phpdbg_error("inactive", "type=\"execution\"", "Not executing!"); } return SUCCESS; @@ -248,27 +209,22 @@ PHPDBG_INFO(literal) /* {{{ */ PHPDBG_INFO(memory) /* {{{ */ { if (is_zend_mm(TSRMLS_C)) { - phpdbg_notice("Memory Manager Information"); - phpdbg_notice("Current"); - phpdbg_writeln("|-------> Used:\t%.3f kB", - (float) (zend_memory_usage(0 TSRMLS_CC)/1024)); - phpdbg_writeln("|-------> Real:\t%.3f kB", - (float) (zend_memory_usage(1 TSRMLS_CC)/1024)); - phpdbg_notice("Peak"); - phpdbg_writeln("|-------> Used:\t%.3f kB", - (float) (zend_memory_peak_usage(0 TSRMLS_CC)/1024)); - phpdbg_writeln("|-------> Real:\t%.3f kB", - (float) (zend_memory_peak_usage(1 TSRMLS_CC)/1024)); + phpdbg_notice("meminfo", "", "Memory Manager Information"); + phpdbg_notice("current", "", "Current"); + phpdbg_writeln("used", "mem=\"%.3f\"", "|-------> Used:\t%.3f kB", (float) (zend_memory_usage(0 TSRMLS_CC)/1024)); + phpdbg_writeln("real", "mem=\"%.3f\"", "|-------> Real:\t%.3f kB", (float) (zend_memory_usage(1 TSRMLS_CC)/1024)); + phpdbg_notice("peak", "", "Peak"); + phpdbg_writeln("used", "mem=\"%.3f\"", "|-------> Used:\t%.3f kB", (float) (zend_memory_peak_usage(0 TSRMLS_CC)/1024)); + phpdbg_writeln("real", "mem=\"%.3f\"", "|-------> Real:\t%.3f kB", (float) (zend_memory_peak_usage(1 TSRMLS_CC)/1024)); } else { - phpdbg_error("Memory Manager Disabled!"); + phpdbg_error("inactive", "type=\"memory_manager\"", "Memory Manager Disabled!"); } return SUCCESS; } /* }}} */ static inline void phpdbg_print_class_name(zend_class_entry **ce TSRMLS_DC) /* {{{ */ { - phpdbg_write( - "%s %s %s (%d)", + phpdbg_writeln("class", "type=\"%s\" flags=\"%s\" name=\"%s\" methodcount=\"%d\"", "%s %s %s (%d)", ((*ce)->type == ZEND_USER_CLASS) ? "User" : "Internal", ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? @@ -292,39 +248,37 @@ PHPDBG_INFO(classes) /* {{{ */ zend_hash_move_forward_ex(EG(class_table), &position)) { if ((*ce)->type == ZEND_USER_CLASS) { - zend_hash_next_index_insert( - &classes, ce, sizeof(ce), NULL); + zend_hash_next_index_insert(&classes, ce, sizeof(ce), NULL); } } - phpdbg_notice("User Classes (%d)", - zend_hash_num_elements(&classes)); + phpdbg_notice("classinfo", "count=\"%d\"", "User Classes (%d)", zend_hash_num_elements(&classes)); for (zend_hash_internal_pointer_reset_ex(&classes, &position); zend_hash_get_current_data_ex(&classes, (void**)&ce, &position) == SUCCESS; zend_hash_move_forward_ex(&classes, &position)) { phpdbg_print_class_name(ce TSRMLS_CC); - phpdbg_writeln(EMPTY); + phpdbg_out("\n"); if ((*ce)->parent) { + phpdbg_xml(""); zend_class_entry *pce = (*ce)->parent; do { - phpdbg_write("|-------- "); + phpdbg_out("|-------- "); phpdbg_print_class_name(&pce TSRMLS_CC); - phpdbg_writeln(EMPTY); } while ((pce = pce->parent)); + phpdbg_xml(""); } if ((*ce)->info.user.filename) { - phpdbg_writeln( - "|---- in %s on line %u", + phpdbg_writeln("classsource", "file=\"\" line=\"%u\"", "|---- in %s on line %u", (*ce)->info.user.filename, (*ce)->info.user.line_start); } else { - phpdbg_writeln("|---- no source code"); + phpdbg_writeln("classsource", "", "|---- no source code"); } - phpdbg_writeln(EMPTY); + phpdbg_out("\n"); } zend_hash_destroy(&classes); @@ -350,16 +304,14 @@ PHPDBG_INFO(funcs) /* {{{ */ } } - phpdbg_notice("User Functions (%d)", - zend_hash_num_elements(&functions)); + phpdbg_notice("functioninfo", "count=\"%d\"", "User Functions (%d)", zend_hash_num_elements(&functions)); for (zend_hash_internal_pointer_reset_ex(&functions, &position); zend_hash_get_current_data_ex(&functions, (void**)&pzf, &position) == SUCCESS; zend_hash_move_forward_ex(&functions, &position)) { zend_op_array *op_array = &((*pzf)->op_array); - phpdbg_writeln( - "|-------- %s in %s on line %d", + phpdbg_writeln("function", "name=\"%s\" file=\"%s\" line=\"%d\"", "|-------- %s in %s on line %d", op_array->function_name ? op_array->function_name : "{main}", op_array->filename ? op_array->filename : "(no source code)", op_array->line_start); diff --git a/phpdbg_list.c b/phpdbg_list.c index e8db4e605c7..64e0d8465b9 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -48,7 +48,7 @@ const phpdbg_command_t phpdbg_list_commands[] = { PHPDBG_LIST(lines) /* {{{ */ { if (!PHPDBG_G(exec) && !zend_is_executing(TSRMLS_C)) { - phpdbg_error("Not executing, and execution context not set"); + phpdbg_error("inactive", "type=\"execution\"", "Not executing, and execution context not set"); return SUCCESS; } @@ -59,7 +59,7 @@ PHPDBG_LIST(lines) /* {{{ */ (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), 0 TSRMLS_CC); break; - + case FILE_PARAM: phpdbg_list_file(param->file.name, param->file.line, 0, 0 TSRMLS_CC); break; @@ -88,12 +88,12 @@ PHPDBG_LIST(method) /* {{{ */ if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**) &function) == SUCCESS) { phpdbg_list_function(function TSRMLS_CC); } else { - phpdbg_error("Could not find %s::%s", param->method.class, param->method.name); + phpdbg_error("list", "type=\"notfound\" method=\"%s::%s\"", "Could not find %s::%s", param->method.class, param->method.name); } efree(lcname); } else { - phpdbg_error("Could not find the class %s", param->method.class); + phpdbg_error("list", "type=\"notfound\" class=\"%s\"", "Could not find the class %s", param->method.class); } return SUCCESS; @@ -112,13 +112,13 @@ PHPDBG_LIST(class) /* {{{ */ (*ce)->info.user.line_start, 0 TSRMLS_CC ); } else { - phpdbg_error("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", (*ce)->name); } } else { - phpdbg_error("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", (*ce)->name); } } else { - phpdbg_error("The requested class (%s) could not be found", param->str); + phpdbg_error("list", "type=\"notfound\" class=\"%s\"", "The requested class (%s) could not be found", param->str); } return SUCCESS; @@ -132,42 +132,44 @@ void phpdbg_list_file(const char *filename, long count, long offset, int highlig long line = 0; php_stream *stream = NULL; - + if (VCWD_STAT(filename, &st) == FAILURE) { - phpdbg_error("Failed to stat file %s", filename); + phpdbg_error("list", "type=\"statfailure\"", "Failed to stat file %s", filename); return; } stream = php_stream_open_wrapper(filename, "rb", USE_PATH, &opened); - + if (!stream) { - phpdbg_error("Failed to open file %s to list", filename); + phpdbg_error("list", "type=\"openfailure\"", "Failed to open file %s to list", filename); return; } - + if (offset < 0) { count += offset; offset = 0; } - + + phpdbg_xml(""); + while (php_stream_gets(stream, buffer, sizeof(buffer)) != NULL) { long linelen = strlen(buffer); ++line; - + if (offset <= line) { if (!highlight) { - phpdbg_write("%05ld: %s", line, buffer); + phpdbg_write("line", "num=\"%d\" code=\"%s\"", "%05ld: %s", line, buffer); } else { if (highlight != line) { - phpdbg_write(" %05ld: %s", line, buffer); + phpdbg_write("line", "num=\"%d\" code=\"%s\"", "%05ld: %s", " %05ld: %s", line, buffer); } else { - phpdbg_write(">%05ld: %s", line, buffer); + phpdbg_write("line", "num=\"%d\" code=\"%s\" current=\"current\"", "%05ld: %s", ">%05ld: %s", line, buffer); } } if (buffer[linelen - 1] != '\n') { - phpdbg_write("\n"); + phpdbg_out("\n"); } } @@ -175,7 +177,9 @@ void phpdbg_list_file(const char *filename, long count, long offset, int highlig break; } } - + + phpdbg_xml(""); + php_stream_close(stream); } /* }}} */ @@ -184,7 +188,7 @@ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */ const zend_op_array *ops; if (fbc->type != ZEND_USER_FUNCTION) { - phpdbg_error("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", fbc->common.function_name); return; } @@ -209,11 +213,11 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ * func_table = &EG(scope)->function_table; } else { - phpdbg_error("No active class"); + phpdbg_error("inactive", "type=\"noclasses\"", "No active class"); return; } } else if (!EG(function_table)) { - phpdbg_error("No function table loaded"); + phpdbg_error("inactive", "type=\"function_table\"", "No function table loaded"); return; } else { func_table = EG(function_table); @@ -225,7 +229,7 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ * if (zend_hash_find(func_table, func_name, func_name_len+1, (void**)&fbc) == SUCCESS) { phpdbg_list_function(fbc TSRMLS_CC); } else { - phpdbg_error("Function %s not found", func_name); + phpdbg_error("list", "type=\"nofunction\" function=\"%s\"", "Function %s not found", func_name); } efree(func_name); diff --git a/phpdbg_opcode.c b/phpdbg_opcode.c index 6b13625fc14..4ae2b3de038 100644 --- a/phpdbg_opcode.c +++ b/phpdbg_opcode.c @@ -26,7 +26,7 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -static inline zend_uint phpdbg_decode_literal(zend_op_array *ops, zend_literal *literal TSRMLS_DC) /* {{{ */ +static inline uint32_t phpdbg_decode_literal(zend_op_array *ops, zend_literal *literal TSRMLS_DC) /* {{{ */ { int iter = 0; @@ -40,7 +40,7 @@ static inline zend_uint phpdbg_decode_literal(zend_op_array *ops, zend_literal * return 0; } /* }}} */ -static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, zend_uint type, HashTable *vars TSRMLS_DC) /* {{{ */ +static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t type, HashTable *vars TSRMLS_DC) /* {{{ */ { char *decode = NULL; @@ -92,8 +92,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM case ZEND_JMPZNZ: decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC); - asprintf( - &decode[2], "J%u or J%lu", op->op2.opline_num, op->extended_value); + asprintf(&decode[2], "J%u or J%lu", op->op2.opline_num, op->extended_value); goto result; case ZEND_JMPZ: @@ -103,13 +102,9 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM #ifdef ZEND_JMP_SET case ZEND_JMP_SET: -#endif -#ifdef ZEND_JMP_SET_VAR - case ZEND_JMP_SET_VAR: #endif decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC); - asprintf( - &decode[2], "J%ld", op->op2.jmp_addr - ops->opcodes); + asprintf(&decode[2], "J%ld", op->op2.jmp_addr - ops->opcodes); goto result; case ZEND_RECV_INIT: @@ -121,8 +116,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM result: decode[3] = phpdbg_decode_op(ops, &op->result, op->result_type, vars TSRMLS_CC); format: - asprintf( - &decode[0], + asprintf(&decode[0], "%-20s %-20s %-20s", decode[1] ? decode[1] : "", decode[2] ? decode[2] : "", @@ -153,7 +147,7 @@ void phpdbg_print_opline_ex(zend_execute_data *execute_data, HashTable *vars, ze if (ignore_flags || (!(PHPDBG_G(flags) & PHPDBG_IS_QUIET) || (PHPDBG_G(flags) & PHPDBG_IS_STEPPING))) { /* output line info */ - phpdbg_notice("L%-5u %16p %-30s %s %s", + phpdbg_notice("opline", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\" file=\"%s\"", "L%-5u %16p %-30s %s %s", opline->lineno, opline, phpdbg_decode_opcode(opline->opcode), @@ -333,12 +327,6 @@ const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */ #ifdef ZEND_SEPARATE CASE(ZEND_SEPARATE); #endif -#ifdef ZEND_QM_ASSIGN_VAR - CASE(ZEND_QM_ASSIGN_VAR); -#endif -#ifdef ZEND_JMP_SET_VAR - CASE(ZEND_JMP_SET_VAR); -#endif #ifdef ZEND_DISCARD_EXCEPTION CASE(ZEND_DISCARD_EXCEPTION); #endif diff --git a/phpdbg_parser.c b/phpdbg_parser.c index e34c2f48ff4..6331cbc59e6 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.6.2. */ +/* A Bison parser, made by GNU Bison 2.5. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.6.2" +#define YYBISON_VERSION "2.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -58,6 +58,8 @@ /* Pull parsers. */ #define YYPULL 1 +/* Using locations. */ +#define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse phpdbg_parse @@ -68,9 +70,11 @@ #define yydebug phpdbg_debug #define yynerrs phpdbg_nerrs + /* Copy the first part of user declarations. */ -/* Line 336 of yacc.c */ -#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 268 of yacc.c */ +#line 1 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" /* @@ -97,16 +101,14 @@ static int yyerror(void ***tsrm_ls, const char *msg); ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -/* Line 336 of yacc.c */ -#line 102 "sapi/phpdbg/phpdbg_parser.c" -# ifndef YY_NULL -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr -# else -# define YY_NULL 0 -# endif -# endif +/* Line 268 of yacc.c */ +#line 107 "sapi/phpdbg/phpdbg_parser.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE @@ -116,20 +118,15 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); # define YYERROR_VERBOSE 1 #endif -/* In a future release of Bison, this section will be replaced - by #include "phpdbg_parser.h". */ -#ifndef PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H -# define PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int phpdbg_debug; +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 #endif + /* "%code requires" blocks. */ -/* Line 350 of yacc.c */ -#line 31 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 288 of yacc.c */ +#line 31 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -138,8 +135,9 @@ typedef void* yyscan_t; #endif -/* Line 350 of yacc.c */ -#line 143 "sapi/phpdbg/phpdbg_parser.c" + +/* Line 288 of yacc.c */ +#line 141 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -189,6 +187,7 @@ typedef void* yyscan_t; + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 @@ -197,26 +196,11 @@ typedef int YYSTYPE; #endif -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int phpdbg_parse (void *YYPARSE_PARAM); -#else -int phpdbg_parse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int phpdbg_parse (void *tsrm_ls); -#else -int phpdbg_parse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H */ - /* Copy the second part of user declarations. */ -/* Line 353 of yacc.c */ -#line 220 "sapi/phpdbg/phpdbg_parser.c" + +/* Line 343 of yacc.c */ +#line 204 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -322,7 +306,6 @@ YYID (yyi) # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif @@ -414,20 +397,20 @@ union yyalloc #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do +/* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ while (YYID (0)) # endif # endif @@ -519,7 +502,7 @@ static const yytype_uint8 yyrline[] = }; #endif -#if YYDEBUG || YYERROR_VERBOSE || 1 +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = @@ -532,7 +515,7 @@ static const char *const yytname[] = "\"digits (numbers)\"", "\"literal (string)\"", "\"address\"", "\"opcode\"", "\"identifier (command or function name)\"", "\"input (input string or data)\"", "\"input\"", "$accept", "input", - "parameters", "parameter", "full_expression", YY_NULL + "parameters", "parameter", "full_expression", 0 }; #endif @@ -662,18 +645,17 @@ static const yytype_uint8 yystos[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ yyerror (tsrm_ls, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ @@ -683,33 +665,32 @@ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 + /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ while (YYID (0)) #endif -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - /* This macro is provided for backward compatibility. */ @@ -770,8 +751,6 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, tsrm_ls) void *tsrm_ls; #endif { - FILE *yyo = yyoutput; - YYUSE (yyo); if (!yyvaluep) return; YYUSE (tsrm_ls); @@ -1026,12 +1005,12 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = YY_NULL; + const char *yyformat = 0; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1091,7 +1070,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, break; } yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + yysize1 = yysize + yytnamerr (0, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; @@ -1185,6 +1164,20 @@ yydestruct (yymsg, yytype, yyvaluep, tsrm_ls) } +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void *tsrm_ls); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ /*----------. @@ -1230,7 +1223,7 @@ YYSTYPE yylval; `yyss': related to states. `yyvs': related to semantic values. - Refer to the stacks through separate pointers, to allow yyoverflow + Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ @@ -1284,6 +1277,7 @@ YYSTYPE yylval; The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; + goto yysetstate; /*------------------------------------------------------------. @@ -1461,26 +1455,30 @@ yyreduce: switch (yyn) { case 3: -/* Line 1802 of yacc.c */ -#line 67 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 67 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); } break; case 5: -/* Line 1802 of yacc.c */ -#line 72 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 72 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); } break; case 6: -/* Line 1802 of yacc.c */ -#line 73 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 73 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(2) - (2)])); } break; case 7: -/* Line 1802 of yacc.c */ -#line 77 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 77 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = FILE_PARAM; (yyval).file.name = (yyvsp[(2) - (3)]).str; @@ -1489,8 +1487,9 @@ yyreduce: break; case 8: -/* Line 1802 of yacc.c */ -#line 82 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 82 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; (yyval).file.name = (yyvsp[(1) - (4)]).str; @@ -1499,8 +1498,9 @@ yyreduce: break; case 9: -/* Line 1802 of yacc.c */ -#line 87 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 87 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = FILE_PARAM; (yyval).file.name = malloc((yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len + 1); @@ -1514,8 +1514,9 @@ yyreduce: break; case 10: -/* Line 1802 of yacc.c */ -#line 97 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 97 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; (yyval).file.name = malloc((yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len + 1); @@ -1529,8 +1530,9 @@ yyreduce: break; case 11: -/* Line 1802 of yacc.c */ -#line 107 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 107 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (3)]).str; @@ -1539,8 +1541,9 @@ yyreduce: break; case 12: -/* Line 1802 of yacc.c */ -#line 112 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 112 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (5)]).str; @@ -1550,8 +1553,9 @@ yyreduce: break; case 13: -/* Line 1802 of yacc.c */ -#line 118 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 118 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FUNCTION_PARAM; (yyval).str = (yyvsp[(1) - (3)]).str; @@ -1561,8 +1565,9 @@ yyreduce: break; case 14: -/* Line 1802 of yacc.c */ -#line 124 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 124 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = COND_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1571,50 +1576,58 @@ yyreduce: break; case 15: -/* Line 1802 of yacc.c */ -#line 129 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 129 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: -/* Line 1802 of yacc.c */ -#line 130 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 130 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: -/* Line 1802 of yacc.c */ -#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 131 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: -/* Line 1802 of yacc.c */ -#line 132 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 132 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: -/* Line 1802 of yacc.c */ -#line 133 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 133 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: -/* Line 1802 of yacc.c */ -#line 134 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 134 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 21: -/* Line 1802 of yacc.c */ -#line 135 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 135 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 22: -/* Line 1802 of yacc.c */ -#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 139 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = EVAL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1623,8 +1636,9 @@ yyreduce: break; case 23: -/* Line 1802 of yacc.c */ -#line 144 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 144 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = SHELL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1633,8 +1647,9 @@ yyreduce: break; case 24: -/* Line 1802 of yacc.c */ -#line 149 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 149 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; (yyval).len = 0; @@ -1642,8 +1657,9 @@ yyreduce: break; case 25: -/* Line 1802 of yacc.c */ -#line 153 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 1806 of yacc.c */ +#line 153 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1652,8 +1668,9 @@ yyreduce: break; -/* Line 1802 of yacc.c */ -#line 1657 "sapi/phpdbg/phpdbg_parser.c" + +/* Line 1806 of yacc.c */ +#line 1674 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1840,7 +1857,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#if !defined yyoverflow || YYERROR_VERBOSE +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -1882,12 +1899,13 @@ yyreturn: } -/* Line 2048 of yacc.c */ -#line 160 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 2067 of yacc.c */ +#line 160 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" static int yyerror(void ***tsrm_ls, const char *msg) { - phpdbg_error("Parse Error: %s", msg); + phpdbg_error("command", "type=\"parseerror\" msg=\"%s\"", "Parse Error: %s", msg); { const phpdbg_param_t *top = PHPDBG_G(parser_stack); @@ -1909,3 +1927,4 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC) { return yyparse(NULL); #endif } + diff --git a/phpdbg_parser.h b/phpdbg_parser.h index b3aadb9c62d..286e7ff1084 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.6.2. */ +/* A Bison parser, made by GNU Bison 2.5. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,18 +30,10 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#ifndef PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H -# define PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int phpdbg_debug; -#endif /* "%code requires" blocks. */ -/* Line 2055 of yacc.c */ -#line 31 "/var/root/php-src/sapi/phpdbg/phpdbg_parser.y" + +/* Line 2068 of yacc.c */ +#line 31 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -50,8 +42,9 @@ typedef void* yyscan_t; #endif -/* Line 2055 of yacc.c */ -#line 55 "sapi/phpdbg/phpdbg_parser.h" + +/* Line 2068 of yacc.c */ +#line 48 "sapi/phpdbg/phpdbg_parser.h" /* Tokens. */ #ifndef YYTOKENTYPE @@ -101,6 +94,7 @@ typedef void* yyscan_t; + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 @@ -109,18 +103,5 @@ typedef int YYSTYPE; #endif -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int phpdbg_parse (void *YYPARSE_PARAM); -#else -int phpdbg_parse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int phpdbg_parse (void *tsrm_ls); -#else -int phpdbg_parse (); -#endif -#endif /* ! YYPARSE_PARAM */ -#endif /* !PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H */ + diff --git a/phpdbg_print.c b/phpdbg_print.c index 76321a5042d..65acc492a29 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -44,7 +44,7 @@ PHPDBG_PRINT(opline) /* {{{ */ if (EG(in_execution) && EG(current_execute_data)) { phpdbg_print_opline(EG(current_execute_data), 1 TSRMLS_CC); } else { - phpdbg_error("Not Executing!"); + phpdbg_error("inactive", "type=\"execution\"", "Not Executing!"); } return SUCCESS; @@ -56,21 +56,22 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) case ZEND_USER_FUNCTION: { zend_op_array* op_array = &(method->op_array); HashTable vars; - + if (op_array) { zend_op *opline = &(op_array->opcodes[0]); - zend_uint opcode = 0, + uint32_t opcode = 0, end = op_array->last-1; if (method->common.scope) { - phpdbg_writeln("\tL%d-%d %s::%s() %s", - op_array->line_start, op_array->line_end, + phpdbg_writeln("printoplineinfo", "startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "\tL%d-%d %s::%s() %s", + op_array->line_start, + op_array->line_end, method->common.scope->name, method->common.function_name, op_array->filename ? op_array->filename : "unknown"); } else { - phpdbg_writeln("\tL%d-%d %s() %s", - method->common.function_name ? op_array->line_start : 0, + phpdbg_writeln("printoplineinfo", "startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "\tL%d-%d %s() %s", + method->common.function_name ? op_array->line_start : 0, method->common.function_name ? op_array->line_end : 0, method->common.function_name ? method->common.function_name : "{main}", op_array->filename ? op_array->filename : "unknown"); @@ -80,14 +81,14 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) do { char *decode = phpdbg_decode_opline(op_array, opline, &vars TSRMLS_CC); if (decode != NULL) { - phpdbg_writeln("\t\tL%u\t%p %-30s %s", + phpdbg_writeln("print", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\"", "\t\tL%u\t%p %-30s %s", opline->lineno, - opline, + opline, phpdbg_decode_opcode(opline->opcode), decode); free(decode); } else { - phpdbg_error("\tFailed to decode opline %16p", opline); + phpdbg_error("print", "type=\"decodefailure\" opline=\"%16p\"", "\tFailed to decode opline %16p", opline); } opline++; } while (opcode++ < end); @@ -97,9 +98,9 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) default: { if (method->common.scope) { - phpdbg_writeln("\tInternal %s::%s()", method->common.scope->name, method->common.function_name); + phpdbg_writeln("printoplineinfo", "type=\"internal\" method=\"%s::%s\"", "Internal %s::%s()", method->common.scope->name, method->common.function_name); } else { - phpdbg_writeln("\tInternal %s()", method->common.function_name); + phpdbg_writeln("printoplineinfo", "type=\"internal\" function=\"%s\"", "\tInternal %s()", method->common.function_name); } } } @@ -113,12 +114,12 @@ PHPDBG_PRINT(exec) /* {{{ */ } if (PHPDBG_G(ops)) { - phpdbg_notice("Context %s", PHPDBG_G(exec)); + phpdbg_notice("printinfo", "file=\"%s\" count=\"%d\"", "Context %s (%d ops)", PHPDBG_G(exec), PHPDBG_G(ops)->last); phpdbg_print_function_helper((zend_function*) PHPDBG_G(ops) TSRMLS_CC); } } else { - phpdbg_error("No execution context set"); + phpdbg_error("inactive", "type=\"nocontext\"", "No execution context set"); } return SUCCESS; @@ -127,24 +128,24 @@ return SUCCESS; PHPDBG_PRINT(stack) /* {{{ */ { zend_op_array *ops = EG(active_op_array); - + if (EG(in_execution) && ops) { if (ops->function_name) { if (ops->scope) { - phpdbg_notice("Stack in %s::%s()", ops->scope->name, ops->function_name); + phpdbg_notice("printinfo", "method=\"%s::%s\" count=\"%d\"", "Stack in %s::%s() (%d ops)", ops->scope->name, ops->function_name, ops->last); } else { - phpdbg_notice("Stack in %s()", ops->function_name); + phpdbg_notice("printinfo", "function=\"%s\" count=\"%d\"", "Stack in %s() (%d ops)", ops->function_name, ops->last); } } else { if (ops->filename) { - phpdbg_notice("Stack in %s", ops->filename); + phpdbg_notice("printinfo", "file=\"%s\" count=\"%d\"", "Stack in %s (%d ops)", ops->filename, ops->last); } else { - phpdbg_notice("Stack @ %p", ops); + phpdbg_notice("printinfo", "opline=\"%p\" count=\"%d\"", "Stack @ %p (%d ops)", ops, ops->last); } } phpdbg_print_function_helper((zend_function*) ops TSRMLS_CC); } else { - phpdbg_error("Not Executing!"); + phpdbg_error("inactive", "type=\"execution\"", "Not Executing!"); } return SUCCESS; @@ -155,7 +156,7 @@ PHPDBG_PRINT(class) /* {{{ */ zend_class_entry **ce; if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { - phpdbg_notice("%s %s: %s", + phpdbg_notice("printinfo", "type=\"%s\" flag=\"%s\" class=\"%s\" count=\"%d\"", "%s %s: %s (%d methods)", ((*ce)->type == ZEND_USER_CLASS) ? "User" : "Internal", ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? @@ -163,9 +164,11 @@ PHPDBG_PRINT(class) /* {{{ */ ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ? "Abstract Class" : "Class", - (*ce)->name); + (*ce)->name, + zend_hash_num_elements(&(*ce)->function_table)); + + phpdbg_xml(""); - phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table)); if (zend_hash_num_elements(&(*ce)->function_table)) { HashPosition position; zend_function *method; @@ -176,8 +179,10 @@ PHPDBG_PRINT(class) /* {{{ */ phpdbg_print_function_helper(method TSRMLS_CC); } } + + phpdbg_xml(""); } else { - phpdbg_error("The class %s could not be found", param->str); + phpdbg_error("print", "type=\"noclass\" class=\"%s\"", "The class %s could not be found", param->str); } return SUCCESS; @@ -192,18 +197,19 @@ PHPDBG_PRINT(method) /* {{{ */ char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { - phpdbg_notice("%s Method %s", + phpdbg_notice("printinfo", "type=\"%s\" flag=\"Method\" symbol=\"%s\" count=\"%d\"", "%s Method %s (%d ops)", (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", - fbc->common.function_name); + fbc->common.function_name, + (fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0); phpdbg_print_function_helper(fbc TSRMLS_CC); } else { - phpdbg_error("The method %s could not be found", param->method.name); + phpdbg_error("print", "type=\"nomethod\" method=\"%s::%s\"", "The method %s::%s could not be found", param->method.class, param->method.name); } efree(lcname); } else { - phpdbg_error("The class %s could not be found", param->method.class); + phpdbg_error("print", "type=\"noclass\" class=\"%s\"", "The class %s could not be found", param->method.class); } return SUCCESS; @@ -224,11 +230,11 @@ PHPDBG_PRINT(func) /* {{{ */ func_table = &EG(scope)->function_table; } else { - phpdbg_error("No active class"); + phpdbg_error("inactive", "type=\"noclasses\"", "No active class"); return SUCCESS; } } else if (!EG(function_table)) { - phpdbg_error("No function table loaded"); + phpdbg_error("inactive", "type=\"function_table\"", "No function table loaded"); return SUCCESS; } else { func_table = EG(function_table); @@ -237,14 +243,15 @@ PHPDBG_PRINT(func) /* {{{ */ lcname = zend_str_tolower_dup(func_name, func_name_len); if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { - phpdbg_notice("%s %s %s", + phpdbg_notice("printinfo", "type=\"%s\" flag=\"%s\" symbol=\"%s\" count=\"%d\"", "%s %s %s (%d ops)", (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", (fbc->common.scope) ? "Method" : "Function", - fbc->common.function_name); + fbc->common.function_name, + (fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0 ); phpdbg_print_function_helper(fbc TSRMLS_CC); } else { - phpdbg_error("The function %s could not be found", func_name); + phpdbg_error("print", "type=\"nofunction\" function=\"%s\"", "The function %s could not be found", func_name); } efree(lcname); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index d91ef3f3f5c..0081fd2312a 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -44,7 +44,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0), PHPDBG_COMMAND_D(continue,"continue execution", 'c', NULL, 0), PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s"), - PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"), + PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"), PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0), PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0), PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0), @@ -61,7 +61,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s"), PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s"), - PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"), + PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss"), PHPDBG_END_COMMAND @@ -75,13 +75,12 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * if (stack->type == STACK_PARAM) { name = stack->next; - + if (!name || name->type != STR_PARAM) { return FAILURE; } - - if (zend_hash_exists( - &PHPDBG_G(registered), name->str, name->len+1)) { + + if (zend_hash_exists(&PHPDBG_G(registered), name->str, name->len+1)) { zval fname, *fretval; zend_fcall_info fci; @@ -101,62 +100,59 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * if (name->next) { zval params; phpdbg_param_t *next = name->next; - + array_init(¶ms); while (next) { char *buffered = NULL; - + switch (next->type) { case OP_PARAM: case COND_PARAM: case STR_PARAM: - add_next_index_stringl( - ¶ms, - next->str, - next->len, 1); + add_next_index_stringl(¶ms, next->str, next->len, 1); break; - + case NUMERIC_PARAM: add_next_index_long(¶ms, next->num); break; - + case METHOD_PARAM: spprintf(&buffered, 0, "%s::%s", next->method.class, next->method.name); add_next_index_string(¶ms, buffered, 0); break; - + case NUMERIC_METHOD_PARAM: spprintf(&buffered, 0, "%s::%s#%ld", next->method.class, next->method.name, next->num); add_next_index_string(¶ms, buffered, 0); break; - + case NUMERIC_FUNCTION_PARAM: spprintf(&buffered, 0, "%s#%ld", next->str, next->num); add_next_index_string(¶ms, buffered, 0); break; - + case FILE_PARAM: spprintf(&buffered, 0, "%s:%ld", next->file.name, next->file.line); add_next_index_string(¶ms, buffered, 0); break; - + case NUMERIC_FILE_PARAM: spprintf(&buffered, 0, "%s:#%ld", next->file.name, next->file.line); add_next_index_string(¶ms, buffered, 0); break; - + default: { /* not yet */ } } - - next = next->next; + + next = next->next; } zend_fcall_info_args(&fci, ¶ms TSRMLS_CC); @@ -165,22 +161,19 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * fci.param_count = 0; } - phpdbg_debug( - "created %d params from arguments", - fci.param_count); + phpdbg_debug("created %d params from arguments", fci.param_count); zend_call_function(&fci, NULL TSRMLS_CC); if (fretval) { - zend_print_zval_r( - fretval, 0 TSRMLS_CC); - phpdbg_writeln(EMPTY); + zend_print_zval_r(fretval, 0 TSRMLS_CC); + phpdbg_out("\n"); } zval_dtor(&fname); return SUCCESS; - } + } } return FAILURE; @@ -189,7 +182,7 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */ { struct stat sb; - + if (init_file && VCWD_STAT(init_file, &sb) != -1) { FILE *fp = fopen(init_file, "r"); if (fp) { @@ -219,8 +212,7 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ in_code = 0; code[code_len] = '\0'; { - zend_eval_stringl( - code, code_len, NULL, "phpdbginit code" TSRMLS_CC); + zend_eval_stringl(code, code_len, NULL, "phpdbginit code" TSRMLS_CC); } free(code); code = NULL; @@ -243,30 +235,26 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ } { - char *why = NULL; char *input = phpdbg_read_input(cmd TSRMLS_CC); phpdbg_param_t stack; phpdbg_init_param(&stack, STACK_PARAM); + phpdbg_activate_err_buf(1 TSRMLS_CC); + if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { - switch (phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { + switch (phpdbg_stack_execute(&stack TSRMLS_CC)) { case FAILURE: -// if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { - phpdbg_error( - "Unrecognized command in %s:%d: %s, %s!", - init_file, line, input, why); - } -// } + phpdbg_activate_err_buf(0 TSRMLS_CC); + if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, init_file, line, input); + } break; } } - if (why) { - free(why); - why = NULL; - } + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); @@ -282,8 +270,7 @@ next_line: fclose(fp); } else { - phpdbg_error( - "Failed to open %s for initialization", init_file); + phpdbg_error("initfailure", "type=\"openfile\" file=\"%s\"", "Failed to open %s for initialization", init_file); } if (free_init) { @@ -315,8 +302,7 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TS scan_dir[i] = 0; } - asprintf( - &init_file, "%s/%s", scan_dir, PHPDBG_INIT_FILENAME); + asprintf(&init_file, "%s/%s", scan_dir, PHPDBG_INIT_FILENAME); phpdbg_try_file_init(init_file, strlen(init_file), 1 TSRMLS_CC); if (i == -1) { break; @@ -342,14 +328,14 @@ PHPDBG_COMMAND(exec) /* {{{ */ if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) { if (PHPDBG_G(exec)) { - phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec)); + phpdbg_notice("exec", "type=\"unset\" context=\"%s\"", "Unsetting old execution context: %s", PHPDBG_G(exec)); efree(PHPDBG_G(exec)); PHPDBG_G(exec) = NULL; PHPDBG_G(exec_len) = 0L; } if (PHPDBG_G(ops)) { - phpdbg_notice("Destroying compiled opcodes"); + phpdbg_notice("exec", "type=\"unsetops\"", "Destroying compiled opcodes"); phpdbg_clean(0 TSRMLS_CC); } @@ -359,19 +345,19 @@ PHPDBG_COMMAND(exec) /* {{{ */ *SG(request_info).argv = PHPDBG_G(exec); php_hash_environment(TSRMLS_C); - phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); + phpdbg_notice("exec", "type=\"set\" context=\"%s\"", "Set execution context: %s", PHPDBG_G(exec)); if (phpdbg_compile(TSRMLS_C) == FAILURE) { - phpdbg_error("Failed to compile %s", PHPDBG_G(exec)); + phpdbg_error("compile", "context=\"%s\"", "Failed to compile %s", PHPDBG_G(exec)); } } else { - phpdbg_notice("Execution context not changed"); + phpdbg_notice("exec", "type=\"unchanged\"", "Execution context not changed"); } } else { - phpdbg_error("Cannot use %s as execution context, not a valid file or symlink", param->str); + phpdbg_error("exec", "type=\"invalid\" context=\"%s\"", "Cannot use %s as execution context, not a valid file or symlink", param->str); } } else { - phpdbg_error("Cannot stat %s, ensure the file exists", param->str); + phpdbg_error("exec", "type=\"notfound\" context=\"%s\"", "Cannot stat %s, ensure the file exists", param->str); } return SUCCESS; } /* }}} */ @@ -381,27 +367,24 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ zend_file_handle fh; if (!PHPDBG_G(exec)) { - phpdbg_error("No execution context"); + phpdbg_error("compile", "type=\"nocontext\"", "No execution context"); return SUCCESS; } if (EG(in_execution)) { - phpdbg_error("Cannot compile while in execution"); + phpdbg_error("compile", "type=\"isrunning\"", "Cannot compile while in execution"); return FAILURE; } - phpdbg_notice("Attempting compilation of %s", PHPDBG_G(exec)); - - if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, - USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) { + if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) { PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE TSRMLS_CC); zend_destroy_file_handle(&fh TSRMLS_CC); - phpdbg_notice("Success"); + phpdbg_notice("compile", "context=\"%s\"", "Successful compilation of %s", PHPDBG_G(exec)); return SUCCESS; } else { - phpdbg_error("Could not open file %s", PHPDBG_G(exec)); + phpdbg_error("compile", "type=\"openfailure\" context=\"%s\"", "Could not open file %s", PHPDBG_G(exec)); } return FAILURE; @@ -424,23 +407,18 @@ PHPDBG_COMMAND(continue) /* {{{ */ PHPDBG_COMMAND(until) /* {{{ */ { if (!EG(in_execution)) { - phpdbg_error("Not executing"); + phpdbg_error("until", "type=\"noexec\"", "Not executing"); return SUCCESS; } PHPDBG_G(flags) |= PHPDBG_IN_UNTIL; { - zend_uint next = 0, - self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + uint32_t next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); zend_op *opline = &EG(active_op_array)->opcodes[self]; for (next = self; next < EG(active_op_array)->last; next++) { if (EG(active_op_array)->opcodes[next].lineno != opline->lineno) { - zend_hash_index_update( - &PHPDBG_G(seek), - (zend_ulong) &EG(active_op_array)->opcodes[next], - &EG(active_op_array)->opcodes[next], - sizeof(zend_op), NULL); + zend_hash_index_update(&PHPDBG_G(seek), (zend_ulong) &EG(active_op_array)->opcodes[next], &EG(active_op_array)->opcodes[next], sizeof(zend_op), NULL); break; } } @@ -452,14 +430,13 @@ PHPDBG_COMMAND(until) /* {{{ */ PHPDBG_COMMAND(finish) /* {{{ */ { if (!EG(in_execution)) { - phpdbg_error("Not executing"); + phpdbg_error("finish", "type=\"noexec\"", "Not executing"); return SUCCESS; } PHPDBG_G(flags) |= PHPDBG_IN_FINISH; { - zend_uint next = 0, - self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + uint32_t next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); for (next = self; next < EG(active_op_array)->last; next++) { switch (EG(active_op_array)->opcodes[next].opcode) { @@ -469,11 +446,7 @@ PHPDBG_COMMAND(finish) /* {{{ */ #ifdef ZEND_YIELD case ZEND_YIELD: #endif - zend_hash_index_update( - &PHPDBG_G(seek), - (zend_ulong) &EG(active_op_array)->opcodes[next], - &EG(active_op_array)->opcodes[next], - sizeof(zend_op), NULL); + zend_hash_index_update(&PHPDBG_G(seek), (zend_ulong) &EG(active_op_array)->opcodes[next], &EG(active_op_array)->opcodes[next], sizeof(zend_op), NULL); break; } } @@ -485,14 +458,13 @@ PHPDBG_COMMAND(finish) /* {{{ */ PHPDBG_COMMAND(leave) /* {{{ */ { if (!EG(in_execution)) { - phpdbg_error("Not executing"); + phpdbg_error("leave", "type=\"noexec\"", "Not executing"); return SUCCESS; } PHPDBG_G(flags) |= PHPDBG_IN_LEAVE; { - zend_uint next = 0, - self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + uint32_t next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); for (next = self; next < EG(active_op_array)->last; next++) { switch (EG(active_op_array)->opcodes[next].opcode) { @@ -502,11 +474,7 @@ PHPDBG_COMMAND(leave) /* {{{ */ #ifdef ZEND_YIELD case ZEND_YIELD: #endif - zend_hash_index_update( - &PHPDBG_G(seek), - (zend_ulong) &EG(active_op_array)->opcodes[next], - &EG(active_op_array)->opcodes[next], - sizeof(zend_op), NULL); + zend_hash_index_update(&PHPDBG_G(seek), (zend_ulong) &EG(active_op_array)->opcodes[next], &EG(active_op_array)->opcodes[next], sizeof(zend_op), NULL); break; } } @@ -518,8 +486,10 @@ PHPDBG_COMMAND(leave) /* {{{ */ PHPDBG_COMMAND(frame) /* {{{ */ { if (!param) { - phpdbg_notice("Currently in frame #%d", PHPDBG_G(frame).num); - } else phpdbg_switch_frame(param->num TSRMLS_CC); + phpdbg_notice("frame", "num=\"%d\"", "Currently in frame #%d", PHPDBG_G(frame).num); + } else { + phpdbg_switch_frame(param->num TSRMLS_CC); + } return SUCCESS; } /* }}} */ @@ -528,23 +498,17 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ { zend_fcall_info fci; - zval fname, - *trace, - exception; + zval fname, *trace, exception; /* get filename and linenumber before unsetting exception */ const char *filename = zend_get_executed_filename(TSRMLS_C); - zend_uint lineno = zend_get_executed_lineno(TSRMLS_C); + uint32_t lineno = zend_get_executed_lineno(TSRMLS_C); /* copy exception */ exception = *EG(exception); zval_copy_ctor(&exception); EG(exception) = NULL; - phpdbg_error( - "Uncaught %s!", - Z_OBJCE(exception)->name); - /* call __toString */ ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring")-1, 1); fci.size = sizeof(fci); @@ -559,16 +523,15 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ zend_call_function(&fci, NULL TSRMLS_CC); if (trace) { - phpdbg_writeln( - "Uncaught %s", Z_STRVAL_P(trace)); - /* remember to dtor trace */ + phpdbg_writeln("exception", "name=\"%s\" trace=\"%s\"", "Uncaught %s!\n%.*s", Z_OBJCE(exception)->name, Z_STRLEN_P(trace), Z_STRVAL_P(trace)); + zval_ptr_dtor(&trace); + } else { + phpdbg_error("exception", "name=\"%s\"" "Uncaught %s!", Z_OBJCE(exception)->name); } /* output useful information about address */ - phpdbg_writeln( - "Stacked entered at %p in %s on line %u", - EG(active_op_array)->opcodes, filename, lineno); + phpdbg_writeln("exception", "opline=\"%p\" file=\"%s\" line=\"%u\"", "Stack entered at %p in %s on line %u", EG(active_op_array)->opcodes, filename, lineno); zval_dtor(&fname); zval_dtor(&exception); @@ -577,7 +540,7 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ PHPDBG_COMMAND(run) /* {{{ */ { if (EG(in_execution)) { - phpdbg_error("Cannot start another execution while one is in progress"); + phpdbg_error("run", "type=\"isrunning\"", "Cannot start another execution while one is in progress"); return SUCCESS; } @@ -590,7 +553,7 @@ PHPDBG_COMMAND(run) /* {{{ */ if (!PHPDBG_G(ops)) { if (phpdbg_compile(TSRMLS_C) == FAILURE) { - phpdbg_error("Failed to compile %s, cannot run", PHPDBG_G(exec)); + phpdbg_error("run", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec)); goto out; } } @@ -651,7 +614,7 @@ PHPDBG_COMMAND(run) /* {{{ */ EG(return_value_ptr_ptr) = orig_retval_ptr; if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - phpdbg_error("Caught exit/error from VM"); + phpdbg_error("run", "type=\"bailout\"", "Caught exit/error from VM"); restore = 0; } } zend_end_try(); @@ -666,7 +629,7 @@ PHPDBG_COMMAND(run) /* {{{ */ EG(return_value_ptr_ptr) = orig_retval_ptr; } } else { - phpdbg_error("Nothing to execute!"); + phpdbg_error("run", "type=\"noexec\"", "Nothing to execute!"); } out: @@ -676,29 +639,28 @@ out: PHPDBG_COMMAND(ev) /* {{{ */ { - zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)==PHPDBG_IS_STEPPING); + zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING) == PHPDBG_IS_STEPPING); zval retval; if (!(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { - PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; + PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; } /* disable stepping while eval() in progress */ PHPDBG_G(flags) |= PHPDBG_IN_EVAL; zend_try { - if (zend_eval_stringl(param->str, param->len, - &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { - zend_print_zval_r( - &retval, 0 TSRMLS_CC); - phpdbg_writeln(EMPTY); + if (zend_eval_stringl(param->str, param->len,&retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { + phpdbg_xml(""); + zend_print_zval_r(&retval, 0 TSRMLS_CC); + phpdbg_xml(""); + phpdbg_out("\n"); zval_dtor(&retval); } } zend_end_try(); PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL; /* switch stepping back on */ - if (stepping && - !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { + if (stepping && !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; } @@ -710,7 +672,7 @@ PHPDBG_COMMAND(ev) /* {{{ */ PHPDBG_COMMAND(back) /* {{{ */ { if (!EG(in_execution)) { - phpdbg_error("Not executing!"); + phpdbg_error("back", "type=\"noexec\"", "Not executing!"); return SUCCESS; } @@ -725,62 +687,54 @@ PHPDBG_COMMAND(back) /* {{{ */ PHPDBG_COMMAND(print) /* {{{ */ { - phpdbg_writeln(SEPARATE); - phpdbg_notice("Execution Context Information"); + phpdbg_out("Execution Context Information\n\n"); + phpdbg_xml(""); #ifdef HAVE_LIBREADLINE - phpdbg_writeln("Readline\tyes"); + phpdbg_writeln("print", "readline=\"yes\"", "Readline yes"); #else - phpdbg_writeln("Readline\tno"); + phpdbg_writeln("print", "readline=\"no\"", "Readline no"); #endif #ifdef HAVE_LIBEDIT - phpdbg_writeln("Libedit\t\tyes"); + phpdbg_writeln("print", "libedit=\"yes\"", "Libedit yes"); #else - phpdbg_writeln("Libedit\t\tno"); + phpdbg_writeln("print", "libedit=\"no\"", "Libedit no"); #endif - phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none"); - phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no"); - phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); - phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off"); - phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off"); + phpdbg_writeln("print", "context=\"%s\"", "Exec %s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none"); + phpdbg_writeln("print", "compiled=\"%s\"", "Compiled %s", PHPDBG_G(ops) ? "yes" : "no"); + phpdbg_writeln("print", "stepping=\"%s\"", "Stepping %s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); + phpdbg_writeln("print", "quiet=\"%s\"", "Quietness %s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off"); + phpdbg_writeln("print", "oplog=\"%s\"", "Oplog %s", PHPDBG_G(oplog) ? "on" : "off"); if (PHPDBG_G(ops)) { - phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last); - - if (PHPDBG_G(ops)->last_var) { - phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1); - } else { - phpdbg_writeln("Variables\tNone"); - } + phpdbg_writeln("print", "ops=\"%d\"", "Opcodes %d", PHPDBG_G(ops)->last); + phpdbg_writeln("print", "vars=\"%d\"", "Variables %d", PHPDBG_G(ops)->last_var ? PHPDBG_G(ops)->last_var - 1 : 0); } - phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no"); + phpdbg_writeln("print", "executing=\"%d\"", "Executing %s", EG(in_execution) ? "yes" : "no"); if (EG(in_execution)) { - phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret)); + phpdbg_writeln("print", "vmret=\"%d\"", "VM Return %d", PHPDBG_G(vmret)); } - phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table))); - phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table))); - phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants))); - phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files))); - - phpdbg_writeln(SEPARATE); + phpdbg_writeln("print", "classes=\"%d\"", "Classes %d", zend_hash_num_elements(EG(class_table))); + phpdbg_writeln("print", "functions=\"%d\"", "Functions %d", zend_hash_num_elements(EG(function_table))); + phpdbg_writeln("print", "constants=\"%d\"", "Constants %d", zend_hash_num_elements(EG(zend_constants))); + phpdbg_writeln("print", "includes=\"%d\"", "Included %d", zend_hash_num_elements(&EG(included_files))); + phpdbg_xml(""); return SUCCESS; } /* }}} */ PHPDBG_COMMAND(info) /* {{{ */ { - phpdbg_error( - "No information command selected!"); + phpdbg_error("info", "type=\"toofewargs\" expected=\"1\"", "No information command selected!"); return SUCCESS; } /* }}} */ PHPDBG_COMMAND(set) /* {{{ */ { - phpdbg_error( - "No set command selected!"); + phpdbg_error("set", "type=\"toofewargs\" expected=\"1\"", "No set command selected!"); return SUCCESS; } /* }}} */ @@ -789,8 +743,8 @@ PHPDBG_COMMAND(break) /* {{{ */ { if (!param) { phpdbg_set_breakpoint_file( - zend_get_executed_filename(TSRMLS_C), - zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); } else switch (param->type) { case ADDR_PARAM: phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC); @@ -799,7 +753,7 @@ PHPDBG_COMMAND(break) /* {{{ */ if (PHPDBG_G(exec)) { phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC); } else { - phpdbg_error("Execution context not set!"); + phpdbg_error("break", "type=\"noexec\"", "Execution context not set!"); } break; case METHOD_PARAM: @@ -837,42 +791,39 @@ PHPDBG_COMMAND(sh) /* {{{ */ { FILE *fd = NULL; if ((fd=VCWD_POPEN((char*)param->str, "w"))) { - /* do something perhaps ?? do we want input ?? */ + /* TODO: do something perhaps ?? do we want input ?? */ fclose(fd); } else { - phpdbg_error( - "Failed to execute %s", param->str); + phpdbg_error("sh", "type=\"failure\" smd=\"%s\"", "Failed to execute %s", param->str); } - + return SUCCESS; } /* }}} */ PHPDBG_COMMAND(source) /* {{{ */ { struct stat sb; - + if (VCWD_STAT(param->str, &sb) != -1) { phpdbg_try_file_init(param->str, param->len, 0 TSRMLS_CC); } else { - phpdbg_error( - "Failed to stat %s, file does not exist", param->str); + phpdbg_error("source", "type=\"nofile\" file=\"%s\"", "Failed to stat %s, file does not exist", param->str); } - + return SUCCESS; } /* }}} */ PHPDBG_COMMAND(export) /* {{{ */ { FILE *handle = VCWD_FOPEN(param->str, "w+"); - + if (handle) { phpdbg_export_breakpoints(handle TSRMLS_CC); fclose(handle); } else { - phpdbg_error( - "Failed to open or create %s, check path and permissions", param->str); + phpdbg_error("export", "type=\"openfailure\" file=\"%s\"", "Failed to open or create %s, check path and permissions", param->str); } - + return SUCCESS; } /* }}} */ @@ -884,18 +835,15 @@ PHPDBG_COMMAND(register) /* {{{ */ if (!zend_hash_exists(&PHPDBG_G(registered), lcname, lcname_len+1)) { if (zend_hash_find(EG(function_table), lcname, lcname_len+1, (void**) &function) == SUCCESS) { - zend_hash_update( - &PHPDBG_G(registered), lcname, lcname_len+1, (void*)&function, sizeof(zend_function), NULL); + zend_hash_update(&PHPDBG_G(registered), lcname, lcname_len+1, (void*)&function, sizeof(zend_function), NULL); function_add_ref(function); - phpdbg_notice( - "Registered %s", lcname); + phpdbg_notice("register", "function=\"%s\"", "Registered %s", lcname); } else { - phpdbg_error("The requested function (%s) could not be found", param->str); + phpdbg_error("register", "type=\"notfound\" function=\"%s\"", "The requested function (%s) could not be found", param->str); } } else { - phpdbg_error( - "The requested name (%s) is already in use", lcname); + phpdbg_error("register", "type=\"inuse\" function=\"%s\"", "The requested name (%s) is already in use", lcname); } efree(lcname); @@ -916,37 +864,43 @@ PHPDBG_COMMAND(quit) /* {{{ */ PHPDBG_COMMAND(clean) /* {{{ */ { if (EG(in_execution)) { - phpdbg_error("Cannot clean environment while executing"); + phpdbg_error("clean", "type=\"isrunning\"", "Cannot clean environment while executing"); return SUCCESS; } - phpdbg_notice("Cleaning Execution Environment"); + phpdbg_out("Cleaning Execution Environment"); + phpdbg_xml(""); - phpdbg_writeln("Classes\t\t\t%d", zend_hash_num_elements(EG(class_table))); - phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(EG(function_table))); - phpdbg_writeln("Constants\t\t%d", zend_hash_num_elements(EG(zend_constants))); - phpdbg_writeln("Includes\t\t%d", zend_hash_num_elements(&EG(included_files))); + phpdbg_writeln("clean", "classes=\"%d\"", "Classes %d", zend_hash_num_elements(EG(class_table))); + phpdbg_writeln("clean", "functions=\"%d\"", "Functions %d", zend_hash_num_elements(EG(function_table))); + phpdbg_writeln("clean", "constants=\"%d\"", "Constants %d", zend_hash_num_elements(EG(zend_constants))); + phpdbg_writeln("clean", "includes=\"%d\"", "Includes %d", zend_hash_num_elements(&EG(included_files))); phpdbg_clean(1 TSRMLS_CC); + phpdbg_xml(""); + return SUCCESS; } /* }}} */ PHPDBG_COMMAND(clear) /* {{{ */ { - phpdbg_notice("Clearing Breakpoints"); + phpdbg_out("Clearing Breakpoints"); + phpdbg_xml(""); - phpdbg_writeln("File\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE])); - phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM])); - phpdbg_writeln("Methods\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD])); - phpdbg_writeln("Oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE])); - phpdbg_writeln("File oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE])); - phpdbg_writeln("Function oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE])); - phpdbg_writeln("Method oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE])); - phpdbg_writeln("Conditionals\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_COND])); + phpdbg_writeln("clear", "files=\"%d\"", "File %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE])); + phpdbg_writeln("clear", "functions=\"%d\"", "Functions %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM])); + phpdbg_writeln("clear", "methods=\"%d\"", "Methods %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD])); + phpdbg_writeln("clear", "oplines=\"%d\"", "Oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE])); + phpdbg_writeln("clear", "fileoplines=\"%d\"", "File oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE])); + phpdbg_writeln("clear", "functionoplines=\"%d\"", "Function oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE])); + phpdbg_writeln("clear", "methodoplines=\"%d\"", "Method oplines %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE])); + phpdbg_writeln("clear", "eval=\"%d\"", "Conditionals %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_COND])); phpdbg_clear_breakpoints(TSRMLS_C); + phpdbg_xml(""); + return SUCCESS; } /* }}} */ @@ -981,7 +935,7 @@ PHPDBG_COMMAND(watch) /* {{{ */ } else switch (param->type) { case STR_PARAM: if (phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC) != FAILURE) { - phpdbg_notice("Set watchpoint on %.*s", (int)param->len, param->str); + phpdbg_notice("watch", "variable=\"%.*s\"", "Set watchpoint on %.*s", (int) param->len, param->str); } break; @@ -994,7 +948,6 @@ PHPDBG_COMMAND(watch) /* {{{ */ int phpdbg_interactive(TSRMLS_D) /* {{{ */ { int ret = SUCCESS; - char *why = NULL; char *input = NULL; phpdbg_param_t stack; @@ -1007,42 +960,36 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ phpdbg_init_param(&stack, STACK_PARAM); if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { - switch (ret = phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { + phpdbg_activate_err_buf(1 TSRMLS_CC); + + switch (ret = phpdbg_stack_execute(&stack TSRMLS_CC)) { case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { - if (why) { - phpdbg_error("%s", why); - } + phpdbg_output_err_buf(NULL, "%b", "%b" TSRMLS_CC); } } - - if (why) { - free(why); - why = NULL; - } break; case PHPDBG_LEAVE: case PHPDBG_FINISH: case PHPDBG_UNTIL: case PHPDBG_NEXT: { + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - phpdbg_error("Not running"); + phpdbg_error("command", "type=\"noexec\"", "Not running"); } goto out; } } - } - if (why) { - free(why); - why = NULL; + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); } phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); - } while ((input = phpdbg_read_input(NULL TSRMLS_CC))); } @@ -1052,10 +999,6 @@ out: phpdbg_destroy_input(&input TSRMLS_CC); } - if (why) { - free(why); - } - if (EG(in_execution)) { phpdbg_restore_frame(TSRMLS_C); } @@ -1105,9 +1048,9 @@ static inline zend_execute_data *phpdbg_create_execute_data(zend_op_array *op_ar ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) + ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC); - EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data))); - memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var); - EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2))); + EX(CVs) = (zval ***)((char *)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data))); + memset(EX(CVs), 0, sizeof(zval **) * op_array->last_var); + EX(Ts) = (temp_variable *)(((char *) EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2))); EX(fbc) = NULL; EX(called_scope) = NULL; EX(object) = NULL; @@ -1125,16 +1068,16 @@ static inline zend_execute_data *phpdbg_create_execute_data(zend_op_array *op_ar if (op_array->this_var != -1 && EG(This)) { Z_ADDREF_P(EG(This)); /* For $this pointer */ if (!EG(active_symbol_table)) { - EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var); + EX_CV(op_array->this_var) = (zval**) EX_CVs() + (op_array->last_var + op_array->this_var); *EX_CV(op_array->this_var) = EG(This); } else { - if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX_CV(op_array->this_var))==FAILURE) { + if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void **) &EX_CV(op_array->this_var))==FAILURE) { Z_DELREF_P(EG(This)); } } } - EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes; + EX(opline) = op_array->opcodes; EG(opline_ptr) = &EX(opline); EX(function_state).function = (zend_function *) op_array; @@ -1232,8 +1175,7 @@ zend_vm_enter: if (PHPDBG_G(flags) & PHPDBG_IN_UNTIL) { if (zend_hash_index_exists(&PHPDBG_G(seek), address)) { PHPDBG_G(flags) &= ~PHPDBG_IN_UNTIL; - zend_hash_clean( - &PHPDBG_G(seek)); + zend_hash_clean(&PHPDBG_G(seek)); } else { /* skip possible breakpoints */ goto next; @@ -1244,8 +1186,7 @@ zend_vm_enter: if (PHPDBG_G(flags) & PHPDBG_IN_FINISH) { if (zend_hash_index_exists(&PHPDBG_G(seek), address)) { PHPDBG_G(flags) &= ~PHPDBG_IN_FINISH; - zend_hash_clean( - &PHPDBG_G(seek)); + zend_hash_clean(&PHPDBG_G(seek)); } /* skip possible breakpoints */ goto next; @@ -1255,10 +1196,8 @@ zend_vm_enter: if (PHPDBG_G(flags) & PHPDBG_IN_LEAVE) { if (zend_hash_index_exists(&PHPDBG_G(seek), address)) { PHPDBG_G(flags) &= ~PHPDBG_IN_LEAVE; - zend_hash_clean( - &PHPDBG_G(seek)); - phpdbg_notice( - "Breaking for leave at %s:%u", + zend_hash_clean(&PHPDBG_G(seek)); + phpdbg_notice("breakpoint", "id=\"leave\" file=\"%s\" line=\"%u\"", "Breaking for leave at %s:%u", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C) ); @@ -1271,8 +1210,7 @@ zend_vm_enter: } /* not while in conditionals */ - phpdbg_print_opline_ex( - execute_data, &vars, 0 TSRMLS_CC); + phpdbg_print_opline_ex(execute_data, &vars, 0 TSRMLS_CC); if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING && (PHPDBG_G(flags) & PHPDBG_STEP_OPCODE || execute_data->opline->lineno != PHPDBG_G(last_line))) { PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; @@ -1300,8 +1238,8 @@ zend_vm_enter: next: if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { - phpdbg_writeln(EMPTY); - phpdbg_notice("Program received signal SIGINT"); + phpdbg_out("\n"); + phpdbg_notice("signal", "type=\"SIGINT\"", "Program received signal SIGINT"); PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED; DO_INTERACTIVE(); } diff --git a/phpdbg_set.c b/phpdbg_set.c index 54269a81931..e5d8d6d1dba 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -48,9 +48,11 @@ const phpdbg_command_t phpdbg_set_commands[] = { PHPDBG_SET(prompt) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("%s", phpdbg_get_prompt(TSRMLS_C)); - } else phpdbg_set_prompt(param->str TSRMLS_CC); - + phpdbg_writeln("prompt", "str=\"%s\"", "Current prompt: %s", phpdbg_get_prompt(TSRMLS_C)); + } else { + phpdbg_set_prompt(param->str TSRMLS_CC); + } + return SUCCESS; } /* }}} */ @@ -61,21 +63,21 @@ PHPDBG_SET(break) /* {{{ */ if (param->next) { if (param->next->num) { phpdbg_enable_breakpoint(param->num TSRMLS_CC); - } else phpdbg_disable_breakpoint(param->num TSRMLS_CC); + } else { + phpdbg_disable_breakpoint(param->num TSRMLS_CC); + } } else { phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num TSRMLS_CC); if (brake) { - phpdbg_writeln( - "%s", brake->disabled ? "off" : "on"); + phpdbg_writeln("setbreak", "id=\"%d\" active=\"%s\"", "Breakpoint #%d %s", param->num, brake->disabled ? "off" : "on"); } else { - phpdbg_error("Failed to find breakpoint #%ld", param->num); + phpdbg_error("setbreak", "type=\"nobreak\" id=\"%d\"", "Failed to find breakpoint #%ld", param->num); } } } break; default: - phpdbg_error( - "set break used incorrectly: set break [id] "); + phpdbg_error("setbreak", "type=\"wrongargs\"", "set break used incorrectly: set break [id] "); } return SUCCESS; @@ -84,18 +86,18 @@ PHPDBG_SET(break) /* {{{ */ PHPDBG_SET(breaks) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("%s", - PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off"); - } else switch (param->type) { + phpdbg_writeln("setbreaks", "active=\"%s\"", "Breakpoints %s",PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off"); + } else switch (param->type) { case NUMERIC_PARAM: { if (param->num) { phpdbg_enable_breakpoints(TSRMLS_C); - } else phpdbg_disable_breakpoints(TSRMLS_C); + } else { + phpdbg_disable_breakpoints(TSRMLS_C); + } } break; default: - phpdbg_error( - "set break used incorrectly: set break [id] "); + phpdbg_error("setbreaks", "type=\"wrongargs\"", "set breaks used incorrectly: set breaks "); } return SUCCESS; @@ -104,19 +106,16 @@ PHPDBG_SET(breaks) /* {{{ */ #ifndef _WIN32 PHPDBG_SET(color) /* {{{ */ { - const phpdbg_color_t *color = phpdbg_get_color( - param->next->str, param->next->len TSRMLS_CC); + const phpdbg_color_t *color = phpdbg_get_color(param->next->str, param->next->len TSRMLS_CC); if (!color) { - phpdbg_error( - "Failed to find the requested color (%s)", param->next->str); + phpdbg_error("setcolor", "type=\"nocolor\"", "Failed to find the requested color (%s)", param->next->str); return SUCCESS; } switch (phpdbg_get_element(param->str, param->len TSRMLS_CC)) { case PHPDBG_COLOR_PROMPT: - phpdbg_notice( - "setting prompt color to %s (%s)", color->name, color->code); + phpdbg_notice("setcolor", "type=\"prompt\" color=\"%s\" code=\"%s\"", "setting prompt color to %s (%s)", color->name, color->code); if (PHPDBG_G(prompt)[1]) { free(PHPDBG_G(prompt)[1]); PHPDBG_G(prompt)[1]=NULL; @@ -125,20 +124,17 @@ PHPDBG_SET(color) /* {{{ */ break; case PHPDBG_COLOR_ERROR: - phpdbg_notice( - "setting error color to %s (%s)", color->name, color->code); + phpdbg_notice("setcolor", "type=\"error\" color=\"%s\" code=\"%s\"", "setting error color to %s (%s)", color->name, color->code); phpdbg_set_color(PHPDBG_COLOR_ERROR, color TSRMLS_CC); break; case PHPDBG_COLOR_NOTICE: - phpdbg_notice( - "setting notice color to %s (%s)", color->name, color->code); + phpdbg_notice("setcolor", "type=\"notice\" color=\"%s\" code=\"%s\"", "setting notice color to %s (%s)", color->name, color->code); phpdbg_set_color(PHPDBG_COLOR_NOTICE, color TSRMLS_CC); break; default: - phpdbg_error( - "Failed to find the requested element (%s)", param->str); + phpdbg_error("setcolor", "type=\"invalidelement\"", "Failed to find the requested element (%s)", param->str); } return SUCCESS; @@ -147,7 +143,7 @@ PHPDBG_SET(color) /* {{{ */ PHPDBG_SET(colors) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("%s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off"); + phpdbg_writeln("setcolors", "active=\"%s\"", "Colors %s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off"); } else switch (param->type) { case NUMERIC_PARAM: { if (param->num) { @@ -158,8 +154,7 @@ PHPDBG_SET(colors) /* {{{ */ } break; default: - phpdbg_error( - "set colors used incorrectly: set colors "); + phpdbg_error("setcolors", "type=\"wrongargs\"", "set colors used incorrectly: set colors "); } return SUCCESS; @@ -169,7 +164,7 @@ PHPDBG_SET(colors) /* {{{ */ PHPDBG_SET(oplog) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_notice("Oplog %s", PHPDBG_G(oplog) ? "enabled" : "disabled"); + phpdbg_notice("setoplog", "active=\"%s\"", "Oplog %s", PHPDBG_G(oplog) ? "on" : "off"); } else switch (param->type) { case STR_PARAM: { /* open oplog */ @@ -177,14 +172,15 @@ PHPDBG_SET(oplog) /* {{{ */ PHPDBG_G(oplog) = fopen(param->str, "w+"); if (!PHPDBG_G(oplog)) { - phpdbg_error("Failed to open %s for oplog", param->str); + phpdbg_error("setoplog", "file=\"%s\"", "Failed to open %s for oplog", param->str); PHPDBG_G(oplog) = old; } else { if (old) { - phpdbg_notice("Closing previously open oplog"); + phpdbg_notice("setoplog", "type=\"closingold\"", "Closing previously open oplog"); fclose(old); } - phpdbg_notice("Successfully opened oplog %s", param->str); + + phpdbg_notice("setoplog", "file=\"%s\"", "Successfully opened oplog %s", param->str); } } break; @@ -197,8 +193,7 @@ PHPDBG_SET(oplog) /* {{{ */ PHPDBG_SET(quiet) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("Quietness %s", - PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + phpdbg_writeln("setquiet", "active=\"%s\"", "Quietness %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); } else switch (param->type) { case NUMERIC_PARAM: { if (param->num) { @@ -217,18 +212,15 @@ PHPDBG_SET(quiet) /* {{{ */ PHPDBG_SET(stepping) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("Stepping %s", - PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line"); + phpdbg_writeln("setstepping", "type=\"%s\"", "Stepping %s", PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line"); } else switch (param->type) { - case STR_PARAM: { - if ((param->len == sizeof("opcode")-1) && - (memcmp(param->str, "opcode", sizeof("opcode")) == SUCCESS)) { + case STR_PARAM: { + if ((param->len == sizeof("opcode") - 1) && memcmp(param->str, "opcode", sizeof("opcode") == SUCCESS)) { PHPDBG_G(flags) |= PHPDBG_STEP_OPCODE; - } else if ((param->len == sizeof("line")-1) && - (memcmp(param->str, "line", sizeof("line")) == SUCCESS)) { + } else if ((param->len == sizeof("line")-1) && memcmp(param->str, "line", sizeof("line")) == SUCCESS) { PHPDBG_G(flags) &= ~PHPDBG_STEP_OPCODE; } else { - phpdbg_error("usage set stepping []"); + phpdbg_error("setstepping", "type=\"wrongargs\"", "usage set stepping []"); } } break; @@ -241,7 +233,7 @@ PHPDBG_SET(stepping) /* {{{ */ PHPDBG_SET(refcount) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("Refcount %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + phpdbg_writeln("setrefcount", "active=\"%s\"", "Showing refcounts %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); } else switch (param->type) { case NUMERIC_PARAM: { if (param->num) { diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 3ce2fade17d..25c2199649f 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -27,10 +27,11 @@ #include "phpdbg.h" #include "phpdbg_opcode.h" #include "phpdbg_utils.h" +#include "ext/standard/html.h" #ifdef _WIN32 # include "win32/time.h" -#elif defined(HAVE_SYS_IOCTL_H) +#elif defined(HAVE_SYS_IOCTL_H) # include "sys/ioctl.h" # ifndef GWINSZ_IN_SYS_IOCTL # include @@ -128,12 +129,12 @@ PHPDBG_API int phpdbg_is_class_method(const char *str, size_t len, char **class, } if (class != NULL) { - + if (str[0] == '\\') { str++; len--; } - + *class = estrndup(str, sep - str); (*class)[sep - str] = 0; } @@ -224,75 +225,1070 @@ PHPDBG_API char *phpdbg_trim(const char *str, size_t len, size_t *new_len) /* {{ } /* }}} */ -PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, ...) /* {{{ */ -{ - int rc = 0; - char *buffer = NULL; - va_list args; +/* copied from php-src/main/snprintf.c and slightly modified */ +/* + * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions + * + * XXX: this is a magic number; do not decrease it + * Emax = 1023 + * NDIG = 320 + * NUM_BUF_SIZE >= strlen("-") + Emax + strlrn(".") + NDIG + strlen("E+1023") + 1; + */ +#define NUM_BUF_SIZE 2048 - if (format != NULL && strlen(format) > 0L) { - va_start(args, format); - vspprintf(&buffer, 0, format, args); - va_end(args); +/* + * Descriptor for buffer area + */ +struct buf_area { + char *buf_end; + char *nextb; /* pointer to next byte to read/write */ +}; + +typedef struct buf_area buffy; + +/* + * The INS_CHAR macro inserts a character in the buffer and writes + * the buffer back to disk if necessary + * It uses the char pointers sp and bep: + * sp points to the next available character in the buffer + * bep points to the end-of-buffer+1 + * While using this macro, note that the nextb pointer is NOT updated. + * + * NOTE: Evaluation of the c argument should not have any side-effects + */ +#define INS_CHAR(c, sp, bep, cc) \ + { \ + if (sp < bep) \ + { \ + *sp++ = c; \ + } \ + cc++; \ + } + +#define NUM( c ) ( c - '0' ) + +#define STR_TO_DEC( str, num ) \ + num = NUM( *str++ ) ; \ + while ( isdigit((int)*str ) ) \ + { \ + num *= 10 ; \ + num += NUM( *str++ ) ; \ + } + +/* + * This macro does zero padding so that the precision + * requirement is satisfied. The padding is done by + * adding '0's to the left of the string that is going + * to be printed. + */ +#define FIX_PRECISION( adjust, precision, s, s_len ) \ + if ( adjust ) \ + while ( s_len < precision ) \ + { \ + *--s = '0' ; \ + s_len++ ; \ + } + +/* + * Macro that does padding. The padding is done by printing + * the character ch. + */ +#define PAD( width, len, ch ) do \ + { \ + INS_CHAR( ch, sp, bep, cc ) ; \ + width-- ; \ + } \ + while ( width > len ) + +/* + * Prefix the character ch to the string str + * Increase length + * Set the has_prefix flag + */ +#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES + + +#ifdef HAVE_LOCALE_H +#include +#define LCONV_DECIMAL_POINT (*lconv->decimal_point) +#else +#define LCONV_DECIMAL_POINT '.' +#endif +#define NUL '\0' +#define S_NULL "(null)" +#define S_NULL_LEN 6 +#define FLOAT_DIGITS 6 + +/* + * Do format conversion placing the output in buffer + */ +static int format_converter(register buffy *odp, const char *fmt, zend_bool escape_xml, va_list ap TSRMLS_DC) { + char *sp; + char *bep; + int cc = 0; + int i; + + char *s = NULL, *free_s = NULL; + int s_len, free_zcopy; + zval *zvp, zcopy; + + int min_width = 0; + int precision = 0; + enum { + LEFT, RIGHT + } adjust; + char pad_char; + char prefix_char; + + double fp_num; + wide_int i_num = (wide_int) 0; + u_wide_int ui_num; + + char num_buf[NUM_BUF_SIZE]; + char char_buf[2]; /* for printing %% and % */ + +#ifdef HAVE_LOCALE_H + struct lconv *lconv = NULL; +#endif + + /* + * Flag variables + */ + length_modifier_e modifier; + boolean_e alternate_form; + boolean_e print_sign; + boolean_e print_blank; + boolean_e adjust_precision; + boolean_e adjust_width; + bool_int is_negative; + + sp = odp->nextb; + bep = odp->buf_end; + + while (*fmt) { + if (*fmt != '%') { + INS_CHAR(*fmt, sp, bep, cc); + } else { + /* + * Default variable settings + */ + adjust = RIGHT; + alternate_form = print_sign = print_blank = NO; + pad_char = ' '; + prefix_char = NUL; + free_zcopy = 0; + + fmt++; + + /* + * Try to avoid checking for flags, width or precision + */ + if (isascii((int)*fmt) && !islower((int)*fmt)) { + /* + * Recognize flags: -, #, BLANK, + + */ + for (;; fmt++) { + if (*fmt == '-') + adjust = LEFT; + else if (*fmt == '+') + print_sign = YES; + else if (*fmt == '#') + alternate_form = YES; + else if (*fmt == ' ') + print_blank = YES; + else if (*fmt == '0') + pad_char = '0'; + else + break; + } + + /* + * Check if a width was specified + */ + if (isdigit((int)*fmt)) { + STR_TO_DEC(fmt, min_width); + adjust_width = YES; + } else if (*fmt == '*') { + min_width = va_arg(ap, int); + fmt++; + adjust_width = YES; + if (min_width < 0) { + adjust = LEFT; + min_width = -min_width; + } + } else + adjust_width = NO; + + /* + * Check if a precision was specified + */ + if (*fmt == '.') { + adjust_precision = YES; + fmt++; + if (isdigit((int)*fmt)) { + STR_TO_DEC(fmt, precision); + } else if (*fmt == '*') { + precision = va_arg(ap, int); + fmt++; + if (precision < 0) + precision = 0; + } else + precision = 0; + + if (precision > FORMAT_CONV_MAX_PRECISION) { + precision = FORMAT_CONV_MAX_PRECISION; + } + } else + adjust_precision = NO; + } else + adjust_precision = adjust_width = NO; + + /* + * Modifier check + */ + switch (*fmt) { + case 'L': + fmt++; + modifier = LM_LONG_DOUBLE; + break; + case 'I': + fmt++; +#if SIZEOF_LONG_LONG + if (*fmt == '6' && *(fmt+1) == '4') { + fmt += 2; + modifier = LM_LONG_LONG; + } else +#endif + if (*fmt == '3' && *(fmt+1) == '2') { + fmt += 2; + modifier = LM_LONG; + } else { +#ifdef _WIN64 + modifier = LM_LONG_LONG; +#else + modifier = LM_LONG; +#endif + } + break; + case 'l': + fmt++; +#if SIZEOF_LONG_LONG + if (*fmt == 'l') { + fmt++; + modifier = LM_LONG_LONG; + } else +#endif + modifier = LM_LONG; + break; + case 'z': + fmt++; + modifier = LM_SIZE_T; + break; + case 'j': + fmt++; +#if SIZEOF_INTMAX_T + modifier = LM_INTMAX_T; +#else + modifier = LM_SIZE_T; +#endif + break; + case 't': + fmt++; +#if SIZEOF_PTRDIFF_T + modifier = LM_PTRDIFF_T; +#else + modifier = LM_SIZE_T; +#endif + break; + case 'h': + fmt++; + if (*fmt == 'h') { + fmt++; + } + /* these are promoted to int, so no break */ + default: + modifier = LM_STD; + break; + } + + /* + * Argument extraction and printing. + * First we determine the argument type. + * Then, we convert the argument to a string. + * On exit from the switch, s points to the string that + * must be printed, s_len has the length of the string + * The precision requirements, if any, are reflected in s_len. + * + * NOTE: pad_char may be set to '0' because of the 0 flag. + * It is reset to ' ' by non-numeric formats + */ + switch (*fmt) { + case 'Z': + zvp = (zval*) va_arg(ap, zval*); + zend_make_printable_zval(zvp, &zcopy, &free_zcopy); + if (free_zcopy) { + zvp = &zcopy; + } + s_len = Z_STRLEN_P(zvp); + s = Z_STRVAL_P(zvp); + if (adjust_precision && precision < s_len) { + s_len = precision; + } + break; + case 'u': + switch(modifier) { + default: + i_num = (wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG_DOUBLE: + goto fmt_error; + case LM_LONG: + i_num = (wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + i_num = (wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + i_num = (wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + i_num = (wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + i_num = (wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + /* + * The rest also applies to other integer formats, so fall + * into that case. + */ + case 'd': + case 'i': + /* + * Get the arg if we haven't already. + */ + if ((*fmt) != 'u') { + switch(modifier) { + default: + i_num = (wide_int) va_arg(ap, int); + break; + case LM_LONG_DOUBLE: + goto fmt_error; + case LM_LONG: + i_num = (wide_int) va_arg(ap, long int); + break; + case LM_SIZE_T: +#if SIZEOF_SSIZE_T + i_num = (wide_int) va_arg(ap, ssize_t); +#else + i_num = (wide_int) va_arg(ap, size_t); +#endif + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + i_num = (wide_int) va_arg(ap, wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + i_num = (wide_int) va_arg(ap, intmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + i_num = (wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + } + s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + FIX_PRECISION(adjust_precision, precision, s, s_len); + + if (*fmt != 'u') { + if (is_negative) { + prefix_char = '-'; + } else if (print_sign) { + prefix_char = '+'; + } else if (print_blank) { + prefix_char = ' '; + } + } + break; + + + case 'o': + switch(modifier) { + default: + ui_num = (u_wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG_DOUBLE: + goto fmt_error; + case LM_LONG: + ui_num = (u_wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + ui_num = (u_wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + ui_num = (u_wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + s = ap_php_conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); + FIX_PRECISION(adjust_precision, precision, s, s_len); + if (alternate_form && *s != '0') { + *--s = '0'; + s_len++; + } + break; + + + case 'x': + case 'X': + switch(modifier) { + default: + ui_num = (u_wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG_DOUBLE: + goto fmt_error; + case LM_LONG: + ui_num = (u_wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + ui_num = (u_wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + ui_num = (u_wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + s = ap_php_conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); + FIX_PRECISION(adjust_precision, precision, s, s_len); + if (alternate_form && i_num != 0) { + *--s = *fmt; /* 'x' or 'X' */ + *--s = '0'; + s_len += 2; + } + break; + + + case 's': + case 'v': + s = va_arg(ap, char *); + if (s != NULL) { + s_len = strlen(s); + + if (adjust_precision && precision < s_len) { + s_len = precision; + } + + if (escape_xml) { + /* added: support for xml escaping */ + + int old_slen = s_len, i = 0; + char *old_s = s, *s_ptr; + free_s = s_ptr = s = malloc(old_slen * 6 + 1); + do { + if (old_s[i] == '&' || old_s[i] == '"') { + *s_ptr++ = '&'; + if (old_s[i] == '"') { + s_len += 5; + *s_ptr++ = 'q'; + *s_ptr++ = 'u'; + *s_ptr++ = 'o'; + *s_ptr++ = 't'; + } else { + s_len += 4; + *s_ptr++ = 'a'; + *s_ptr++ = 'm'; + *s_ptr++ = 'p'; + } + *s_ptr++ = ';'; + } else { + *s_ptr++ = s[i]; + } + } while (i++ < old_slen); + } + } else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + break; + + + case 'b': + if (escape_xml) { + s = PHPDBG_G(err_buf).xml; + } else { + s = PHPDBG_G(err_buf).msg; + } + + if (s != NULL) { + if (escape_xml) { + s_len = PHPDBG_G(err_buf).xmllen; + } else { + s_len = PHPDBG_G(err_buf).msglen; + } + + if (adjust_precision && precision < s_len) { + s_len = precision; + } + } else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + break; + + + case 'f': + case 'F': + case 'e': + case 'E': + + switch(modifier) { + case LM_LONG_DOUBLE: + fp_num = (double) va_arg(ap, long double); + break; + case LM_STD: + fp_num = va_arg(ap, double); + break; + default: + goto fmt_error; + } + + if (zend_isnan(fp_num)) { + s = "NAN"; + s_len = 3; + } else if (zend_isinf(fp_num)) { + s = "INF"; + s_len = 3; + } else { +#ifdef HAVE_LOCALE_H + if (!lconv) { + lconv = localeconv(); + } +#endif + s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form, + (adjust_precision == NO) ? FLOAT_DIGITS : precision, + (*fmt == 'f')?LCONV_DECIMAL_POINT:'.', + &is_negative, &num_buf[1], &s_len); + if (is_negative) + prefix_char = '-'; + else if (print_sign) + prefix_char = '+'; + else if (print_blank) + prefix_char = ' '; + } + break; + + + case 'g': + case 'k': + case 'G': + case 'H': + switch(modifier) { + case LM_LONG_DOUBLE: + fp_num = (double) va_arg(ap, long double); + break; + case LM_STD: + fp_num = va_arg(ap, double); + break; + default: + goto fmt_error; + } + + if (zend_isnan(fp_num)) { + s = "NAN"; + s_len = 3; + break; + } else if (zend_isinf(fp_num)) { + if (fp_num > 0) { + s = "INF"; + s_len = 3; + } else { + s = "-INF"; + s_len = 4; + } + break; + } + + if (adjust_precision == NO) { + precision = FLOAT_DIGITS; + } else if (precision == 0) { + precision = 1; + } + /* + * * We use &num_buf[ 1 ], so that we have room for the sign + */ +#ifdef HAVE_LOCALE_H + if (!lconv) { + lconv = localeconv(); + } +#endif + s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]); + if (*s == '-') { + prefix_char = *s++; + } else if (print_sign) { + prefix_char = '+'; + } else if (print_blank) { + prefix_char = ' '; + } + + s_len = strlen(s); + + if (alternate_form && (strchr(s, '.')) == NULL) { + s[s_len++] = '.'; + } + break; + + + case 'c': + char_buf[0] = (char) (va_arg(ap, int)); + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; + break; + + + case '%': + char_buf[0] = '%'; + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; + break; + + + case 'n': + *(va_arg(ap, int *)) = cc; + goto skip_output; + + /* + * Always extract the argument as a "char *" pointer. We + * should be using "void *" but there are still machines + * that don't understand it. + * If the pointer size is equal to the size of an unsigned + * integer we convert the pointer to a hex number, otherwise + * we print "%p" to indicate that we don't handle "%p". + */ + case 'p': + if (sizeof(char *) <= sizeof(u_wide_int)) { + ui_num = (u_wide_int)((size_t) va_arg(ap, char *)); + s = ap_php_conv_p2(ui_num, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + if (ui_num != 0) { + *--s = 'x'; + *--s = '0'; + s_len += 2; + } + } else { + s = "%p"; + s_len = 2; + } + pad_char = ' '; + break; + + + case NUL: + /* + * The last character of the format string was %. + * We ignore it. + */ + continue; + + +fmt_error: + php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt); + /* + * The default case is for unrecognized %'s. + * We print % to help the user identify what + * option is not understood. + * This is also useful in case the user wants to pass + * the output of format_converter to another function + * that understands some other % (like syslog). + * Note that we can't point s inside fmt because the + * unknown could be preceded by width etc. + */ + default: + char_buf[0] = '%'; + char_buf[1] = *fmt; + s = char_buf; + s_len = 2; + pad_char = ' '; + break; + } + + if (prefix_char != NUL) { + *--s = prefix_char; + s_len++; + } + if (adjust_width && adjust == RIGHT && min_width > s_len) { + if (pad_char == '0' && prefix_char != NUL) { + INS_CHAR(*s, sp, bep, cc) + s++; + s_len--; + min_width--; + } + PAD(min_width, s_len, pad_char); + } + /* + * Print the string s. + */ + for (i = s_len; i != 0; i--) { + INS_CHAR(*s, sp, bep, cc); + s++; + } + + if (adjust_width && adjust == LEFT && min_width > s_len) + PAD(min_width, s_len, pad_char); + if (free_zcopy) { + zval_dtor(&zcopy); + } + } +skip_output: + if (free_s) { + free(free_s); + free_s = NULL; + } + + fmt++; + } + odp->nextb = sp; + return (cc); +} + +static void strx_printv(int *ccp, char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { + buffy od; + int cc; + + /* + * First initialize the descriptor + * Notice that if no length is given, we initialize buf_end to the + * highest possible address. + */ + if (len == 0) { + od.buf_end = (char *) ~0; + od.nextb = (char *) ~0; + } else { + od.buf_end = &buf[len-1]; + od.nextb = buf; + } + + /* + * Do the conversion + */ + cc = format_converter(&od, format, escape_xml, ap TSRMLS_CC); + if (len != 0 && od.nextb <= od.buf_end) { + *(od.nextb) = '\0'; + } + if (ccp) { + *ccp = cc; + } +} + +static int phpdbg_xml_vsnprintf(char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { + int cc; + + strx_printv(&cc, buf, len, format, escape_xml, ap TSRMLS_CC); + return (cc); +} + +PHPAPI int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { + va_list ap2; + int cc; + + va_copy(ap2, ap); + cc = phpdbg_xml_vsnprintf(NULL, 0, format, escape_xml, ap2 TSRMLS_CC); + va_end(ap2); + + *buf = NULL; + + if (cc >= 0) { + if ((*buf = malloc(++cc)) != NULL) { + if ((cc = phpdbg_xml_vsnprintf(*buf, cc, format, escape_xml, ap TSRMLS_CC)) < 0) { + free(*buf); + *buf = NULL; + } + } + } + + return cc; +} +/* copy end */ + +static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char *msg, int msglen, const char *xml, int xmllen TSRMLS_DC) { + char *msgout, *buf; + int msgoutlen, xmloutlen, buflen; + const char *severity; + + if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML) && PHPDBG_G(in_script_xml) && PHPDBG_G(in_script_xml) != type) { + fprintf(fp, ""); + PHPDBG_G(in_script_xml) = 0; } /* TODO(anyone) colours */ switch (type) { case P_ERROR: + severity = "error"; if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - rc = fprintf(fp, - "\033[%sm[%s]\033[0m\n", - PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, buffer); + msgoutlen = asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); } else { - rc = fprintf(fp, "[%s]\n", buffer); + msgoutlen = asprintf(&msgout, "[%.*s]\n", msglen, msg); } - break; + break; case P_NOTICE: + severity = "notice"; if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - rc = fprintf(fp, - "\033[%sm[%s]\033[0m\n", - PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, buffer); + msgoutlen = asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); } else { - rc = fprintf(fp, "[%s]\n", buffer); + msgoutlen = asprintf(&msgout, "[%.*s]\n", msglen, msg); } - break; + break; - case P_WRITELN: { - if (buffer) { - rc = fprintf(fp, "%s\n", buffer); + case P_WRITELN: + severity = "normal"; + if (msg) { + msgoutlen = asprintf(&msgout, "%.*s\n", msglen, msg); } else { - rc = fprintf(fp, "\n"); + msgoutlen = asprintf(&msgout, "\n"); } - } break; + break; case P_WRITE: - if (buffer) { - rc = fprintf(fp, "%s", buffer); + severity = "normal"; + if (msg) { + msgoutlen = asprintf(&msgout, "%.*s\n", msglen, msg); + } else { + msgoutlen = asprintf(&msgout, ""); + } + break; + + case P_STDOUT: + case P_STDERR: + if (msg) { + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + if (PHPDBG_G(in_script_xml) != type) { + fprintf(fp, "", type == P_STDERR ? "stderr" : "stdout"); + PHPDBG_G(in_script_xml) = type; + } + buf = php_escape_html_entities((char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); + fprintf(fp, "%.*s", buflen, buf); + efree(buf); + } else { + fprintf(fp, "%.*s", msglen, msg); + } + return msglen; } break; /* no formatting on logging output */ case P_LOG: - if (buffer) { + severity = "log"; + if (msg) { struct timeval tp; if (gettimeofday(&tp, NULL) == SUCCESS) { - rc = fprintf(fp, "[%ld %.8F]: %s\n", tp.tv_sec, tp.tv_usec / 1000000.00, buffer); + msgoutlen = asprintf(&msgout, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); } else { - rc = FAILURE; + msgoutlen = FAILURE; } } break; } - if (buffer) { - efree(buffer); + + if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { + if (msgout) { + buf = php_escape_html_entities(msgout, msgoutlen, (size_t *) &buflen, 0, ENT_COMPAT, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); + xmloutlen = fprintf(fp, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf); + + efree(buf); + } else { + xmloutlen = fprintf(fp, "<%s severity=\"%s\" %.*s msgout=\"\" />", tag, severity, xmllen, xml); + } + } else if (msgout) { + fprintf(fp, "%.*s", msgoutlen, msgout); } - return rc; + if (msgout) { + free(msgout); + } + + return msgout ? msgoutlen : xmloutlen; } /* }}} */ +PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D) { + if (PHPDBG_G(err_buf).type == 0) { + return; + } + + PHPDBG_G(err_buf).type = 0; + + efree(PHPDBG_G(err_buf).tag); + efree(PHPDBG_G(err_buf).msg); + efree(PHPDBG_G(err_buf).xml); +} + +PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC) { + PHPDBG_G(err_buf).active = active; +} + +PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt TSRMLS_DC, ...) { + int len; + va_list args; + int errbuf_active = PHPDBG_G(err_buf).active; + + PHPDBG_G(err_buf).active = 0; + +#ifdef ZTS + va_start(args, tsrm_ls); +#else + va_start(args, strfmt); +#endif + len = phpdbg_vprint(PHPDBG_G(err_buf).type TSRMLS_CC, PHPDBG_G(err_buf).fp, tag ? tag : PHPDBG_G(err_buf).tag, xmlfmt, strfmt, args); + va_end(args); + + PHPDBG_G(err_buf).active = errbuf_active; + phpdbg_free_err_buf(TSRMLS_C); + + return len; +} + +PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, FILE *fp, const char *tag, const char *xmlfmt, const char *strfmt, va_list args) { + char *msg = NULL, *xml = NULL; + int msglen = 0, xmllen = 0; + int len; + + if (strfmt != NULL && strlen(strfmt) > 0L) { + msglen = phpdbg_xml_vasprintf(&msg, strfmt, 0, args TSRMLS_CC); + } + + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + if (xmlfmt != NULL && strlen(xmlfmt) > 0L) { + xmllen = phpdbg_xml_vasprintf(&xml, xmlfmt, 1, args TSRMLS_CC); + } + } + + if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) { + PHPDBG_G(err_buf).type = type; + PHPDBG_G(err_buf).fp = fp; + PHPDBG_G(err_buf).tag = estrdup(tag); + PHPDBG_G(err_buf).msg = msg; + PHPDBG_G(err_buf).msglen = msglen; + PHPDBG_G(err_buf).xml = xml; + PHPDBG_G(err_buf).xmllen = xmllen; + + return msglen; + } + + len = phpdbg_process_print(fp, type, tag, msg, msglen, xml, xmllen TSRMLS_CC); + + if (msg) { + free(msg); + } + + if (xml) { + free(xml); + } + + return len; +} + +PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *tag, const char *xmlfmt, const char *strfmt, ...) { + va_list args; + + va_start(args, strfmt); + phpdbg_vprint(type TSRMLS_CC, fp, tag, xmlfmt, strfmt, args); + va_end(args); +} + +PHPDBG_API int phpdbg_xml_internal(FILE *fp TSRMLS_DC, const char *fmt, ...) { + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + va_list args; + char *buffer; + int buflen; + + va_start(args, fmt); + buflen = vspprintf(&buffer, 0, fmt, args); + va_end(args); + + if (PHPDBG_G(in_script_xml)) { + fprintf(fp, ""); + PHPDBG_G(in_script_xml) = 0; + } + + return fprintf(fp, "%.*s", buflen, buffer); + } + + return 0; +} + +PHPDBG_API int phpdbg_log_internal(FILE *fp TSRMLS_DC, const char *fmt, ...) { + va_list args; + char *buffer; + int buflen; + + va_start(args, fmt); + buflen = vspprintf(&buffer, 0, fmt, args); + va_end(args); + + return fprintf(fp, "%.*s", buflen, buffer); +} + +PHPDBG_API int phpdbg_out_internal(FILE *fp TSRMLS_DC, const char *fmt, ...) { + va_list args; + char *buffer; + int buflen; + + va_start(args, fmt); + buflen = vspprintf(&buffer, 0, fmt, args); + va_end(args); + + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + if (PHPDBG_G(in_script_xml)) { + fprintf(fp, ""); + PHPDBG_G(in_script_xml) = 0; + } + + fprintf(fp, "%.*s", buflen, buffer); + return buflen; + } else { + return fprintf(fp, "%.*s", buflen, buffer); + } +} + + PHPDBG_API int phpdbg_rlog(FILE *fp, const char *fmt, ...) { /* {{{ */ int rc = 0; @@ -306,12 +1302,9 @@ PHPDBG_API int phpdbg_rlog(FILE *fp, const char *fmt, ...) { /* {{{ */ const time_t tt = tp.tv_sec; strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt)); - asprintf( - &buffer, friendly, tp.tv_usec/1000); - asprintf( - &format, "[%s]: %s\n", buffer, fmt); - rc = vfprintf( - fp, format, args); + asprintf(&buffer, friendly, tp.tv_usec/1000); + asprintf(&format, "[%s]: %s\n", buffer, fmt); + rc = vfprintf(fp, format, args); free(format); free(buffer); @@ -328,15 +1321,13 @@ PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_ while (color && color->name) { if (name_length == color->name_length && memcmp(name, color->name, name_length) == SUCCESS) { - phpdbg_debug( - "phpdbg_get_color(%s, %lu): %s", name, name_length, color->code); + phpdbg_debug("phpdbg_get_color(%s, %lu): %s", name, name_length, color->code); return color; } ++color; } - phpdbg_debug( - "phpdbg_get_color(%s, %lu): failed", name, name_length); + phpdbg_debug("phpdbg_get_color(%s, %lu): failed", name, name_length); return NULL; } /* }}} */ @@ -420,7 +1411,7 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ int phpdbg_rebuild_symtable(TSRMLS_D) { if (!EG(active_op_array)) { - phpdbg_error("No active op array!"); + phpdbg_error("symtable", "type=\"noops\"", "No active op array!"); return FAILURE; } @@ -428,7 +1419,7 @@ int phpdbg_rebuild_symtable(TSRMLS_D) { zend_rebuild_symbol_table(TSRMLS_C); if (!EG(active_symbol_table)) { - phpdbg_error("No active symbol table!"); + phpdbg_error("symtable", "type=\"nosymtable\"", "No active symbol table!"); return FAILURE; } } @@ -444,7 +1435,7 @@ PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D) /* {{{ */ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; -#elif defined(HAVE_SYS_IOCTL_H) && defined (TIOCGWINSZ) +#elif defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ) struct winsize w; columns = ioctl(fileno(stdout), TIOCGWINSZ, &w) == 0 ? w.ws_col : 80; diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 56bacfc4596..42d24164100 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -41,40 +41,51 @@ enum { P_NOTICE, P_WRITELN, P_WRITE, + P_STDOUT, + P_STDERR, P_LOG }; #ifdef ZTS -PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUTE_FORMAT(printf, 4, 5); +PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE *, const char *, const char *, const char *, ...) PHP_ATTRIBUTE_FORMAT(printf, 6, 7); #else -PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE *, const char *, const char *, const char *, ...) PHP_ATTRIBUTE_FORMAT(printf, 5, 6); #endif +PHPDBG_API int phpdbg_xml_internal(FILE *fp TSRMLS_DC, const char *fmt, ...); +PHPDBG_API int phpdbg_log_internal(FILE *fp TSRMLS_DC, const char *fmt, ...); +PHPDBG_API int phpdbg_out_internal(FILE *fp TSRMLS_DC, const char *fmt, ...); + PHPDBG_API int phpdbg_rlog(FILE *stream, const char *fmt, ...); -#define phpdbg_error(fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) -#define phpdbg_notice(fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) -#define phpdbg_writeln(fmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) -#define phpdbg_write(fmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) -#define phpdbg_log(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) +#define phpdbg_error(tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_notice(tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_writeln(tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_write(tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_script(type, fmt, ...) phpdbg_print(type TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], NULL, NULL, fmt, ##__VA_ARGS__) +#define phpdbg_log(fmt, ...) phpdbg_log_internal(PHPDBG_G(io)[PHPDBG_STDOUT] TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_xml(fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT] TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_out(fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT] TSRMLS_CC, fmt, ##__VA_ARGS__) -#define phpdbg_error_ex(out, fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, out, fmt, ##__VA_ARGS__) -#define phpdbg_notice_ex(out, fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, out, fmt, ##__VA_ARGS__) -#define phpdbg_writeln_ex(out, fmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, out, fmt, ##__VA_ARGS__) -#define phpdbg_write_ex(out, fmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, out, fmt, ##__VA_ARGS__) -#define phpdbg_log_ex(out, fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, out, fmt, ##__VA_ARGS__) +#define phpdbg_error_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_notice_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_writeln_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_write_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_script_ex(out, type, fmt, ...) phpdbg_print(type TSRMLS_CC, out, NULL, NULL, fmt, ##__VA_ARGS__) +#define phpdbg_log_ex(out, fmt, ...) phpdbg_log_internal(PHPDBG_G(io)[PHPDBG_STDOUT] TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_xml_ex(out, fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT] TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_out_ex(out, fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT] TSRMLS_CC, fmt, ##__VA_ARGS__) #if PHPDBG_DEBUG -# define phpdbg_debug(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDERR], fmt, ##__VA_ARGS__) +# define phpdbg_debug(fmt, ...) phpdbg_log_ex(PHPDBG_G(io)[PHPDBG_STDERR] TSRMLS_CC, fmt, ##__VA_ARGS__) #else # define phpdbg_debug(fmt, ...) #endif -/* {{{ For writing blank lines */ -#define EMPTY NULL /* }}} */ +PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D); +PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC); +PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt TSRMLS_DC, ...); -/* {{{ For prompt lines */ -#define PROMPT "phpdbg>" /* }}} */ /* {{{ For separation */ #define SEPARATE "------------------------------------------------" /* }}} */ @@ -112,7 +123,7 @@ typedef struct _phpdbg_element_t { PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_length TSRMLS_DC); PHPDBG_API void phpdbg_set_color(int element, const phpdbg_color_t *color TSRMLS_DC); PHPDBG_API void phpdbg_set_color_ex(int element, const char *name, size_t name_length TSRMLS_DC); -PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D); +PHPDBG_API const phpdbg_color_t *phpdbg_get_colors(TSRMLS_D); PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC); /* }}} */ /* {{{ Prompt Management */ diff --git a/phpdbg_watch.c b/phpdbg_watch.c index e88622444bf..128a9e7cedf 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -190,7 +190,7 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ } new_watch->str = NULL; - new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%s%s", (int)watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", phpdbg_get_property_key(new_watch->name_in_parent), Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); + new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%s%s", (int) watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY ? "[" : "->", phpdbg_get_property_key(new_watch->name_in_parent), Z_TYPE_P(watch->addr.zv) == IS_ARRAY ? "]" : ""); phpdbg_create_zval_watchpoint(*zv, new_watch); phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC); @@ -236,9 +236,9 @@ static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch, zend_b zend_hash_get_current_key_zval_ex(ht, &key, &position); str = NULL; if (Z_TYPE(key) == IS_STRING) { - str_len = asprintf(&str, "%.*s%s%s%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", phpdbg_get_property_key(Z_STRVAL(key)), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + str_len = asprintf(&str, "%.*s%s%s%s", (int) watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY ? "[" : "->", phpdbg_get_property_key(Z_STRVAL(key)), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY ? "]" : ""); } else { - str_len = asprintf(&str, "%.*s%s%li%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + str_len = asprintf(&str, "%.*s%s%li%s", (int) watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY ? "[" : "->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY ? "]" : ""); } if (zend_hash_find(&PHPDBG_G(watchpoints), str, str_len, (void **) &watchpoint) == SUCCESS) { @@ -339,14 +339,14 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par zend_hash_get_current_key_zval_ex(parent, key, &position); convert_to_string(key); watch->str = malloc(i + Z_STRLEN_P(key) + 2); - watch->str_len = sprintf(watch->str, "%.*s%s%s", (int)i, input, phpdbg_get_property_key(Z_STRVAL_P(key)), input[len - 1] == ']'?"]":""); + watch->str_len = sprintf(watch->str, "%.*s%s%s", (int) i, input, phpdbg_get_property_key(Z_STRVAL_P(key)), input[len - 1] == ']' ? "]" : ""); efree(key); watch->name_in_parent = zend_strndup(last_index, index_len); watch->name_in_parent_len = index_len; watch->parent_container = parent; phpdbg_create_zval_watchpoint(*zv, watch); - ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS ? SUCCESS : FAILURE; } else if (Z_TYPE_PP(zv) == IS_OBJECT) { phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback, silent TSRMLS_CC); } else if (Z_TYPE_PP(zv) == IS_ARRAY) { @@ -361,7 +361,7 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par last_index[index_len] = 0; if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) { if (!silent) { - phpdbg_error("%.*s is undefined", (int)i, input); + phpdbg_error("watch", "type=\"undefined\" variable=\"%.*s\"", "%.*s is undefined", (int) i, input); } return FAILURE; } @@ -382,7 +382,7 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par } else if (Z_TYPE_PP(zv) == IS_ARRAY) { parent = Z_ARRVAL_PP(zv); } else { - phpdbg_error("%.*s is nor an array nor an object", (int)i, input); + phpdbg_error("watch", "type=\"notiterable\" variable=\"%.*s\"", "%.*s is nor an array nor an object", (int) i, input); return FAILURE; } index_len = 0; @@ -391,7 +391,7 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par return ret; error: - phpdbg_error("Malformed input"); + phpdbg_error("watch", "type=\"invalidinput\"", "Malformed input"); return FAILURE; } @@ -412,9 +412,9 @@ PHPDBG_WATCH(delete) /* {{{ */ switch (param->type) { case STR_PARAM: if (phpdbg_delete_var_watchpoint(param->str, param->len TSRMLS_CC) == FAILURE) { - phpdbg_error("Nothing was deleted, no corresponding watchpoint found"); + phpdbg_error("watchdelete", "type=\"nowatch\"", "Nothing was deleted, no corresponding watchpoint found"); } else { - phpdbg_notice("Removed watchpoint %.*s", (int)param->len, param->str); + phpdbg_notice("watchdelete", "variable=\"%.*s\"", "Removed watchpoint %.*s", (int) param->len, param->str); } break; @@ -433,7 +433,7 @@ PHPDBG_WATCH(recursive) /* {{{ */ switch (param->type) { case STR_PARAM: if (phpdbg_watchpoint_parse_symtables(param->str, param->len, phpdbg_create_recursive_watchpoint TSRMLS_CC) != FAILURE) { - phpdbg_notice("Set recursive watchpoint on %.*s", (int)param->len, param->str); + phpdbg_notice("watchrecursive", "variable=\"%.*s\"", "Set recursive watchpoint on %.*s", (int)param->len, param->str); } break; @@ -452,7 +452,7 @@ PHPDBG_WATCH(array) /* {{{ */ switch (param->type) { case STR_PARAM: if (phpdbg_watchpoint_parse_symtables(param->str, param->len, phpdbg_create_array_watchpoint TSRMLS_CC) != FAILURE) { - phpdbg_notice("Set array watchpoint on %.*s", (int)param->len, param->str); + phpdbg_notice("watcharray", "variable=\"%.*s\"", "Set array watchpoint on %.*s", (int)param->len, param->str); } break; @@ -473,7 +473,7 @@ void phpdbg_watch_HashTable_dtor(zval **zv) { PHPDBG_G(watchpoint_hit) = 1; - phpdbg_notice("%.*s was removed, removing watchpoint%s", (int)watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE)?" recursively":""); + phpdbg_notice("watchdelete", "variable=\"%.*s\" recursive=\"%s\"", "%.*s was removed, removing watchpoint%s", (int)watch->str_len, watch->str, watch->flags & PHPDBG_WATCH_RECURSIVE ? " recursively" : ""); if (watch->flags & PHPDBG_WATCH_RECURSIVE) { phpdbg_delete_watchpoint_recursive(watch, 0 TSRMLS_CC); @@ -585,7 +585,7 @@ void phpdbg_setup_watchpoints(TSRMLS_D) { static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { /* fetch all changes between dump->page and dump->page + dump->size */ - phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong)dump->page, (zend_ulong)dump->page + dump->size); + phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong) dump->page, (zend_ulong) dump->page + dump->size); phpdbg_btree_result *result, *htresult; int elementDiff; void *curTest; @@ -597,7 +597,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); char reenable = 1; - if ((size_t)watch->addr.ptr < (size_t)dump->page || (size_t)watch->addr.ptr + watch->size > (size_t)dump->page + dump->size) { + if ((size_t)watch->addr.ptr < (size_t)dump->page || (size_t)watch->addr.ptr + watch->size > (size_t) dump->page + dump->size) { continue; } @@ -629,14 +629,17 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { /* Show to the user what changed and delete watchpoint upon removal */ if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) { - if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS || (watch->type == WATCH_ON_ZVAL && memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value))) || (watch->type == WATCH_ON_HASHTABLE + zend_bool do_break = PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS || (watch->type == WATCH_ON_ZVAL && memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value))) || (watch->type == WATCH_ON_HASHTABLE #if ZEND_DEBUG && !watch->addr.ht->inconsistent #endif - && zend_hash_num_elements((HashTable *)oldPtr) != zend_hash_num_elements(watch->addr.ht))) { + && zend_hash_num_elements((HashTable *)oldPtr) != zend_hash_num_elements(watch->addr.ht)); + + if (do_break) { PHPDBG_G(watchpoint_hit) = 1; - phpdbg_notice("Breaking on watchpoint %s", watch->str); + phpdbg_notice("watchhit", "variable=\"%s\"", "Breaking on watchpoint %.*s", (int) watch->str_len, watch->str); + phpdbg_xml(""); } switch (watch->type) { @@ -646,26 +649,28 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { int show_ref = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc || ((zval *)oldPtr)->is_ref__gc != watch->addr.zv->is_ref__gc; if (removed || show_value) { - phpdbg_write("Old value: "); if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) { - phpdbg_writeln("Value inaccessible, HashTable already destroyed"); + phpdbg_writeln("watchvalue", "type=\"old\" inaccessible=\"inaccessible\"", "Old value inaccessible, array or object (HashTable) already destroyed"); } else { - zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); - phpdbg_writeln(""); + phpdbg_out("Old value: "); + phpdbg_xml(""); + zend_print_flat_zval_r((zval *) oldPtr TSRMLS_CC); + phpdbg_xml(""); + phpdbg_out("\n"); } } if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && (removed || show_ref)) { - phpdbg_writeln("Old refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); + phpdbg_write("watchrefcount", "type=\"old\" refcount=\"%d\" isref=\"%d\"", "Old refcount: %d; Old is_ref: %d", ((zval *) oldPtr)->refcount__gc, ((zval *) oldPtr)->is_ref__gc); } /* check if zval was removed */ if (removed) { - phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); + phpdbg_notice("watchdelete", "variable=\"%.*s\"", "Watchpoint %.*s was unset, removing watchpoint", (int) watch->str_len, watch->str); zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); reenable = 0; - if (Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) { + if (Z_TYPE_P((zval *) oldPtr) == IS_ARRAY || Z_TYPE_P((zval *) oldPtr) == IS_OBJECT) { goto remove_ht_watch; } @@ -673,22 +678,24 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { } if (show_value) { - phpdbg_write("New value: "); + phpdbg_out("New value: "); + phpdbg_xml(""); zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); - phpdbg_writeln(""); + phpdbg_xml(""); + phpdbg_out("\n"); } if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && show_ref) { - phpdbg_writeln("New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); + phpdbg_writeln("watchrefcount", "type=\"new\" refcount=\"%d\" isref=\"%d\"", "New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); } - if ((Z_TYPE_P(watch->addr.zv) == IS_ARRAY && Z_ARRVAL_P(watch->addr.zv) != Z_ARRVAL_P((zval *)oldPtr)) || (Z_TYPE_P(watch->addr.zv) != IS_OBJECT && Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) { + if ((Z_TYPE_P(watch->addr.zv) == IS_ARRAY && Z_ARRVAL_P(watch->addr.zv) != Z_ARRVAL_P((zval *) oldPtr)) || (Z_TYPE_P(watch->addr.zv) != IS_OBJECT && Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *) oldPtr))) { /* add new watchpoints if necessary */ if (watch->flags & PHPDBG_WATCH_RECURSIVE) { phpdbg_create_recursive_watchpoint(watch TSRMLS_CC); } } - if ((Z_TYPE_P((zval *)oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *)oldPtr)) && (Z_TYPE_P((zval *)oldPtr) != IS_OBJECT || Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) { + if ((Z_TYPE_P((zval *) oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *) oldPtr)) && (Z_TYPE_P((zval *)oldPtr) != IS_OBJECT || Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *) oldPtr))) { break; } @@ -704,7 +711,7 @@ remove_ht_watch: #if ZEND_DEBUG if (watch->addr.ht->inconsistent) { - phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); + phpdbg_notice("watchdelete", "variable=\"%.*s\"", "Watchpoint %.*s was unset, removing watchpoint", (int) watch->str_len, watch->str); zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); reenable = 0; @@ -713,12 +720,12 @@ remove_ht_watch: } #endif - elementDiff = zend_hash_num_elements((HashTable *)oldPtr) - zend_hash_num_elements(watch->addr.ht); + elementDiff = zend_hash_num_elements((HashTable *) oldPtr) - zend_hash_num_elements(watch->addr.ht); if (elementDiff) { if (elementDiff > 0) { - phpdbg_writeln("%d elements were removed from the array", elementDiff); + phpdbg_writeln("watchsize", "removed=\"%d\"", "%d elements were removed from the array", elementDiff); } else { - phpdbg_writeln("%d elements were added to the array", -elementDiff); + phpdbg_writeln("watchsize", "added=\"%d\"", "%d elements were added to the array", -elementDiff); /* add new watchpoints if necessary */ if (watch->flags & PHPDBG_WATCH_RECURSIVE) { @@ -726,11 +733,15 @@ remove_ht_watch: } } } - if (((HashTable *)oldPtr)->pInternalPointer != watch->addr.ht->pInternalPointer) { - phpdbg_writeln("Internal pointer of array was changed"); + if (((HashTable *) oldPtr)->pInternalPointer != watch->addr.ht->pInternalPointer) { + phpdbg_writeln("watcharrayptr", "", "Internal pointer of array was changed"); } break; } + + if (do_break) { + phpdbg_xml(""); + } } dump->reenable_writing = dump->reenable_writing | reenable; @@ -746,15 +757,15 @@ int phpdbg_print_changed_zvals(TSRMLS_D) { return FAILURE; } - dump = (phpdbg_watch_memdump **)zend_llist_get_last_ex(&PHPDBG_G(watchlist_mem), &pos); + dump = (phpdbg_watch_memdump **) zend_llist_get_last_ex(&PHPDBG_G(watchlist_mem), &pos); do { phpdbg_print_changed_zval(*dump TSRMLS_CC); - } while ((dump = (phpdbg_watch_memdump **)zend_llist_get_prev_ex(&PHPDBG_G(watchlist_mem), &pos))); + } while ((dump = (phpdbg_watch_memdump **) zend_llist_get_prev_ex(&PHPDBG_G(watchlist_mem), &pos))); zend_llist_clean(&PHPDBG_G(watchlist_mem)); - ret = PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; + ret = PHPDBG_G(watchpoint_hit) ? SUCCESS : FAILURE; PHPDBG_G(watchpoint_hit) = 0; return ret; @@ -764,23 +775,27 @@ void phpdbg_list_watchpoints(TSRMLS_D) { HashPosition position; phpdbg_watchpoint_t **watch; + phpdbg_xml(""); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(watchpoints), &position); zend_hash_get_current_data_ex(&PHPDBG_G(watchpoints), (void**) &watch, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(watchpoints), &position)) { - phpdbg_writeln("%.*s", (int)(*watch)->str_len, (*watch)->str); + phpdbg_writeln("watchvariable", "variable=\"%.*s\" on=\"%s\" type=\"%s\"", "%.*s (%s, %s)", (int) (*watch)->str_len, (*watch)->str, (*watch)->type == WATCH_ON_HASHTABLE ? "array" : "variable", (*watch)->flags == PHPDBG_WATCH_RECURSIVE ? "recursive" : "simple"); } + + phpdbg_xml(""); } void phpdbg_watch_efree(void *ptr) { phpdbg_btree_result *result; TSRMLS_FETCH(); - result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)ptr); + result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong) ptr); if (result) { phpdbg_watchpoint_t *watch = result->ptr; - if ((size_t)watch->addr.ptr + watch->size > (size_t)ptr) { + if ((size_t)watch->addr.ptr + watch->size > (size_t) ptr) { zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); } } From ca635e488484838db2a4ab11e407a58271fbe917 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 22 Sep 2014 00:52:22 +0200 Subject: [PATCH 006/125] A few general segfault fixes --- phpdbg.c | 32 +++++++------- phpdbg_cmd.c | 3 ++ phpdbg_prompt.c | 7 +++- phpdbg_utils.c | 108 ++++++++++++++++++++++++++---------------------- 4 files changed, 84 insertions(+), 66 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index b27e774bdd0..ab2f8256ee5 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -539,11 +539,11 @@ static size_t phpdbg_stdiop_write(php_stream *stream, const char *buf, size_t co } if (stat[0].st_dev == stat[1].st_dev && stat[0].st_ino == stat[1].st_ino) { - phpdbg_script(P_STDOUT, "%.*s", buf, count); + phpdbg_script(P_STDOUT, "%.*s", (int) count, buf); return count; } if (stat[2].st_dev == stat[1].st_dev && stat[2].st_ino == stat[1].st_ino) { - phpdbg_script(P_STDERR, "%.*s", buf, count); + phpdbg_script(P_STDERR, "%.*s", (int) count, buf); return count; } break; @@ -1244,10 +1244,15 @@ phpdbg_main: sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); #endif + php_output_activate(TSRMLS_C); + php_output_deactivate(TSRMLS_C); + + php_output_activate(TSRMLS_C); + if (php_request_startup(TSRMLS_C) == SUCCESS) { int i; - - SG(request_info).argc = argc - php_optind + 1; + + SG(request_info).argc = argc - php_optind + 1; SG(request_info).argv = emalloc(SG(request_info).argc * sizeof(char *)); for (i = SG(request_info).argc; --i;) { SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]); @@ -1257,10 +1262,6 @@ phpdbg_main: php_hash_environment(TSRMLS_C); } - /* make sure to turn off buffer for ev command */ - php_output_activate(TSRMLS_C); - php_output_deactivate(TSRMLS_C); - /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ #ifndef _WIN32 @@ -1425,7 +1426,7 @@ phpdbg_out: } phpdbg_out: #endif - + { int i; /* free argv */ @@ -1438,8 +1439,7 @@ phpdbg_out: #ifndef ZTS /* force cleanup of auto and core globals */ zend_hash_clean(CG(auto_globals)); - memset( - &core_globals, 0, sizeof(php_core_globals)); + memset( &core_globals, 0, sizeof(php_core_globals)); #endif if (ini_entries) { free(ini_entries); @@ -1448,15 +1448,17 @@ phpdbg_out: if (ini_override) { free(ini_override); } - + /* this must be forced */ CG(unclean_shutdown) = 0; - + /* this is just helpful */ PG(report_memleaks) = 0; php_request_shutdown((void*)0); + php_output_deactivate(TSRMLS_C); + zend_try { php_module_shutdown(TSRMLS_C); } zend_end_try(); @@ -1468,7 +1470,7 @@ phpdbg_out: if (cleaning || remote) { goto phpdbg_main; } - + #ifdef ZTS /* bugggy */ /* tsrm_shutdown(); */ @@ -1483,7 +1485,7 @@ phpdbg_out: if (sapi_name) { free(sapi_name); } - + #ifdef _WIN32 free(bp_tmp_file); #else diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 587007e9008..5c6ac072ea9 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -763,6 +763,9 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack TSRMLS_DC) { if (handler) { if (phpdbg_stack_verify(handler, &top TSRMLS_CC) == SUCCESS) { + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); + return handler->handler(top TSRMLS_CC); } } diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 0081fd2312a..b877f3511ce 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -161,6 +161,9 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * fci.param_count = 0; } + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); + phpdbg_debug("created %d params from arguments", fci.param_count); zend_call_function(&fci, NULL TSRMLS_CC); @@ -603,11 +606,11 @@ PHPDBG_COMMAND(run) /* {{{ */ } zend_try { - php_output_activate(TSRMLS_C); +// php_output_activate(TSRMLS_C); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; zend_execute(EG(active_op_array) TSRMLS_CC); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; - php_output_deactivate(TSRMLS_C); +// php_output_deactivate(TSRMLS_C); } zend_catch { EG(active_op_array) = orig_op_array; EG(opline_ptr) = orig_opline; diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 25c2199649f..b68a0b6d2dc 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -734,7 +734,7 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca } *s_ptr++ = ';'; } else { - *s_ptr++ = s[i]; + *s_ptr++ = old_s[i]; } } while (i++ < old_slen); } @@ -1082,7 +1082,8 @@ static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char if (msg) { msgoutlen = asprintf(&msgout, "%.*s\n", msglen, msg); } else { - msgoutlen = asprintf(&msgout, "\n"); + msgoutlen = 1; + msgout = strdup("\n"); } break; @@ -1091,7 +1092,8 @@ static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char if (msg) { msgoutlen = asprintf(&msgout, "%.*s\n", msglen, msg); } else { - msgoutlen = asprintf(&msgout, ""); + msgoutlen = 0; + msgout = strdup(""); } break; @@ -1103,7 +1105,7 @@ static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char fprintf(fp, "", type == P_STDERR ? "stderr" : "stdout"); PHPDBG_G(in_script_xml) = type; } - buf = php_escape_html_entities((char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); + buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); fprintf(fp, "%.*s", buflen, buf); efree(buf); } else { @@ -1130,7 +1132,7 @@ static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { if (msgout) { - buf = php_escape_html_entities(msgout, msgoutlen, (size_t *) &buflen, 0, ENT_COMPAT, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); + buf = php_escape_html_entities((unsigned char *) msgout, msgoutlen, (size_t *) &buflen, 0, ENT_COMPAT, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); xmloutlen = fprintf(fp, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf); efree(buf); @@ -1148,6 +1150,51 @@ static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char return msgout ? msgoutlen : xmloutlen; } /* }}} */ +PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, FILE *fp, const char *tag, const char *xmlfmt, const char *strfmt, va_list args) { + char *msg = NULL, *xml = NULL; + int msglen = 0, xmllen = 0; + int len; + va_list argcpy; + + if (strfmt != NULL && strlen(strfmt) > 0L) { + va_copy(argcpy, args); + msglen = phpdbg_xml_vasprintf(&msg, strfmt, 0, argcpy TSRMLS_CC); + va_end(argcpy); + } + + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + if (xmlfmt != NULL && strlen(xmlfmt) > 0L) { + va_copy(argcpy, args); + xmllen = phpdbg_xml_vasprintf(&xml, xmlfmt, 1, argcpy TSRMLS_CC); + va_end(argcpy); + } + } + + if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) { + PHPDBG_G(err_buf).type = type; + PHPDBG_G(err_buf).fp = fp; + PHPDBG_G(err_buf).tag = strdup(tag); + PHPDBG_G(err_buf).msg = msg; + PHPDBG_G(err_buf).msglen = msglen; + PHPDBG_G(err_buf).xml = xml; + PHPDBG_G(err_buf).xmllen = xmllen; + + return msglen; + } + + len = phpdbg_process_print(fp, type, tag, msg, msglen, xml, xmllen TSRMLS_CC); + + if (msg) { + free(msg); + } + + if (xml) { + free(xml); + } + + return len; +} + PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D) { if (PHPDBG_G(err_buf).type == 0) { return; @@ -1155,9 +1202,9 @@ PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D) { PHPDBG_G(err_buf).type = 0; - efree(PHPDBG_G(err_buf).tag); - efree(PHPDBG_G(err_buf).msg); - efree(PHPDBG_G(err_buf).xml); + free(PHPDBG_G(err_buf).tag); + free(PHPDBG_G(err_buf).msg); + free(PHPDBG_G(err_buf).xml); } PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC) { @@ -1185,52 +1232,15 @@ PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const return len; } -PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, FILE *fp, const char *tag, const char *xmlfmt, const char *strfmt, va_list args) { - char *msg = NULL, *xml = NULL; - int msglen = 0, xmllen = 0; - int len; - - if (strfmt != NULL && strlen(strfmt) > 0L) { - msglen = phpdbg_xml_vasprintf(&msg, strfmt, 0, args TSRMLS_CC); - } - - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - if (xmlfmt != NULL && strlen(xmlfmt) > 0L) { - xmllen = phpdbg_xml_vasprintf(&xml, xmlfmt, 1, args TSRMLS_CC); - } - } - - if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) { - PHPDBG_G(err_buf).type = type; - PHPDBG_G(err_buf).fp = fp; - PHPDBG_G(err_buf).tag = estrdup(tag); - PHPDBG_G(err_buf).msg = msg; - PHPDBG_G(err_buf).msglen = msglen; - PHPDBG_G(err_buf).xml = xml; - PHPDBG_G(err_buf).xmllen = xmllen; - - return msglen; - } - - len = phpdbg_process_print(fp, type, tag, msg, msglen, xml, xmllen TSRMLS_CC); - - if (msg) { - free(msg); - } - - if (xml) { - free(xml); - } - - return len; -} - PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *tag, const char *xmlfmt, const char *strfmt, ...) { va_list args; + int len; va_start(args, strfmt); - phpdbg_vprint(type TSRMLS_CC, fp, tag, xmlfmt, strfmt, args); + len = phpdbg_vprint(type TSRMLS_CC, fp, tag, xmlfmt, strfmt, args); va_end(args); + + return len; } PHPDBG_API int phpdbg_xml_internal(FILE *fp TSRMLS_DC, const char *fmt, ...) { From 7f9e0360776f21f2e9c854aaebe9d4b559e15a4a Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 22 Sep 2014 23:28:07 +0200 Subject: [PATCH 007/125] Fix breakpoints and listing --- phpdbg_bp.c | 32 ++++++++++++++++---------------- phpdbg_cmd.c | 7 ++++++- phpdbg_list.c | 6 +++--- phpdbg_utils.c | 3 ++- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index dbe1da63ddc..eddcbcb3589 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -1357,8 +1357,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ uint32_t class_len = 0; zend_ulong class_idx = 0L; - phpdbg_out(SEPARATE); - phpdbg_out("Method Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Method Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**) &class_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) { @@ -1383,8 +1383,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *points; - phpdbg_out(SEPARATE); - phpdbg_out("File Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("File Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**) &points, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) { @@ -1405,8 +1405,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakline_t *brake; - phpdbg_out(SEPARATE); - phpdbg_out("Opline Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Opline Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) { @@ -1436,8 +1436,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ uint32_t class_len = 0, method_len = 0; zend_ulong class_idx = 0L, method_idx = 0L; - phpdbg_out(SEPARATE); - phpdbg_out("Method opline Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Method opline Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) { @@ -1475,8 +1475,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ uint32_t function_len = 0; zend_ulong function_idx = 0L; - phpdbg_out(SEPARATE); - phpdbg_out("Function opline Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Function opline Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) { @@ -1505,8 +1505,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ uint32_t file_len = 0; zend_ulong file_idx = 0L; - phpdbg_out(SEPARATE); - phpdbg_out("File opline Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("File opline Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) { @@ -1531,8 +1531,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakcond_t *brake; - phpdbg_out(SEPARATE); - phpdbg_out("Conditional Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Conditional Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { @@ -1607,8 +1607,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakop_t *brake; - phpdbg_out(SEPARATE); - phpdbg_out("Opcode Breakpoints:"); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Opcode Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) { diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 5c6ac072ea9..2e91304d7ea 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -750,12 +750,18 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack TSRMLS_DC) { switch (top->type) { case EVAL_PARAM: + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); case RUN_PARAM: + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); return PHPDBG_COMMAND_HANDLER(run)(top TSRMLS_CC); case SHELL_PARAM: + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); return PHPDBG_COMMAND_HANDLER(sh)(top TSRMLS_CC); case STR_PARAM: { @@ -765,7 +771,6 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack TSRMLS_DC) { if (phpdbg_stack_verify(handler, &top TSRMLS_CC) == SUCCESS) { phpdbg_activate_err_buf(0 TSRMLS_CC); phpdbg_free_err_buf(TSRMLS_C); - return handler->handler(top TSRMLS_CC); } } diff --git a/phpdbg_list.c b/phpdbg_list.c index 64e0d8465b9..748461908cf 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -159,12 +159,12 @@ void phpdbg_list_file(const char *filename, long count, long offset, int highlig if (offset <= line) { if (!highlight) { - phpdbg_write("line", "num=\"%d\" code=\"%s\"", "%05ld: %s", line, buffer); + phpdbg_write("line", "num=\"%d\" code=\"%s\"", " %05ld: %s", line, buffer); } else { if (highlight != line) { - phpdbg_write("line", "num=\"%d\" code=\"%s\"", "%05ld: %s", " %05ld: %s", line, buffer); + phpdbg_write("line", "num=\"%ld\" code=\"%s\"", " %05ld: %s", line, buffer); } else { - phpdbg_write("line", "num=\"%d\" code=\"%s\" current=\"current\"", "%05ld: %s", ">%05ld: %s", line, buffer); + phpdbg_write("line", "num=\"%ld\" code=\"%s\" current=\"current\"", ">%05ld: %s", line, buffer); } } diff --git a/phpdbg_utils.c b/phpdbg_utils.c index b68a0b6d2dc..6ff905c7369 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1090,7 +1090,8 @@ static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char case P_WRITE: severity = "normal"; if (msg) { - msgoutlen = asprintf(&msgout, "%.*s\n", msglen, msg); + msgout = strndup(msg, msglen); + msgoutlen = msglen; } else { msgoutlen = 0; msgout = strdup(""); From e2329bc70495adfaf8070fc6194aaefa2c5999c1 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 23 Sep 2014 13:04:53 +0200 Subject: [PATCH 008/125] Add notification at script end --- phpdbg_prompt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index d91ef3f3f5c..ed60e99c468 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -645,6 +645,7 @@ PHPDBG_COMMAND(run) /* {{{ */ zend_execute(EG(active_op_array) TSRMLS_CC); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; php_output_deactivate(TSRMLS_C); + phpdbg_notice("Script ended normally"); } zend_catch { EG(active_op_array) = orig_op_array; EG(opline_ptr) = orig_opline; From 92fe2d0a85ab831b01e2de9802da1753c144b808 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 23 Sep 2014 16:48:37 +0200 Subject: [PATCH 009/125] Add info globals command --- phpdbg_help.c | 1 + phpdbg_info.c | 57 +++++++++++++++++++++++++++++++++++++-------------- phpdbg_info.h | 1 + 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 3244b653ef9..57d70c3581b 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -646,6 +646,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **funcs** **f** show loaded classes" CR " **error** **e** show last error" CR " **vars** **v** show active variables" CR +" **globals** **g** show superglobal variables" CR " **literal** **l** show active literal constants" CR " **memory** **m** show memory manager stats" }, diff --git a/phpdbg_info.c b/phpdbg_info.c index 97f88bfa1ec..a783bf44fcd 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -37,6 +37,7 @@ const phpdbg_command_t phpdbg_info_commands[] = { PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0), PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0), PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0), + PHPDBG_INFO_COMMAND_D(globals, "show superglobals", 'g', info_globals, NULL, 0), PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0), PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0), PHPDBG_END_COMMAND @@ -86,9 +87,16 @@ PHPDBG_INFO(error) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_INFO(vars) /* {{{ */ -{ - HashTable vars; +static int phpdbg_arm_auto_global(zend_auto_global *auto_global TSRMLS_DC) { + if (auto_global->armed) { + auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC); + } + + return 0; +} + +static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { + HashTable vars, *symtable; HashPosition pos; char *var; zval **data; @@ -107,22 +115,31 @@ PHPDBG_INFO(vars) /* {{{ */ } } - zend_hash_init(&vars, 8, NULL, NULL, 0); - zend_hash_internal_pointer_reset_ex(EG(active_symbol_table), &pos); - while (zend_hash_get_current_key_ex(EG(active_symbol_table), &var, - NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { - zend_hash_get_current_data_ex(EG(active_symbol_table), (void **)&data, &pos); - if (*var != '_') { - zend_hash_update( - &vars, var, strlen(var)+1, (void**)data, sizeof(zval*), NULL); - } - zend_hash_move_forward_ex(EG(active_symbol_table), &pos); + if (show_globals) { + zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_arm_auto_global TSRMLS_CC); + symtable = &EG(symbol_table); + } else { + symtable = EG(active_symbol_table); } - { + zend_hash_init(&vars, 8, NULL, NULL, 0); + + zend_hash_internal_pointer_reset_ex(symtable, &pos); + while (zend_hash_get_current_key_ex(symtable, &var, + NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { + zend_hash_get_current_data_ex(symtable, (void **)&data, &pos); + if (zend_is_auto_global(var, strlen(var) TSRMLS_CC) ^ !show_globals) { + zend_hash_update(&vars, var, strlen(var)+1, (void**)data, sizeof(zval*), NULL); + } + zend_hash_move_forward_ex(symtable, &pos); + } + + if (show_globals) { + phpdbg_notice("Superglobal variables (%d)", zend_hash_num_elements(&vars)); + } else { zend_op_array *ops = EG(active_op_array); - + if (ops->function_name) { if (ops->scope) { phpdbg_notice( @@ -204,6 +221,16 @@ PHPDBG_INFO(vars) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_INFO(vars) /* {{{ */ +{ + return phpdbg_print_symbols(0 TSRMLS_CC); +} + +PHPDBG_INFO(globals) /* {{{ */ +{ + return phpdbg_print_symbols(1 TSRMLS_CC); +} + PHPDBG_INFO(literal) /* {{{ */ { if ((EG(in_execution) && EG(active_op_array)) || PHPDBG_G(ops)) { diff --git a/phpdbg_info.h b/phpdbg_info.h index c36e6bebd65..6930cdd8244 100644 --- a/phpdbg_info.h +++ b/phpdbg_info.h @@ -31,6 +31,7 @@ PHPDBG_INFO(classes); PHPDBG_INFO(funcs); PHPDBG_INFO(error); PHPDBG_INFO(vars); +PHPDBG_INFO(globals); PHPDBG_INFO(literal); PHPDBG_INFO(memory); From 79ea51f360b1ec80ef12332a29aa365a856fcfb0 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 23 Sep 2014 17:04:39 +0200 Subject: [PATCH 010/125] Use consistently "num" for an nth opline number --- phpdbg_bp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index eddcbcb3589..87952cba270 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -1198,7 +1198,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_METHOD_OPLINE: { - phpdbg_notice("breakpoint", "id=\"%d\" method=\"%s::%s\" opline=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" method=\"%s::%s\" num=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->func_name, @@ -1209,7 +1209,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_FUNCTION_OPLINE: { - phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%lu\" function=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" num=\"%lu\" function=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num, @@ -1219,7 +1219,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_FILE_OPLINE: { - phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in #%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" num=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in #%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, ((phpdbg_breakopline_t*)brake)->opline_num, zend_get_executed_filename(TSRMLS_C), From 3b81337f80419b1736224461edc2266852a37fcc Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 23 Sep 2014 18:29:36 +0200 Subject: [PATCH 011/125] Fix accidental short-circuiting when comparing fds (& warnings) --- phpdbg.c | 2 +- phpdbg_set.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index ab2f8256ee5..0c4e2f11bfe 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -534,7 +534,7 @@ static size_t phpdbg_stdiop_write(php_stream *stream, const char *buf, size_t co while (data->fd >= 0) { struct stat stat[3]; memset(stat, 0, sizeof(stat)); - if ((fstat(fileno(stderr), &stat[2]) < 0 && fstat(fileno(stdout), &stat[0]) < 0) || fstat(data->fd, &stat[1]) < 0) { + if (((fstat(fileno(stderr), &stat[2]) < 0) & (fstat(fileno(stdout), &stat[0]) < 0)) | (fstat(data->fd, &stat[1]) < 0)) { break; } diff --git a/phpdbg_set.c b/phpdbg_set.c index e5d8d6d1dba..da850719416 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -69,9 +69,9 @@ PHPDBG_SET(break) /* {{{ */ } else { phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num TSRMLS_CC); if (brake) { - phpdbg_writeln("setbreak", "id=\"%d\" active=\"%s\"", "Breakpoint #%d %s", param->num, brake->disabled ? "off" : "on"); + phpdbg_writeln("setbreak", "id=\"%ld\" active=\"%s\"", "Breakpoint #%ld %s", param->num, brake->disabled ? "off" : "on"); } else { - phpdbg_error("setbreak", "type=\"nobreak\" id=\"%d\"", "Failed to find breakpoint #%ld", param->num); + phpdbg_error("setbreak", "type=\"nobreak\" id=\"%ld\"", "Failed to find breakpoint #%ld", param->num); } } } break; From 9bd171888bc8ae6ec783f2a250ae83be4e1fe446 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 00:21:27 +0200 Subject: [PATCH 012/125] Use more consistent naming in info command for xml protocol --- phpdbg_info.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/phpdbg_info.c b/phpdbg_info.c index d9ef3f9e6df..9cc59c066d6 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -136,21 +136,21 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { } if (show_globals) { - phpdbg_notice("variableinfo", "count=\"%d\"", "Superglobal variables (%d)", zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "num=\"%d\"", "Superglobal variables (%d)", zend_hash_num_elements(&vars)); } else { zend_op_array *ops = EG(active_op_array); if (ops->function_name) { if (ops->scope) { - phpdbg_notice("variableinfo", "method=\"%s::%s\" count=\"%d\"", "Variables in %s::%s() (%d)", ops->scope->name, ops->function_name, zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "method=\"%s::%s\" num=\"%d\"", "Variables in %s::%s() (%d)", ops->scope->name, ops->function_name, zend_hash_num_elements(&vars)); } else { - phpdbg_notice("variableinfo", "function=\"%s\" count=\"%d\"", "Variables in %s() (%d)", ops->function_name, zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "function=\"%s\" num=\"%d\"", "Variables in %s() (%d)", ops->function_name, zend_hash_num_elements(&vars)); } } else { if (ops->filename) { - phpdbg_notice("variableinfo", "file=\"%s\" count=\"%d\"", "Variables in %s (%d)", ops->filename, zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "file=\"%s\" num=\"%d\"", "Variables in %s (%d)", ops->filename, zend_hash_num_elements(&vars)); } else { - phpdbg_notice("variableinfo", "opline=\"%p\" count=\"%d\"", "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars)); + phpdbg_notice("variableinfo", "opline=\"%p\" num=\"%d\"", "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars)); } } } @@ -205,15 +205,15 @@ PHPDBG_INFO(literal) /* {{{ */ if (ops->function_name) { if (ops->scope) { - phpdbg_notice("literalinfo", "method=\"%s::%s\" count=\"%d\"", "Literal Constants in %s::%s() (%d)", ops->scope->name, ops->function_name, count); + phpdbg_notice("literalinfo", "method=\"%s::%s\" num=\"%d\"", "Literal Constants in %s::%s() (%d)", ops->scope->name, ops->function_name, count); } else { - phpdbg_notice("literalinfo", "function=\"%s\" count=\"%d\"", "Literal Constants in %s() (%d)", ops->function_name, count); + phpdbg_notice("literalinfo", "function=\"%s\" num=\"%d\"", "Literal Constants in %s() (%d)", ops->function_name, count); } } else { if (ops->filename) { - phpdbg_notice("literalinfo", "file=\"%s\" count=\"%d\"", "Literal Constants in %s (%d)", ops->filename, count); + phpdbg_notice("literalinfo", "file=\"%s\" num=\"%d\"", "Literal Constants in %s (%d)", ops->filename, count); } else { - phpdbg_notice("literalinfo", "opline=\"%p\" count=\"%d\"", "Literal Constants @ %p (%d)", ops, count); + phpdbg_notice("literalinfo", "opline=\"%p\" num=\"%d\"", "Literal Constants @ %p (%d)", ops, count); } } @@ -279,7 +279,7 @@ PHPDBG_INFO(classes) /* {{{ */ } } - phpdbg_notice("classinfo", "count=\"%d\"", "User Classes (%d)", zend_hash_num_elements(&classes)); + phpdbg_notice("classinfo", "num=\"%d\"", "User Classes (%d)", zend_hash_num_elements(&classes)); for (zend_hash_internal_pointer_reset_ex(&classes, &position); zend_hash_get_current_data_ex(&classes, (void**)&ce, &position) == SUCCESS; @@ -331,17 +331,22 @@ PHPDBG_INFO(funcs) /* {{{ */ } } - phpdbg_notice("functioninfo", "count=\"%d\"", "User Functions (%d)", zend_hash_num_elements(&functions)); + phpdbg_notice("functioninfo", "num=\"%d\"", "User Functions (%d)", zend_hash_num_elements(&functions)); for (zend_hash_internal_pointer_reset_ex(&functions, &position); zend_hash_get_current_data_ex(&functions, (void**)&pzf, &position) == SUCCESS; zend_hash_move_forward_ex(&functions, &position)) { zend_op_array *op_array = &((*pzf)->op_array); - phpdbg_writeln("function", "name=\"%s\" file=\"%s\" line=\"%d\"", "|-------- %s in %s on line %d", - op_array->function_name ? op_array->function_name : "{main}", - op_array->filename ? op_array->filename : "(no source code)", - op_array->line_start); + phpdbg_write("function", "name=\"%s\"", "|-------- %s", op_array->function_name ? op_array->function_name : "{main}"); + + if (op_array->filename) { + phpdbg_writeln("functionsource", "file=\"%s\" line=\"%d\"", " in %s on line %d", + op_array->filename, + op_array->line_start); + } else { + phpdbg_writeln("functionsource", "", " (no source code)"); + } } zend_hash_destroy(&functions); From abafb7b4f90006442c10a341f0d9bef44ba3b08a Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 00:22:58 +0200 Subject: [PATCH 013/125] Better naming in list command and inform about filename --- phpdbg_list.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpdbg_list.c b/phpdbg_list.c index 748461908cf..17a125fcf78 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -150,7 +150,7 @@ void phpdbg_list_file(const char *filename, long count, long offset, int highlig offset = 0; } - phpdbg_xml(""); + phpdbg_xml("", filename); while (php_stream_gets(stream, buffer, sizeof(buffer)) != NULL) { long linelen = strlen(buffer); @@ -159,12 +159,12 @@ void phpdbg_list_file(const char *filename, long count, long offset, int highlig if (offset <= line) { if (!highlight) { - phpdbg_write("line", "num=\"%d\" code=\"%s\"", " %05ld: %s", line, buffer); + phpdbg_write("line", "line=\"%d\" code=\"%s\"", " %05ld: %s", line, buffer); } else { if (highlight != line) { - phpdbg_write("line", "num=\"%ld\" code=\"%s\"", " %05ld: %s", line, buffer); + phpdbg_write("line", "line=\"%ld\" code=\"%s\"", " %05ld: %s", line, buffer); } else { - phpdbg_write("line", "num=\"%ld\" code=\"%s\" current=\"current\"", ">%05ld: %s", line, buffer); + phpdbg_write("line", "line=\"%ld\" code=\"%s\" current=\"current\"", ">%05ld: %s", line, buffer); } } From 2bd1a74690b03694d32c3cff7b7e4cb2281c50c3 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 00:55:17 +0200 Subject: [PATCH 014/125] Always add a newline before a warning or a notice --- phpdbg.c | 1 + phpdbg.h | 3 ++- phpdbg_cmd.c | 6 +++++- phpdbg_utils.c | 10 ++++++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 1e1642fb761..e30d35d71fc 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -63,6 +63,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->exec = NULL; pg->exec_len = 0; pg->buffer = NULL; + pg->last_was_newline = 1; pg->ops = NULL; pg->vmret = 0; pg->bp_count = 0; diff --git a/phpdbg.h b/phpdbg.h index 2fa2d5093a8..f9ca0f2a710 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -64,7 +64,7 @@ # include "TSRM.h" #endif -#ifdef HAVE_LIBREADLINE +#ifdef LIBREADLINE # include # include #endif @@ -208,6 +208,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) char *prompt[2]; /* prompt */ const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */ char *buffer; /* buffer */ + zend_bool last_was_newline; /* check if we don't need to output a newline upon next phpdbg_error or phpdbg_notice */ zend_ulong flags; /* phpdbg flags */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index a45513bee6b..8ca56aa25cc 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -816,6 +816,7 @@ disconnect: if (!phpdbg_write("%s", phpdbg_get_prompt(TSRMLS_C))) { goto disconnect; } + PHPDBG_G(last_was_newline) = 1; } /* note: EOF is ignored */ @@ -836,7 +837,10 @@ readline: if (fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) { cmd = buf; } else goto disconnect; - } else cmd = readline(phpdbg_get_prompt(TSRMLS_C)); + } else { + cmd = readline(phpdbg_get_prompt(TSRMLS_C)); + PHPDBG_G(last_was_newline) = 1; + } if (!cmd) { goto readline; diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 3ce2fade17d..22a7b562825 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -240,6 +240,10 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, .. switch (type) { case P_ERROR: + if (!PHPDBG_G(last_was_newline)) { + fprintf(fp, "\n"); + PHPDBG_G(last_was_newline) = 1; + } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { rc = fprintf(fp, "\033[%sm[%s]\033[0m\n", @@ -250,6 +254,10 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, .. break; case P_NOTICE: + if (!PHPDBG_G(last_was_newline)) { + fprintf(fp, "\n"); + PHPDBG_G(last_was_newline) = 1; + } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { rc = fprintf(fp, "\033[%sm[%s]\033[0m\n", @@ -265,11 +273,13 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, .. } else { rc = fprintf(fp, "\n"); } + PHPDBG_G(last_was_newline) = 1; } break; case P_WRITE: if (buffer) { rc = fprintf(fp, "%s", buffer); + PHPDBG_G(last_was_newline) = buffer[strlen(buffer) - 1] == '\n'; } break; From a4c4c3593b04ff21929dd75a50e00e1a4f56e896 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 00:59:17 +0200 Subject: [PATCH 015/125] Fix test after adding script ended notice --- tests/commands/0106_compile.test | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/commands/0106_compile.test b/tests/commands/0106_compile.test index 7193600ea3d..ce4e16981b3 100644 --- a/tests/commands/0106_compile.test +++ b/tests/commands/0106_compile.test @@ -7,6 +7,7 @@ #[Attempting compilation of %s] #[Success] #Hello World +#[Script ended normally] ################################################# <: define('OUT', From 5ba53cac060d26717b22e5e76debce1fca3fc776 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 01:29:08 +0200 Subject: [PATCH 016/125] Fix tests --- phpdbg_info.c | 2 -- phpdbg_prompt.c | 4 ++-- tests/commands/0002_set.test | 2 +- tests/commands/0102_print.test | 5 ++--- tests/commands/0104_clean.test | 10 +++++----- tests/commands/0105_clear.test | 2 +- tests/commands/0106_compile.test | 3 +-- 7 files changed, 12 insertions(+), 16 deletions(-) diff --git a/phpdbg_info.c b/phpdbg_info.c index 9cc59c066d6..5204bc13572 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -286,7 +286,6 @@ PHPDBG_INFO(classes) /* {{{ */ zend_hash_move_forward_ex(&classes, &position)) { phpdbg_print_class_name(ce TSRMLS_CC); - phpdbg_out("\n"); if ((*ce)->parent) { phpdbg_xml(""); @@ -305,7 +304,6 @@ PHPDBG_INFO(classes) /* {{{ */ } else { phpdbg_writeln("classsource", "", "|---- no source code"); } - phpdbg_out("\n"); } zend_hash_destroy(&classes); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 46033b0ed3b..b03d23bc57a 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -872,7 +872,7 @@ PHPDBG_COMMAND(clean) /* {{{ */ return SUCCESS; } - phpdbg_out("Cleaning Execution Environment"); + phpdbg_out("Cleaning Execution Environment\n"); phpdbg_xml(""); phpdbg_writeln("clean", "classes=\"%d\"", "Classes %d", zend_hash_num_elements(EG(class_table))); @@ -889,7 +889,7 @@ PHPDBG_COMMAND(clean) /* {{{ */ PHPDBG_COMMAND(clear) /* {{{ */ { - phpdbg_out("Clearing Breakpoints"); + phpdbg_out("Clearing Breakpoints\n"); phpdbg_xml(""); phpdbg_writeln("clear", "files=\"%d\"", "File %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE])); diff --git a/tests/commands/0002_set.test b/tests/commands/0002_set.test index 468ac6d9ea0..6a14a15adc2 100644 --- a/tests/commands/0002_set.test +++ b/tests/commands/0002_set.test @@ -8,7 +8,7 @@ # setting error color # setting notice color # Failed to find breakpoint #0 -# oplog disabled +# [Oplog off] # opened oplog test.log # nothing ################################################# diff --git a/tests/commands/0102_print.test b/tests/commands/0102_print.test index de4acb7651b..c174564e07f 100644 --- a/tests/commands/0102_print.test +++ b/tests/commands/0102_print.test @@ -4,15 +4,14 @@ # expect: TEST::FORMAT # options: -rr ################################################# -#[User Class: test] -#Methods (3): +#[User Class: test (3 methods)] #L%d-%d test::testMethod() %s # L%d %s ZEND_RETURN C%d # L%d-%d test::testPrivateMethod() %s # L%d %s ZEND_RETURN C%d # L%d-%d test::testProtectedMethod() %s # L%d %s ZEND_RETURN C%d -#[User Method testMethod] +#[User Method testMethod (1 ops)] # L%d-%d test::testMethod() %s # L%d %s ZEND_RETURN C%d ################################################# diff --git a/tests/commands/0104_clean.test b/tests/commands/0104_clean.test index c7a579be179..d50903c479e 100644 --- a/tests/commands/0104_clean.test +++ b/tests/commands/0104_clean.test @@ -4,11 +4,11 @@ # expect: TEST::FORMAT # options: -rr ################################################# -#[Cleaning Execution Environment] -#Classes %d -#Functions %d -#Constants %d -#Includes %d +#Cleaning Execution Environment +#Classes %d +#Functions %d +#Constants %d +#Includes %d #[Nothing to execute!] ################################################# clean diff --git a/tests/commands/0105_clear.test b/tests/commands/0105_clear.test index b547b0d6ba1..8ce10024913 100644 --- a/tests/commands/0105_clear.test +++ b/tests/commands/0105_clear.test @@ -4,7 +4,7 @@ # expect: TEST::FORMAT # options: -rr ################################################# -#[Clearing Breakpoints] +#Clearing Breakpoints #File%w%d #Functions%w%d #Methods%w%d diff --git a/tests/commands/0106_compile.test b/tests/commands/0106_compile.test index ce4e16981b3..b4d801670bc 100644 --- a/tests/commands/0106_compile.test +++ b/tests/commands/0106_compile.test @@ -4,8 +4,7 @@ # expect: TEST::FORMAT # options: -rr ################################################# -#[Attempting compilation of %s] -#[Success] +#[Successful compilation of %s] #Hello World #[Script ended normally] ################################################# From c30c40c35991a5c8ea9ee212c5b31b0e09156c01 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 02:04:12 +0200 Subject: [PATCH 017/125] Make print command xml output more consistent --- phpdbg_print.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/phpdbg_print.c b/phpdbg_print.c index 65acc492a29..b7ec4c5dcaa 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -63,14 +63,14 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) end = op_array->last-1; if (method->common.scope) { - phpdbg_writeln("printoplineinfo", "startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "\tL%d-%d %s::%s() %s", + phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "\tL%d-%d %s::%s() %s", op_array->line_start, op_array->line_end, method->common.scope->name, method->common.function_name, op_array->filename ? op_array->filename : "unknown"); } else { - phpdbg_writeln("printoplineinfo", "startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "\tL%d-%d %s() %s", + phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "\tL%d-%d %s() %s", method->common.function_name ? op_array->line_start : 0, method->common.function_name ? op_array->line_end : 0, method->common.function_name ? method->common.function_name : "{main}", @@ -98,9 +98,9 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) default: { if (method->common.scope) { - phpdbg_writeln("printoplineinfo", "type=\"internal\" method=\"%s::%s\"", "Internal %s::%s()", method->common.scope->name, method->common.function_name); + phpdbg_writeln("printoplineinfo", "type=\"Internal\" method=\"%s::%s\"", "Internal %s::%s()", method->common.scope->name, method->common.function_name); } else { - phpdbg_writeln("printoplineinfo", "type=\"internal\" function=\"%s\"", "\tInternal %s()", method->common.function_name); + phpdbg_writeln("printoplineinfo", "type=\"Internal\" function=\"%s\"", "\tInternal %s()", method->common.function_name); } } } @@ -114,7 +114,7 @@ PHPDBG_PRINT(exec) /* {{{ */ } if (PHPDBG_G(ops)) { - phpdbg_notice("printinfo", "file=\"%s\" count=\"%d\"", "Context %s (%d ops)", PHPDBG_G(exec), PHPDBG_G(ops)->last); + phpdbg_notice("printinfo", "file=\"%s\" num=\"%d\"", "Context %s (%d ops)", PHPDBG_G(exec), PHPDBG_G(ops)->last); phpdbg_print_function_helper((zend_function*) PHPDBG_G(ops) TSRMLS_CC); } @@ -132,15 +132,15 @@ PHPDBG_PRINT(stack) /* {{{ */ if (EG(in_execution) && ops) { if (ops->function_name) { if (ops->scope) { - phpdbg_notice("printinfo", "method=\"%s::%s\" count=\"%d\"", "Stack in %s::%s() (%d ops)", ops->scope->name, ops->function_name, ops->last); + phpdbg_notice("printinfo", "method=\"%s::%s\" num=\"%d\"", "Stack in %s::%s() (%d ops)", ops->scope->name, ops->function_name, ops->last); } else { - phpdbg_notice("printinfo", "function=\"%s\" count=\"%d\"", "Stack in %s() (%d ops)", ops->function_name, ops->last); + phpdbg_notice("printinfo", "function=\"%s\" num=\"%d\"", "Stack in %s() (%d ops)", ops->function_name, ops->last); } } else { if (ops->filename) { - phpdbg_notice("printinfo", "file=\"%s\" count=\"%d\"", "Stack in %s (%d ops)", ops->filename, ops->last); + phpdbg_notice("printinfo", "file=\"%s\" num=\"%d\"", "Stack in %s (%d ops)", ops->filename, ops->last); } else { - phpdbg_notice("printinfo", "opline=\"%p\" count=\"%d\"", "Stack @ %p (%d ops)", ops, ops->last); + phpdbg_notice("printinfo", "opline=\"%p\" num=\"%d\"", "Stack @ %p (%d ops)", ops, ops->last); } } phpdbg_print_function_helper((zend_function*) ops TSRMLS_CC); @@ -156,7 +156,7 @@ PHPDBG_PRINT(class) /* {{{ */ zend_class_entry **ce; if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { - phpdbg_notice("printinfo", "type=\"%s\" flag=\"%s\" class=\"%s\" count=\"%d\"", "%s %s: %s (%d methods)", + phpdbg_notice("printinfo", "type=\"%s\" flag=\"%s\" class=\"%s\" num=\"%d\"", "%s %s: %s (%d methods)", ((*ce)->type == ZEND_USER_CLASS) ? "User" : "Internal", ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? @@ -197,7 +197,7 @@ PHPDBG_PRINT(method) /* {{{ */ char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { - phpdbg_notice("printinfo", "type=\"%s\" flag=\"Method\" symbol=\"%s\" count=\"%d\"", "%s Method %s (%d ops)", + phpdbg_notice("printinfo", "type=\"%s\" flags=\"Method\" symbol=\"%s\" num=\"%d\"", "%s Method %s (%d ops)", (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", fbc->common.function_name, (fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0); @@ -243,7 +243,7 @@ PHPDBG_PRINT(func) /* {{{ */ lcname = zend_str_tolower_dup(func_name, func_name_len); if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { - phpdbg_notice("printinfo", "type=\"%s\" flag=\"%s\" symbol=\"%s\" count=\"%d\"", "%s %s %s (%d ops)", + phpdbg_notice("printinfo", "type=\"%s\" flags=\"%s\" symbol=\"%s\" num=\"%d\"", "%s %s %s (%d ops)", (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", (fbc->common.scope) ? "Method" : "Function", fbc->common.function_name, From 1ad0287499772e4411fb0bcaf607937d6871000f Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 15:28:25 +0200 Subject: [PATCH 018/125] Make phpdbg_prompt.c xml messages more consistent --- phpdbg_prompt.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index b03d23bc57a..6ab1aabbe3a 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -344,14 +344,14 @@ PHPDBG_COMMAND(exec) /* {{{ */ PHPDBG_G(exec) = res; PHPDBG_G(exec_len) = res_len; - + *SG(request_info).argv = PHPDBG_G(exec); php_hash_environment(TSRMLS_C); phpdbg_notice("exec", "type=\"set\" context=\"%s\"", "Set execution context: %s", PHPDBG_G(exec)); if (phpdbg_compile(TSRMLS_C) == FAILURE) { - phpdbg_error("compile", "context=\"%s\"", "Failed to compile %s", PHPDBG_G(exec)); + phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s", PHPDBG_G(exec)); } } else { phpdbg_notice("exec", "type=\"unchanged\"", "Execution context not changed"); @@ -370,12 +370,12 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ zend_file_handle fh; if (!PHPDBG_G(exec)) { - phpdbg_error("compile", "type=\"nocontext\"", "No execution context"); + phpdbg_error("inactivee", "type=\"nocontext\"", "No execution context"); return SUCCESS; } if (EG(in_execution)) { - phpdbg_error("compile", "type=\"isrunning\"", "Cannot compile while in execution"); + phpdbg_error("inactive", "type=\"isrunning\"", "Cannot compile while in execution"); return FAILURE; } @@ -410,7 +410,7 @@ PHPDBG_COMMAND(continue) /* {{{ */ PHPDBG_COMMAND(until) /* {{{ */ { if (!EG(in_execution)) { - phpdbg_error("until", "type=\"noexec\"", "Not executing"); + phpdbg_error("inactive", "type=\"noexec\"", "Not executing"); return SUCCESS; } @@ -433,7 +433,7 @@ PHPDBG_COMMAND(until) /* {{{ */ PHPDBG_COMMAND(finish) /* {{{ */ { if (!EG(in_execution)) { - phpdbg_error("finish", "type=\"noexec\"", "Not executing"); + phpdbg_error("inactive", "type=\"noexec\"", "Not executing"); return SUCCESS; } @@ -461,7 +461,7 @@ PHPDBG_COMMAND(finish) /* {{{ */ PHPDBG_COMMAND(leave) /* {{{ */ { if (!EG(in_execution)) { - phpdbg_error("leave", "type=\"noexec\"", "Not executing"); + phpdbg_error("inactive", "type=\"noexec\"", "Not executing"); return SUCCESS; } @@ -489,7 +489,7 @@ PHPDBG_COMMAND(leave) /* {{{ */ PHPDBG_COMMAND(frame) /* {{{ */ { if (!param) { - phpdbg_notice("frame", "num=\"%d\"", "Currently in frame #%d", PHPDBG_G(frame).num); + phpdbg_notice("frame", "id=\"%d\"", "Currently in frame #%d", PHPDBG_G(frame).num); } else { phpdbg_switch_frame(param->num TSRMLS_CC); } @@ -543,7 +543,7 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ PHPDBG_COMMAND(run) /* {{{ */ { if (EG(in_execution)) { - phpdbg_error("run", "type=\"isrunning\"", "Cannot start another execution while one is in progress"); + phpdbg_error("inactive", "type=\"isrunning\"", "Cannot start another execution while one is in progress"); return SUCCESS; } @@ -553,10 +553,10 @@ PHPDBG_COMMAND(run) /* {{{ */ zval **orig_retval_ptr = EG(return_value_ptr_ptr); zend_bool restore = 1; zend_execute_data *ex = EG(current_execute_data); - + if (!PHPDBG_G(ops)) { if (phpdbg_compile(TSRMLS_C) == FAILURE) { - phpdbg_error("run", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec)); + phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec)); goto out; } } @@ -585,7 +585,7 @@ PHPDBG_COMMAND(run) /* {{{ */ int argc = 0; int i; char *argv_str = strtok(param->str, " "); - + while (argv_str) { if (argc >= 4 && argc == (argc & -argc)) { argv = erealloc(argv, (argc * 2 + 1) * sizeof(char *)); @@ -601,16 +601,14 @@ PHPDBG_COMMAND(run) /* {{{ */ efree(SG(request_info).argv); SG(request_info).argv = erealloc(argv, ++argc * sizeof(char *)); SG(request_info).argc = argc; - + php_hash_environment(TSRMLS_C); } zend_try { -// php_output_activate(TSRMLS_C); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; zend_execute(EG(active_op_array) TSRMLS_CC); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; -// php_output_deactivate(TSRMLS_C); phpdbg_notice("run", "type=\"end\"", "Script ended normally"); } zend_catch { EG(active_op_array) = orig_op_array; @@ -633,7 +631,7 @@ PHPDBG_COMMAND(run) /* {{{ */ EG(return_value_ptr_ptr) = orig_retval_ptr; } } else { - phpdbg_error("run", "type=\"noexec\"", "Nothing to execute!"); + phpdbg_error("inactive", "type=\"nocontext\"", "Nothing to execute!"); } out: @@ -676,7 +674,7 @@ PHPDBG_COMMAND(ev) /* {{{ */ PHPDBG_COMMAND(back) /* {{{ */ { if (!EG(in_execution)) { - phpdbg_error("back", "type=\"noexec\"", "Not executing!"); +s phpdbg_error("inactive", "type=\"noexec\"", "Not executing!"); return SUCCESS; } @@ -757,7 +755,7 @@ PHPDBG_COMMAND(break) /* {{{ */ if (PHPDBG_G(exec)) { phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC); } else { - phpdbg_error("break", "type=\"noexec\"", "Execution context not set!"); + phpdbg_error("inactive", "type=\"noexec\"", "Execution context not set!"); } break; case METHOD_PARAM: @@ -811,7 +809,7 @@ PHPDBG_COMMAND(source) /* {{{ */ if (VCWD_STAT(param->str, &sb) != -1) { phpdbg_try_file_init(param->str, param->len, 0 TSRMLS_CC); } else { - phpdbg_error("source", "type=\"nofile\" file=\"%s\"", "Failed to stat %s, file does not exist", param->str); + phpdbg_error("source", "type=\"notfound\" file=\"%s\"", "Failed to stat %s, file does not exist", param->str); } return SUCCESS; @@ -844,7 +842,7 @@ PHPDBG_COMMAND(register) /* {{{ */ phpdbg_notice("register", "function=\"%s\"", "Registered %s", lcname); } else { - phpdbg_error("register", "type=\"notfound\" function=\"%s\"", "The requested function (%s) could not be found", param->str); + phpdbg_error("register", "type=\"notfoundc\" function=\"%s\"", "The requested function (%s) could not be found", param->str); } } else { phpdbg_error("register", "type=\"inuse\" function=\"%s\"", "The requested name (%s) is already in use", lcname); @@ -868,7 +866,7 @@ PHPDBG_COMMAND(quit) /* {{{ */ PHPDBG_COMMAND(clean) /* {{{ */ { if (EG(in_execution)) { - phpdbg_error("clean", "type=\"isrunning\"", "Cannot clean environment while executing"); + phpdbg_error("inactive", "type=\"isrunning\"", "Cannot clean environment while executing"); return SUCCESS; } From 7beb17f2fd796f5bc5dc0ce7d6afc42122d9e3c3 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 21:25:18 +0200 Subject: [PATCH 019/125] Make set commands more consistent --- phpdbg_set.c | 18 +++++++++--------- phpdbg_utils.c | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/phpdbg_set.c b/phpdbg_set.c index da850719416..2efe8ea6ecc 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -48,7 +48,7 @@ const phpdbg_command_t phpdbg_set_commands[] = { PHPDBG_SET(prompt) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("prompt", "str=\"%s\"", "Current prompt: %s", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("setprompt", "str=\"%s\"", "Current prompt: %s", phpdbg_get_prompt(TSRMLS_C)); } else { phpdbg_set_prompt(param->str TSRMLS_CC); } @@ -107,12 +107,12 @@ PHPDBG_SET(breaks) /* {{{ */ PHPDBG_SET(color) /* {{{ */ { const phpdbg_color_t *color = phpdbg_get_color(param->next->str, param->next->len TSRMLS_CC); - + if (!color) { phpdbg_error("setcolor", "type=\"nocolor\"", "Failed to find the requested color (%s)", param->next->str); return SUCCESS; } - + switch (phpdbg_get_element(param->str, param->len TSRMLS_CC)) { case PHPDBG_COLOR_PROMPT: phpdbg_notice("setcolor", "type=\"prompt\" color=\"%s\" code=\"%s\"", "setting prompt color to %s (%s)", color->name, color->code); @@ -122,19 +122,19 @@ PHPDBG_SET(color) /* {{{ */ } phpdbg_set_color(PHPDBG_COLOR_PROMPT, color TSRMLS_CC); break; - + case PHPDBG_COLOR_ERROR: phpdbg_notice("setcolor", "type=\"error\" color=\"%s\" code=\"%s\"", "setting error color to %s (%s)", color->name, color->code); phpdbg_set_color(PHPDBG_COLOR_ERROR, color TSRMLS_CC); break; - + case PHPDBG_COLOR_NOTICE: phpdbg_notice("setcolor", "type=\"notice\" color=\"%s\" code=\"%s\"", "setting notice color to %s (%s)", color->name, color->code); phpdbg_set_color(PHPDBG_COLOR_NOTICE, color TSRMLS_CC); break; - + default: - phpdbg_error("setcolor", "type=\"invalidelement\"", "Failed to find the requested element (%s)", param->str); + phpdbg_error("setcolor", "type=\"invalidtype\"", "Failed to find the requested element (%s)", param->str); } return SUCCESS; @@ -152,7 +152,7 @@ PHPDBG_SET(colors) /* {{{ */ PHPDBG_G(flags) &= ~PHPDBG_IS_COLOURED; } } break; - + default: phpdbg_error("setcolors", "type=\"wrongargs\"", "set colors used incorrectly: set colors "); } @@ -172,7 +172,7 @@ PHPDBG_SET(oplog) /* {{{ */ PHPDBG_G(oplog) = fopen(param->str, "w+"); if (!PHPDBG_G(oplog)) { - phpdbg_error("setoplog", "file=\"%s\"", "Failed to open %s for oplog", param->str); + phpdbg_error("setoplog", "type=\"openfailure\" file=\"%s\"", "Failed to open %s for oplog", param->str); PHPDBG_G(oplog) = old; } else { if (old) { diff --git a/phpdbg_utils.c b/phpdbg_utils.c index d6b7525c600..bec222e3282 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1383,7 +1383,7 @@ PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D) /* {{{ */ PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC) { const phpdbg_element_t *element = elements; - + while (element && element->name) { if (len == element->name_length) { if (strncasecmp(name, element->name, len) == SUCCESS) { @@ -1392,7 +1392,7 @@ PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC) { } element++; } - + return PHPDBG_COLOR_INVALID; } @@ -1441,7 +1441,7 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ int phpdbg_rebuild_symtable(TSRMLS_D) { if (!EG(active_op_array)) { - phpdbg_error("symtable", "type=\"noops\"", "No active op array!"); + phpdbg_error("inactive", "type=\"op_array\"", "No active op array!"); return FAILURE; } @@ -1449,7 +1449,7 @@ int phpdbg_rebuild_symtable(TSRMLS_D) { zend_rebuild_symbol_table(TSRMLS_C); if (!EG(active_symbol_table)) { - phpdbg_error("symtable", "type=\"nosymtable\"", "No active symbol table!"); + phpdbg_error("inactive", "type=\"symbol_table\"", "No active symbol table!"); return FAILURE; } } @@ -1459,7 +1459,7 @@ int phpdbg_rebuild_symtable(TSRMLS_D) { PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D) /* {{{ */ { - int columns; + int columns; #ifdef _WIN32 CONSOLE_SCREEN_BUFFER_INFO csbi; From 6e698f1fa5563eca077848c02b47ef85d5ebeb61 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 21:26:57 +0200 Subject: [PATCH 020/125] Push first draft of xml protocol documentation --- xml.md | 595 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 595 insertions(+) create mode 100644 xml.md diff --git a/xml.md b/xml.md new file mode 100644 index 00000000000..c0554847cec --- /dev/null +++ b/xml.md @@ -0,0 +1,595 @@ +phpdbg XML format +================= + +Common attributes +================= + +severity +-------- + +- indicates the genre of phpdbg system output +- usually one of these values: + - normal + - notice + - error + +msgout +------ + +- text message output related to the xml data (e.g. <intro severity="normal" help="help" msgout="To get help using phpdbg type "help" and press enter" />) + +file +---- + +- refers to a filename + +method +------ + +- format classname::methodname +- refers to a method + +function +-------- + +- refers to a function + +symbol +------ + +- either function or method (is method if "::" are present) + +opline +------ + +- in hexadecimal format +- refers to a specific pointer to a (zend_)op + +opcode +------ + +- refers to an opcode (ZEND_*) + +type +---- + +- general attribute for most errors, describes the genre of the error + +General tags +============ + +intro +----- + +- appears on startup if -q flag wasn't provided as command line arg +- before any input possibility +- attributes may be spread over multiple tags + +### attributes ### + +- version: current phpdbg version (as string) +- help: command name for help +- report: URL for bug reporting + + +phpdbg +------ + +- general text message output from phpdbg system + +stream +------ + +- any output by PHP itself (e.g. <stream type="stdout">test</stream>) + +### attributes ### + +- type: stderr or stdout + +php +--- + +- php error output + +### attributes ### + +- msg: the error message + + +General error tags +================== + +command +------- + +- general errors about commands + +### possible attributes ### + +- type + - toomanyargs: more arguments than allowed + - noarg: argument missing + - wrongarg: wrong type of argument (e.g. letters instead of integer) + - toofewargs: not enough arguments + - notfound: command (or subcommand) doesn't exist + - ambiguous: command was ambiguous + - invalidcommand: command input is totally invalid + - (nostack: should not happen: is an internal error) + - (emptystack: should not happen: is an internal error) +p- command: passed command +- subcommand: passed subcommand (present if the error is related to the subcommand) +- expected: count of expected arguments +- got: type of argument for type "wrongarg" +- num: if possible, information about which parameter had a wrong argument + +inactive +-------- + +- by type + - op_array: nothing was yet compiled (probably because no execution context set) + - symbol_table: no symbol table present (not yet initiailized or already destructed) + - noexec: not in execution + - memory_manager: using the native memory manager (malloc, free, realloc) instead of e.g. the Zend MM + - notfound: file not found + - nocontext: execution context was not set (or compilation had failed) + - isrunning: command requires no running script + + +Commands +======== + +export +------ + +- tag: <exportbreakpoint /> +- usually triggered by successful export command +- may appear when cleaning to temporary store breakpoints +- errors by type + - openfailure: could not create file + +### attributes ### + +- count: number of exported breakpoints + +break / info break +------------------ + +- General tag for breakpoint creation, deletion and hits is "<breakpoint />" + +### possible attributes ### + +- id: the breakpoint id (if the leave command was executed, the id has the value "leave") +- num: the nth opline of a function/method/file +- success: has value "success": a brekpoint was successfully added +- pending: the breakpoint is waiting for resolving (e.g. a file opline on a not yet loaded file) +- deleted: has value "deleted": a breakpoint was successfully deleted +- eval: the condition on conditional breakpoints +- file +- opline +- opcode +- symbol +- function +- method +- line + + +- listing breakpoints always in a container element "<breakpoints>" + - Child nodes: + - function + - method + - file + - opline + - methodopline + - functionopline + - fileopline + - evalfunction + - evalfunctionopline + - evalmethod + - evalmethodopline + - evalfile + - evalopline + - eval + - opcode + - attributes: + - name: name of the symbol (function/method/file/opcode) + - disabled: empty value if enabled, non-empty if enabled + +- errors (by type) + - exists: the breakpoint already exists + - maxoplines: tries to break at an opline (usedoplinenum) higher than the number of present oplines (in maxoplinenum) + - nomethod: method doesn't exist + - internalfunction: one cannot break on an opline of an internal function + - notregular: tries to set a breakpoint in not a regular file + - (invalidparameter: should not happen: is an internal error) + +frame +----- + +- General tag for frames is "<frame>" +- always has id attribute; if it only has id attribute, it just indicates current frame number, no other elements follow +- may contain other elements (of type <arg>) when contained in <backtrace> tag +- <arg> always contains a <stream> element, the value of the variable + +### possible attributes ### + +- id: the frame id, current frame has id 0 (frames with internal function calls have the same id than their called frame) +- symbol ("{main}" is root frame) +- file +- line +- internal: has value "internal" when being an internal function call (one cannot inspect that frame) + +- being an error: (by type) + - maxnum: tried to access a frame with a number heigher than existing (or < 0) + +### attributes on <arg> ### + +- variadic: has a non-empty value if the argument is variadic +- name: variable name of parameter + +info (subcommands) +------------------ + +### break ### + +- See above ("break / info break") + +### files ### + +- lists included files +- <includedfileinfo num="" /> with num having an integer value, indicating the number of included files +- <includedfile name=""/>: one per file, with name being the file path of the included file + +### error ### + +- gets last error +- <lasterror error="" (file="" line="") /> +- error attribute contains the last error as a string, is empty if there's no last error + +### vars / globals ### + +- <variableinfo num="" /> with num having an integer value, indicating the number of (local or superglobal) variables +- if info vars was used it'll have also one of these attributes: + - method + - function + - file + - opline +- for each variable there is a <variable> followed by a <variabledetails> element +- <variable address="" refcount="" type="" /> + - address: pointer to zval (hexadecimal) + - refcount: refcount of zval + - type: the variable type (long, string, ...). If the value is "unknown", the other attributes are meaningless +- <variabledetails name="" /> with name the name of the variable, optional args are: + - refstatus: empty if the zval is not a reference + - class: the class the object in the zval is an instance of + - resource: the type of the resource in the zval + +### literal ### + +- <literalinfo num="" /> with num having an integer value, indicating the number of literals, optional arguments are: + - method + - function + - file + - opline +- for each literal there is a <literal> followed by a <stream type="stdout"> which prints the value of the literal +- <literal id="" />: where id is the internal identifier of the literal + +### memory ### + +- Format: + + <meminfo /> + <current /> + <used mem="" /> + <real mem="" /> + <peak /> + <used mem="" /> + <real mem="" /> + +- mem is an attribute whose value is a float. The memory is given in kilobytes (1 kB == 1024 bytes) + +### classes ### + +- <classinfo num="" /> with num having an integer value, indicating the number of loaded user-defined classes +- Each class is enumerated with first a <class>, then an optional <parents> container and then a <classsource> element +- The <parents> container contains the <class> elements of the parent of the last <class> element. +- <class type="" flags="" name="" methodcount="" /> + - type: either "User" or "Internal" + - flags: either "Interface", "Class" or "Abstract Class" +- <classsource /> where the class was defined, if there are no attributes, location is unknown, usually defined by + - file + - line + +### funcs ### + +- <functioninfo num="" /> with num having an integer value, indicating the number of loaded user-defined functions +- Each class is enumerated with first a <function> and then a <functionsource> element +- <function name="" /> +- <functionsource /> where the function was defined, if there are no attributes, location is unknown, usually defined by + - file + - line + +list +---- + +- consists of <line> elements wrapped in a <list> container +- <list file=""> is the container element with file being the filename +- <line line="" code="" /> with value of code being the whole line of code in the line specified in the line attribute + - current: this attribute is set to "current" if that line is the line where the executor currently is + +print +----- + +### without a subcommand ### + +- <print> elements are wrapped in a <printinfo> element +- there may be a variable number of <print> elements with a variable count of args inside the <printinfo> element +- possible args are: + - readline: yes/no - readline enabled or disabled + - libedit: yes/no - libedit enabled or disabled + - context: current executing context + - compiled: yes/no - are there actual compiled ops? + - stepping: @@ TODO (meaningless for now) @@ + - quiet: on/off - should it always print the opline being currently executed? + - oplog: on/off - are oplines logged in a file? + - ops: number of opcodes in current executing context + - vars: number of compiled variables (CV) + - executing: yes/no - in executor? + - vmret: the return value of the last executed opcode + - default: continue + - 1: return from vm + - 2: enter stack frame + - 3: leave stack frame + - classes: number of classes + - functions: number of functions + - constants: number of constants + - includes: number of included files + +### with a subcommand ### + +- introduced by <printinfo num="" /> (except for print opline) with num being the number of opcodes and one of these args: + - file + - method + - function + - class (then also type and flags attributes, see info classes command for their meanings) + - symbol (also type and flags attributes; here the value of flags is either "Method" or "Function") +- if there is a class method, the methods are all wrapped in a <printmethods> container +- then comes a <printoplineinfo type="" /> where type is either "User" or "Internal" +- the <printoplineinfo> has either a method or a function attribute +- if the type is "Internal" + - there are no oplines, it's an internal method or function +- if the type is "User" + - it has these attributes + - startline: the first line of code where the method or function is defined + - endline: the lastt line of code where the method or function is defined + - file: the file of code where the method or function is defined + - is followed by the oplines of that method or function (<print> elements) +- <print line="%u" opline="%p" opcode="%s" op="%s" /> +- in case of print opline it emits a single <opline line="" opline="" opcode="" op="" file="" /> + +exec +---- + +- command executing and compiling a given file + - <exec type="unset" context="" />: indicates unsetting of the old context + - <exec type="unsetops" />: indicates unsetting of the old compiled opcodes + - <exec type="unchanged" />: same execution context choosen again + - <exec type="set" context="" />: indicates setting of the new context +- errors by tag + - <compile> + - openfailure: couldn't open file + - compilefailure: The file indicated in context couldn't be compiled + - <exec> + - invalid: given context (attribute) is not matching a valid file or symlink + - notfound: given context (attribute) does not exist + +run +--- + +- runs the script (set via exec command) +- <run type="end" />: script execution ended normally +- (error) <run type="bailout" /> the VM bailed out (usually because there was some error) +- compile failures see under exec, errors, <compile> + +step +---- + +- steps by one line or opcode (as defined via set stepping) default is one line +- returns back to the executor + +continue +-------- + +- returns back to the executor + +until +----- + +- temporarily disables all the breakpoints on that line until that line was left once +- returns back to the executor + +finish +------ + +- temporarily disables all the breakpoints until the end of the current frame +- returns back to the executor + +leave +------ + +- temporarily disables all the breakpoints past the end of the current frame and then stops +- returns back to the executor + +back +---- + +- prints backtrace +- see frame command + +ev +-- + +- eval()uates some code +- output wrapped in <eval> tags + +sh +-- + +- executes shell command +- still pipes to stdout ... without wrapping <stream> !!! (@@ TODO @@) + +source +------ + +- executes a file in .phpdbginit format +- errors by type + - notfound: file not found + +register +-------- + +- registers a function to be used like a command +- <register function="" />: successfully registered function +- errors by type + - notfound: no such function + - inuse: function already registered + +quit +---- + +- quits phpdbg +- if successful connection will be closed... + +clean +----- + +- cleans environment (basically a shutdown + new startup) +- <clean> tags wrapped in a <cleaninfo> container +- possible attributes of <clean> tag + - classes: number of classes + - functions: number of functions + - constants: number of constants + - includes: number of included files + +clear +----- + +- removes all breakpoints +- <clear> tags wrapped in a <clearinfo> container +- possible attributes of <clear> tag (value is always the number of defined breakpoints of that type) + - files + - functions + - methods + - oplines + - fileoplines + - functionoplines + - methodoplines + - eval + +watch +----- + +- watchpoints generally are identified by a variable (one may need to switch frames first...) +- <watch variable="" />, <watchrecursive variable="" /> and <watcharray variable="" /> (normal, array, recursive) +- <watch> if error, by type: + - undefined: tried to set a watchpoint on a not (yet) defined variable + - notiterable: element which is tried to be accessed as an object or array is nor array nor object + - invalidinput: generally malformed input +- <watchdelete variable="" />: when "watch delete" was used on a watchpoint +- (error) <watchdelete type="nowatch" />: that watchpoint doesn't exist, so couldn't be deleted +- for hit watchpoints etc., see Other tags, <watch*> +- when using watch list, <watchvariable> elements are wrapped in a <watchlist> container + - <watchvariable variable="" on="" type="" /> + - variable: watched variable (may be a variable of another scope!) + - on: values are array or variable, depending on what is watched + - type: values are recursive or simple, depending on whether the watchpoint is checked recursively or not + +set +--- + +- a general error is type="wrongargs" where a wrong argument was passed to a subcommand; tag is then <set*> + +### prompt ### + +- without other args, a <setpromt str="" /> tag is emitted where the value of the str attribue is the value of the prompt +- when there is another arg, the prompt is changed to that arg, no further xml answer + +### break ### + +- enables / disables a given breakpoint silently with no further xml answer +- if the boolean switch is omitted, it emits current state in a <setbreak id="" active="" /> where active is on or off +- error with type="nobreak", when no breakpoint with the given id exists + +### breaks ### + +- generally enables / disables breakpoint functionality silently with no futher xml answer +- if the boolean switch is omitted, it emits current state in a <setbreaks active="" /> where active is on or off + +### color ### + +- sets the color on prompt, error or notices +- <setcolor type="" color="" code="" />: code is the color code of color, type is either: + - prompt + - error + - notice +- errors by type: + - nocolor: color doesn't exist + - invalidtype: type wasn't one of the three allowed types + +### colors ### + +- generally enables / disables colors silently with no further xml answer +- if the boolean switch is omitted, it emits current state in a <setcolors active="" /> where active is on or off + +### oplog ### + +- sets oplog +- (error) <setoplog type="openfailure" file="" /> when it couldn't open the passed file path +- <setoplog type="closingold" /> is emitted when there was a previous open oplog (and a file is passed) +- if no further argument is passed, it emits current state in a <setoplog active="" /> where active is on or off + +### quiet ### + +- generally enables / disables quietness silently with no further xml answer +- if the boolean switch is omitted, it emits current state in a <setquiet active="" /> where active is on or off + +### setpping ### + +- sets stepping to either opcode or line (so a step command will either advance one op or one line) +- if no further argument is passed, it emits current state in a <setoplog type="" /> where active is opcode or line + +### refcount ### + +- generally enables / disables showing of refcount in watchpoint breaks silently with no further xml answer +- if the boolean switch is omitted, it emits current state in a <setrefcount active="" /> where active is on or off + + +Other tags +========== + +<signal> +-------- + +- received caught signal + +### attributes ### + +- type: type of signal + +<watch*> +-------- + +- generally emitted on hit watchpoint +- <watchdelete variable="" />: when a variable was unset, the watchpoint is removed too +- <watchhit variable="" />: when ever a watched variable is changed, followed by a <watchdata> container +- <watchdata> may contain + - for watchpoints on variables: + - each of these <watch*> tags conatins a type attribute whose value is either "old" or "new") + - <watchvalue type="" inaccessible="inaccessible" />: old value is inaccessible + - <watchvalue type=""> may contain a <stream> element which indicates the old/new (type attribute) value of the variable + - <watchrefcount type="" refcount="" isref="" />: old/new (type attribute) refcount and isref, both numbers + - isref: if the value is 0, it's not a reference, else it is one + - for watchpoints on arrays: + - <watchsize> inspects size variations of an array (the sum): + - removed: number of elements removed + - added: number of elements added + - <watcharrayptr>: if this tag appears, the internal pointer of the array way changed From aeb750895949df5781738a3b0dce7ea8a0c31768 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 25 Sep 2014 22:01:31 +0200 Subject: [PATCH 021/125] Fix typo: inactivee => inactive --- phpdbg_prompt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 6ab1aabbe3a..4eed3864761 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -370,7 +370,7 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ zend_file_handle fh; if (!PHPDBG_G(exec)) { - phpdbg_error("inactivee", "type=\"nocontext\"", "No execution context"); + phpdbg_error("inactive", "type=\"nocontext\"", "No execution context"); return SUCCESS; } From b183494f376adadeb332c5644e230c226b2ebb04 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 28 Sep 2014 02:57:12 +0200 Subject: [PATCH 022/125] Send a \x03 during execution to interrupt (POSIX only) --- config.m4 | 2 +- phpdbg.c | 134 ++++++++++++++++++++++++++++++++++++---------- phpdbg.h | 37 ++++++------- phpdbg_cmd.c | 81 +++++++++++++++++----------- phpdbg_opcode.c | 2 +- phpdbg_prompt.c | 14 +++++ phpdbg_prompt.h | 2 + phpdbg_sigsafe.c | 107 ++++++++++++++++++++++++++++++++++++ phpdbg_sigsafe.h | 23 ++++++++ phpdbg_utils.c | 66 +++++++++++++---------- phpdbg_utils.h | 20 +++---- zend_mm_structs.h | 102 +++++++++++++++++++++++++++++++++++ 12 files changed, 470 insertions(+), 120 deletions(-) create mode 100644 phpdbg_sigsafe.c create mode 100644 phpdbg_sigsafe.h create mode 100644 zend_mm_structs.h diff --git a/config.m4 b/config.m4 index d78a439af02..24e99761628 100644 --- a/config.m4 +++ b/config.m4 @@ -19,7 +19,7 @@ if test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_sigsafe.c" if test "$PHP_READLINE" != "no" -o "$PHP_LIBEDIT" != "no"; then PHPDBG_EXTRA_LIBS="$PHP_READLINE_LIBS" diff --git a/phpdbg.c b/phpdbg.c index e30d35d71fc..a72ddbb1839 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -36,6 +36,7 @@ # include # include # include +# include # include # include # include @@ -69,10 +70,10 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->bp_count = 0; pg->flags = PHPDBG_DEFAULT_FLAGS; pg->oplog = NULL; - pg->io[PHPDBG_STDIN] = NULL; - pg->io[PHPDBG_STDOUT] = NULL; - pg->io[PHPDBG_STDERR] = NULL; + memset(pg->io, 0, sizeof(pg->io)); pg->frame.num = 0; + pg->input_buflen = 0; + pg->sigsafe_mem.mem = NULL; } /* }}} */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ @@ -529,7 +530,9 @@ static inline void php_sapi_phpdbg_flush(void *context) /* {{{ */ TSRMLS_FETCH(); #endif - fflush(PHPDBG_G(io)[PHPDBG_STDOUT]); + if (!phpdbg_active_sigsafe_mem(TSRMLS_C)) { + fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr); + } } /* }}} */ /* copied from sapi/cli/php_cli.c cli_register_file_handles */ @@ -698,17 +701,27 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */ { TSRMLS_FETCH(); - if (EG(in_execution)) { - /* set signalled only when not interactive */ - if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) { - PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED; - } - } else { + if (PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE) { /* we quit remote consoles on recv SIGINT */ if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; zend_bailout(); } + } else { + /* set signalled only when not interactive */ + if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) { + if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { + char mem[PHPDBG_SIGSAFE_MEM_SIZE + 1]; + + phpdbg_set_sigsafe_mem(mem TSRMLS_CC); + zend_try { + phpdbg_force_interruption(TSRMLS_C); + } zend_end_try() + phpdbg_clear_sigsafe_mem(TSRMLS_C); + return; + } + PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED; + } } } /* }}} */ @@ -769,12 +782,12 @@ static int phpdbg_remote_init(const char* address, short port, int *server, int *server = phpdbg_open_socket(address, port); if (*server < 0) { - phpdbg_rlog(stderr, "Initializing connection on %s:%d failed", address, port); + phpdbg_rlog(fileno(stderr), "Initializing connection on %s:%d failed", address, port); return FAILURE; } - phpdbg_rlog(stderr, "accepting connections on %s:%d", address, port); + phpdbg_rlog(fileno(stderr), "accepting connections on %s:%d", address, port); { struct sockaddr_in address; socklen_t size = sizeof(address); @@ -784,7 +797,7 @@ static int phpdbg_remote_init(const char* address, short port, int *server, int *socket = accept(*server, (struct sockaddr *) &address, &size); inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); - phpdbg_rlog(stderr, "connection established from %s", buffer); + phpdbg_rlog(fileno(stderr), "connection established from %s", buffer); } dup2(*socket, fileno(stdout)); @@ -794,9 +807,61 @@ static int phpdbg_remote_init(const char* address, short port, int *server, int *stream = fdopen(*socket, "r+"); + phpdbg_set_async_io(*socket); + return SUCCESS; } +/* This function *strictly* assumes that SIGIO is *only* used on the remote connection stream */ +void phpdbg_sigio_handler(int sig, siginfo_t *info, void *context) /* {{{ */ +{ + int flags; + size_t newlen; + size_t i; + TSRMLS_FETCH(); + +// if (!(info->si_band & POLLIN)) { +// return; /* Not interested in writeablility etc., just interested in incoming data */ +// } + + /* only non-blocking reading, avoid non-blocking writing */ + flags = fcntl(PHPDBG_G(io)[PHPDBG_STDIN].fd, F_GETFL, 0); + fcntl(PHPDBG_G(io)[PHPDBG_STDIN].fd, F_SETFL, flags | O_NONBLOCK); + + do { + char mem[PHPDBG_SIGSAFE_MEM_SIZE + 1]; + size_t off = 0; + + if ((newlen = recv(PHPDBG_G(io)[PHPDBG_STDIN].fd, mem, PHPDBG_SIGSAFE_MEM_SIZE, MSG_PEEK)) == (size_t) -1) { + break; + } + for (i = 0; i < newlen; i++) { + switch (mem[off + i]) { + case '\x03': /* ^C char */ + if (PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE) { + break; /* or quit ??? */ + } + if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { + phpdbg_set_sigsafe_mem(mem TSRMLS_CC); + zend_try { + phpdbg_force_interruption(TSRMLS_C); + } zend_end_try(); + phpdbg_clear_sigsafe_mem(TSRMLS_C); + break; + } + if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) { + PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED; + } + break; + } + } + off += i; + } while (0); + + + fcntl(PHPDBG_G(io)[PHPDBG_STDIN].fd, F_SETFL, flags); +} /* }}} */ + void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */ { int is_handled = FAILURE; @@ -890,9 +955,13 @@ int main(int argc, char **argv) /* {{{ */ #endif #ifndef _WIN32 + struct sigaction sigio_struct; struct sigaction signal_struct; signal_struct.sa_sigaction = phpdbg_signal_handler; signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER; + sigio_struct.sa_sigaction = phpdbg_sigio_handler; + sigio_struct.sa_flags = SA_SIGINFO; + address = strdup("127.0.0.1"); #endif @@ -1105,18 +1174,6 @@ phpdbg_main: php_optind++; } -#ifndef _WIN32 - /* setup remote server if necessary */ - if (!cleaning && listen > 0) { - if (phpdbg_remote_init(address, listen, &server, &socket, &stream) == FAILURE) { - exit(0); - } - - /* set remote flag to stop service shutting down upon quit */ - remote = 1; - } -#endif - if (sapi_name) { phpdbg->name = sapi_name; } @@ -1171,7 +1228,23 @@ phpdbg_main: EXCEPTION_POINTERS *xp; __try { #endif - zend_mm_heap *mm_heap = phpdbg_mm_get_heap(); + zend_mm_heap *mm_heap; + +#ifndef _WIN32 + /* setup remote server if necessary */ + if (!cleaning && listen > 0) { + if (phpdbg_remote_init(address, listen, &server, &socket, &stream) == FAILURE) { + exit(0); + } + + sigaction(SIGIO, &sigio_struct, NULL); + + /* set remote flag to stop service shutting down upon quit */ + remote = 1; + } +#endif + + mm_heap = phpdbg_mm_get_heap(); if (mm_heap->use_zend_alloc) { mm_heap->_malloc = phpdbg_malloc_wrapper; @@ -1246,9 +1319,12 @@ phpdbg_main: } #endif - PHPDBG_G(io)[PHPDBG_STDIN] = stdin; - PHPDBG_G(io)[PHPDBG_STDOUT] = stdout; - PHPDBG_G(io)[PHPDBG_STDERR] = stderr; + PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin; + PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin); + PHPDBG_G(io)[PHPDBG_STDOUT].ptr = stdout; + PHPDBG_G(io)[PHPDBG_STDOUT].fd = fileno(stdout); + PHPDBG_G(io)[PHPDBG_STDERR].ptr = stderr; + PHPDBG_G(io)[PHPDBG_STDERR].fd = fileno(stderr); if (exec) { /* set execution context */ PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC); diff --git a/phpdbg.h b/phpdbg.h index f9ca0f2a710..105614c8691 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -72,6 +72,13 @@ # include #endif +#ifdef ZTS +# define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v) +#else +# define PHPDBG_G(v) (phpdbg_globals.v) +#endif + +#include "phpdbg_sigsafe.h" #include "phpdbg_lexer.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" @@ -80,12 +87,6 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); -#ifdef ZTS -# define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v) -#else -# define PHPDBG_G(v) (phpdbg_globals.v) -#endif - #define PHPDBG_NEXT 2 #define PHPDBG_UNTIL 3 #define PHPDBG_FINISH 4 @@ -203,29 +204,21 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) int vmret; /* return from last opcode handler execution */ FILE *oplog; /* opline log */ - FILE *io[PHPDBG_IO_FDS]; /* io */ + struct { + FILE *ptr; + int fd; + } io[PHPDBG_IO_FDS]; /* io */ char *prompt[2]; /* prompt */ const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */ char *buffer; /* buffer */ zend_bool last_was_newline; /* check if we don't need to output a newline upon next phpdbg_error or phpdbg_notice */ + char input_buffer[PHPDBG_MAX_CMD]; /* stdin input buffer */ + int input_buflen; /* length of stdin input buffer */ + phpdbg_signal_safe_mem sigsafe_mem; /* memory to use in async safe environment (only once!) */ + zend_ulong flags; /* phpdbg flags */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ -/* the beginning (= the important part) of the _zend_mm_heap struct defined in Zend/zend_alloc.c - Needed for realizing watchpoints */ -struct _zend_mm_heap { - int use_zend_alloc; - void *(*_malloc)(size_t); - void (*_free)(void *); - void *(*_realloc)(void *, size_t); - size_t free_bitmap; - size_t large_free_bitmap; - size_t block_size; - size_t compact_size; - zend_mm_segment *segments_list; - zend_mm_storage *storage; -}; - #endif /* PHPDBG_H */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 8ca56aa25cc..0ea6c121271 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -792,54 +792,71 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC) PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ { char *cmd = NULL; -#if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT) - char buf[PHPDBG_MAX_CMD]; -#endif char *buffer = NULL; if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && - (buffered == NULL)) { - fflush(PHPDBG_G(io)[PHPDBG_STDOUT]); + if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && (buffered == NULL) && !phpdbg_active_sigsafe_mem(TSRMLS_C)) { + fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr); } if (buffered == NULL) { -disconnect: if (0) { +disconnect: PHPDBG_G(flags) |= (PHPDBG_IS_QUITTING|PHPDBG_IS_DISCONNECTED); zend_bailout(); return NULL; } -#if !defined(HAVE_LIBREADLINE) && !defined(HAVE_LIBEDIT) +#define USE_LIB_STAR (defined(HAVE_LIBREADLINE) && defined(HAVE_LIBEDIT)) +#if !USE_LIB_STAR if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { if (!phpdbg_write("%s", phpdbg_get_prompt(TSRMLS_C))) { goto disconnect; } PHPDBG_G(last_was_newline) = 1; } - - /* note: EOF is ignored */ -readline: - if (!fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) { - /* the user has gone away */ - if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { - goto disconnect; - } else goto readline; - } +#endif - cmd = buf; -#else - /* note: EOF makes readline write prompt again in local console mode */ + /* note: EOF makes readline write prompt again in local console mode - and ignored if compiled without readline */ + /* strongly assuming to be in blocking mode... */ +#if USE_LIB_STAR readline: - if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) +#endif + { char buf[PHPDBG_MAX_CMD]; - if (fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) { - cmd = buf; - } else goto disconnect; - } else { + int bytes = 0, len = PHPDBG_G(input_buflen); + if (PHPDBG_G(input_buflen)) { + memcpy(buf, PHPDBG_G(input_buffer), len); + } + + while ((bytes = read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len)) > 0) { + int i; + for (i = len; i < len + bytes; i++) { + if (buf[i] == '\n') { + PHPDBG_G(input_buflen) = len + bytes - 1 - i; + if (PHPDBG_G(input_buflen)) { + memcpy(PHPDBG_G(input_buffer), buf + i + 1, PHPDBG_G(input_buflen)); + } + if (i != PHPDBG_MAX_CMD - 1) { + buf[i + 1] = 0; + } + cmd = buf; + goto end; + } + } + len += bytes; + } + + if (bytes <= 0) { + goto disconnect; + } + + cmd = buf; + } +#if USE_LIB_STAR + else { cmd = readline(phpdbg_get_prompt(TSRMLS_C)); - PHPDBG_G(last_was_newline) = 1; } if (!cmd) { @@ -850,13 +867,15 @@ readline: add_history(cmd); } #endif - } else cmd = buffered; - + } else { + cmd = buffered; + } +end: + PHPDBG_G(last_was_newline) = 1; buffer = estrdup(cmd); -#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT) - if (!buffered && cmd && - !(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { +#if USE_LIB_STAR + if (!buffered && cmd && !(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { free(cmd); } #endif diff --git a/phpdbg_opcode.c b/phpdbg_opcode.c index 6b13625fc14..4edf4cfed25 100644 --- a/phpdbg_opcode.c +++ b/phpdbg_opcode.c @@ -162,7 +162,7 @@ void phpdbg_print_opline_ex(zend_execute_data *execute_data, HashTable *vars, ze } if (!ignore_flags && PHPDBG_G(oplog)) { - phpdbg_log_ex(PHPDBG_G(oplog), "L%-5u %16p %-30s %s %s", + phpdbg_log_ex(fileno(PHPDBG_G(oplog)), "L%-5u %16p %-30s %s %s", opline->lineno, opline, phpdbg_decode_opcode(opline->opcode), diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index ed60e99c468..367926abd5f 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1334,3 +1334,17 @@ next: } zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen"); } /* }}} */ + +void phpdbg_force_interruption(TSRMLS_D) { + zend_execute_data *data = EG(current_execute_data); /* should be always readable if not NULL */ + + if (data) { + if (data->op_array) { + phpdbg_notice("Current opline: %p (op #%lu) in %s:%u", data->opline, (data->opline - data->op_array->opcodes) / sizeof(data->opline), data->op_array->filename, data->opline->lineno); + } else { + phpdbg_notice("Current opline: %p (op_array information unavailable)", data->opline); + } + } else { + phpdbg_notice("No information available about executing context"); + } +} diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index ef648aabeb0..5909407e7df 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -64,4 +64,6 @@ void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC); void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC); #endif /* }}} */ +void phpdbg_force_interruption(TSRMLS_D); + #endif /* PHPDBG_PROMPT_H */ diff --git a/phpdbg_sigsafe.c b/phpdbg_sigsafe.c new file mode 100644 index 00000000000..96ac713f232 --- /dev/null +++ b/phpdbg_sigsafe.c @@ -0,0 +1,107 @@ +#include "phpdbg_sigsafe.h" +#include "phpdbg.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +static inline void zend_mm_init(zend_mm_heap *heap) { + zend_mm_free_block *p; + int i; + + heap->free_bitmap = 0; + heap->large_free_bitmap = 0; +#if ZEND_MM_CACHE + heap->cached = 0; + memset(heap->cache, 0, sizeof(heap->cache)); +#endif +#if ZEND_MM_CACHE_STAT + for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { + heap->cache_stat[i].count = 0; + } +#endif + p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0); + for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { + p->next_free_block = p; + p->prev_free_block = p; + p = (zend_mm_free_block *)((char *)p + sizeof(zend_mm_free_block *) * 2); + heap->large_free_buckets[i] = NULL; + } + heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap); + heap->rest_count = 0; +} + +static zend_mm_storage* zend_mm_mem_init(void *params) { + TSRMLS_FETCH(); + + return &PHPDBG_G(sigsafe_mem).storage; +} + +static void zend_mm_mem_dummy(zend_mm_storage *storage) { +} + +#define STR(x) #x +#define EXP_STR(x) STR(x) + +static zend_mm_segment* zend_mm_mem_alloc(zend_mm_storage *storage, size_t size) { + TSRMLS_FETCH(); + + if (EXPECTED(size == PHPDBG_SIGSAFE_MEM_SIZE && !PHPDBG_G(sigsafe_mem).allocated)) { + PHPDBG_G(sigsafe_mem).allocated = 1; + return (zend_mm_segment *) PHPDBG_G(sigsafe_mem).mem; + } + + write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Tried to allocate more than " EXP_STR(PHPDBG_SIGSAFE_MEM_SIZE) " bytes from stack memory in signal handler ... bailing out of signal handler\n")); + + if (*EG(bailout)) { + LONGJMP(*EG(bailout), FAILURE); + } + + write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Bailed out without a bailout address in signal handler!\n")); + + return NULL; +} + +static zend_mm_segment* zend_mm_mem_realloc(zend_mm_storage *storage, zend_mm_segment *ptr, size_t size) { + return zend_mm_mem_alloc(storage, size); +} + +static void zend_mm_mem_free(zend_mm_storage *storage, zend_mm_segment *ptr) { +} + +static const zend_mm_mem_handlers phpdbg_handlers_sigsafe_mem = { "stack", zend_mm_mem_init, zend_mm_mem_dummy, zend_mm_mem_dummy, zend_mm_mem_alloc, zend_mm_mem_realloc, zend_mm_mem_free }; + +void phpdbg_set_sigsafe_mem(char *buffer TSRMLS_DC) { + phpdbg_signal_safe_mem *mem = &PHPDBG_G(sigsafe_mem); + mem->old_heap = zend_mm_set_heap(&mem->heap TSRMLS_CC); + mem->mem = buffer; + mem->allocated = 0; + + mem->storage.handlers = &phpdbg_handlers_sigsafe_mem; + mem->heap.storage = &mem->storage; + mem->heap.block_size = PHPDBG_SIGSAFE_MEM_SIZE; + mem->heap.compact_size = 0; + mem->heap.segments_list = NULL; + zend_mm_init(&mem->heap); +#if ZEND_MM_CACHE_STAT + memset(mem->heap.cache_stat, 0, sizeof(mem->heap.cache_stat)); +#endif + mem->heap.use_zend_alloc = 1; + mem->heap.real_size = 0; + mem->heap.overflow = 0; + mem->heap.real_peak = 0; + mem->heap.limit = PHPDBG_SIGSAFE_MEM_SIZE; + mem->heap.size = 0; + mem->heap.peak = 0; + mem->heap.internal = 0; + mem->heap.reserve = NULL; + mem->heap.reserve_size = 0; +} + +void phpdbg_clear_sigsafe_mem(TSRMLS_D) { + PHPDBG_G(sigsafe_mem).mem = NULL; + zend_mm_set_heap(PHPDBG_G(sigsafe_mem).old_heap TSRMLS_CC); +} + +zend_bool phpdbg_active_sigsafe_mem(TSRMLS_D) { + return !!PHPDBG_G(sigsafe_mem).mem; +} + diff --git a/phpdbg_sigsafe.h b/phpdbg_sigsafe.h new file mode 100644 index 00000000000..810e07c789c --- /dev/null +++ b/phpdbg_sigsafe.h @@ -0,0 +1,23 @@ +#ifndef PHPDBG_SIGSAFE_H +#define PHPDBG_SIGSAFE_H + +#include "zend_mm_structs.h" + +#define PHPDBG_SIGSAFE_MEM_SIZE (1 << 20) + +typedef struct { + char *mem; + zend_bool allocated;; + zend_mm_heap heap; + zend_mm_heap *old_heap; + zend_mm_storage storage; +} phpdbg_signal_safe_mem; + +#include "phpdbg.h" + +zend_bool phpdbg_active_sigsafe_mem(TSRMLS_D); + +void phpdbg_set_sigsafe_mem(char *mem TSRMLS_DC); +void phpdbg_clear_sigsafe_mem(TSRMLS_D); + +#endif diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 22a7b562825..4d3eb4cde68 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -224,10 +224,9 @@ PHPDBG_API char *phpdbg_trim(const char *str, size_t len, size_t *new_len) /* {{ } /* }}} */ -PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, ...) /* {{{ */ -{ +PHPDBG_API int phpdbg_print(int type TSRMLS_DC, int fd, const char *format, ...) { /* {{{ */ int rc = 0; - char *buffer = NULL; + char *buffer = NULL, *outbuf = NULL; va_list args; if (format != NULL && strlen(format) > 0L) { @@ -241,44 +240,41 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, .. switch (type) { case P_ERROR: if (!PHPDBG_G(last_was_newline)) { - fprintf(fp, "\n"); + write(fd, "\n", 1); PHPDBG_G(last_was_newline) = 1; } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - rc = fprintf(fp, - "\033[%sm[%s]\033[0m\n", - PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, buffer); + rc = spprintf(&outbuf, 0, "\033[%sm[%s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, buffer); } else { - rc = fprintf(fp, "[%s]\n", buffer); + rc = spprintf(&outbuf, 0, "[%s]\n", buffer); } break; case P_NOTICE: if (!PHPDBG_G(last_was_newline)) { - fprintf(fp, "\n"); + write(fd, "\n", 1); PHPDBG_G(last_was_newline) = 1; } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - rc = fprintf(fp, - "\033[%sm[%s]\033[0m\n", - PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, buffer); + rc = spprintf(&outbuf, 0, "\033[%sm[%s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, buffer); } else { - rc = fprintf(fp, "[%s]\n", buffer); + rc = spprintf(&outbuf, 0, "[%s]\n", buffer); } break; case P_WRITELN: { if (buffer) { - rc = fprintf(fp, "%s\n", buffer); + rc = spprintf(&outbuf, 0, "%s\n", buffer); } else { - rc = fprintf(fp, "\n"); + rc = 1; + outbuf = estrdup("\n"); } PHPDBG_G(last_was_newline) = 1; } break; case P_WRITE: if (buffer) { - rc = fprintf(fp, "%s", buffer); + rc = spprintf(&outbuf, 0, "%s", buffer); PHPDBG_G(last_was_newline) = buffer[strlen(buffer) - 1] == '\n'; } break; @@ -288,7 +284,7 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, .. if (buffer) { struct timeval tp; if (gettimeofday(&tp, NULL) == SUCCESS) { - rc = fprintf(fp, "[%ld %.8F]: %s\n", tp.tv_sec, tp.tv_usec / 1000000.00, buffer); + rc = spprintf(&outbuf, 0, "[%ld %.8F]: %s\n", tp.tv_sec, tp.tv_usec / 1000000.00, buffer); } else { rc = FAILURE; } @@ -296,6 +292,11 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, .. break; } + if (outbuf) { + rc = write(fd, outbuf, rc); + efree(outbuf); + } + if (buffer) { efree(buffer); } @@ -303,7 +304,7 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, .. return rc; } /* }}} */ -PHPDBG_API int phpdbg_rlog(FILE *fp, const char *fmt, ...) { /* {{{ */ +PHPDBG_API int phpdbg_rlog(int fd, const char *fmt, ...) { /* {{{ */ int rc = 0; va_list args; @@ -312,19 +313,21 @@ PHPDBG_API int phpdbg_rlog(FILE *fp, const char *fmt, ...) { /* {{{ */ va_start(args, fmt); if (gettimeofday(&tp, NULL) == SUCCESS) { char friendly[100]; - char *format = NULL, *buffer = NULL; + char *format = NULL, *buffer = NULL, *outbuf = NULL; const time_t tt = tp.tv_sec; strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt)); - asprintf( - &buffer, friendly, tp.tv_usec/1000); - asprintf( - &format, "[%s]: %s\n", buffer, fmt); - rc = vfprintf( - fp, format, args); + spprintf(&buffer, 0, friendly, tp.tv_usec/1000); + spprintf(&format, 0, "[%s]: %s\n", buffer, fmt); + rc = vspprintf(&outbuf, 0, format, args); - free(format); - free(buffer); + if (outbuf) { + rc = write(fd, outbuf, rc); + efree(outbuf); + } + + efree(format); + efree(buffer); } va_end(args); @@ -463,3 +466,12 @@ PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D) /* {{{ */ #endif return columns; } /* }}} */ + +PHPDBG_API void phpdbg_set_async_io(int fd) { +#ifndef _WIN32 + int flags; + fcntl(STDIN_FILENO, F_SETOWN, getpid()); + flags = fcntl(STDIN_FILENO, F_GETFL); + fcntl(STDIN_FILENO, F_SETFL, flags | FASYNC); +#endif +} diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 56bacfc4596..9686d769480 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -45,18 +45,18 @@ enum { }; #ifdef ZTS -PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUTE_FORMAT(printf, 4, 5); +PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 4, 5); #else -PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); #endif -PHPDBG_API int phpdbg_rlog(FILE *stream, const char *fmt, ...); +PHPDBG_API int phpdbg_rlog(int fd, const char *fmt, ...); -#define phpdbg_error(fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) -#define phpdbg_notice(fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) -#define phpdbg_writeln(fmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) -#define phpdbg_write(fmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) -#define phpdbg_log(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) +#define phpdbg_error(fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, fmt, ##__VA_ARGS__) +#define phpdbg_notice(fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, fmt, ##__VA_ARGS__) +#define phpdbg_writeln(fmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, fmt, ##__VA_ARGS__) +#define phpdbg_write(fmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, fmt, ##__VA_ARGS__) +#define phpdbg_log(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, fmt, ##__VA_ARGS__) #define phpdbg_error_ex(out, fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, out, fmt, ##__VA_ARGS__) #define phpdbg_notice_ex(out, fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, out, fmt, ##__VA_ARGS__) @@ -65,7 +65,7 @@ PHPDBG_API int phpdbg_rlog(FILE *stream, const char *fmt, ...); #define phpdbg_log_ex(out, fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, out, fmt, ##__VA_ARGS__) #if PHPDBG_DEBUG -# define phpdbg_debug(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDERR], fmt, ##__VA_ARGS__) +# define phpdbg_debug(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDERR].fd, fmt, ##__VA_ARGS__) #else # define phpdbg_debug(fmt, ...) #endif @@ -122,6 +122,8 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D); /* }}} */ /* {{{ Console Width */ PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D); /* }}} */ +PHPDBG_API void phpdbg_set_async_io(int fd); + int phpdbg_rebuild_symtable(TSRMLS_D); #if PHP_VERSION_ID < 50500 diff --git a/zend_mm_structs.h b/zend_mm_structs.h new file mode 100644 index 00000000000..ca64069e0f8 --- /dev/null +++ b/zend_mm_structs.h @@ -0,0 +1,102 @@ +#ifndef ZEND_MM_STRUCTS_H +#define ZEND_MM_STRUCTS_H + +/* structs and macros defined in Zend/zend_alloc.c + Needed for realizing watchpoints and sigsafe memory */ + +#include "zend.h" + +#ifndef ZEND_MM_COOKIES +# define ZEND_MM_COOKIES ZEND_DEBUG +#endif + +#define ZEND_MM_CACHE 1 +#ifndef ZEND_MM_CACHE_STAT +# define ZEND_MM_CACHE_STAT 0 +#endif + +typedef struct _zend_mm_block_info { +#if ZEND_MM_COOKIES + size_t _cookie; +#endif + size_t _size; + size_t _prev; +} zend_mm_block_info; + +typedef struct _zend_mm_small_free_block { + zend_mm_block_info info; +#if ZEND_DEBUG + unsigned int magic; +#ifdef ZTS + THREAD_T thread_id; +#endif +#endif + struct _zend_mm_free_block *prev_free_block; + struct _zend_mm_free_block *next_free_block; +} zend_mm_small_free_block; + +typedef struct _zend_mm_free_block { + zend_mm_block_info info; +#if ZEND_DEBUG + unsigned int magic; +#ifdef ZTS + THREAD_T thread_id; +#endif +#endif + struct _zend_mm_free_block *prev_free_block; + struct _zend_mm_free_block *next_free_block; + + struct _zend_mm_free_block **parent; + struct _zend_mm_free_block *child[2]; +} zend_mm_free_block; + +#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \ + (zend_mm_free_block *) ((char *)&heap->free_buckets[index * 2] + \ + sizeof(zend_mm_free_block *) * 2 - \ + sizeof(zend_mm_small_free_block)) + +#define ZEND_MM_REST_BUCKET(heap) \ + (zend_mm_free_block *)((char *)&heap->rest_buckets[0] + \ + sizeof(zend_mm_free_block *) * 2 - \ + sizeof(zend_mm_small_free_block)) + +#define ZEND_MM_NUM_BUCKETS (sizeof(size_t) << 3) +struct _zend_mm_heap { + int use_zend_alloc; + void *(*_malloc)(size_t); + void (*_free)(void *); + void *(*_realloc)(void *, size_t); + size_t free_bitmap; + size_t large_free_bitmap; + size_t block_size; + size_t compact_size; + zend_mm_segment *segments_list; + zend_mm_storage *storage; + size_t real_size; + size_t real_peak; + size_t limit; + size_t size; + size_t peak; + size_t reserve_size; + void *reserve; + int overflow; + int internal; +#if ZEND_MM_CACHE + unsigned int cached; + zend_mm_free_block *cache[ZEND_MM_NUM_BUCKETS]; +#endif + zend_mm_free_block *free_buckets[ZEND_MM_NUM_BUCKETS*2]; + zend_mm_free_block *large_free_buckets[ZEND_MM_NUM_BUCKETS]; + zend_mm_free_block *rest_buckets[2]; + int rest_count; +#if ZEND_MM_CACHE_STAT + struct { + int count; + int max_count; + int hit; + int miss; + } cache_stat[ZEND_MM_NUM_BUCKETS+1]; +#endif +}; + +#endif From 7911b6405c0b1e646509a68760c0929ec811e4c5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 2 Oct 2014 11:18:36 +0200 Subject: [PATCH 023/125] Remove accidental insertion of a single "s" --- phpdbg_prompt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 4eed3864761..3f5d5afdd6c 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -674,7 +674,7 @@ PHPDBG_COMMAND(ev) /* {{{ */ PHPDBG_COMMAND(back) /* {{{ */ { if (!EG(in_execution)) { -s phpdbg_error("inactive", "type=\"noexec\"", "Not executing!"); + phpdbg_error("inactive", "type=\"noexec\"", "Not executing!"); return SUCCESS; } From 8af0870d727bf4030923aff3a13dfc7e3ceaaec5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 3 Oct 2014 01:29:41 +0200 Subject: [PATCH 024/125] Made some functions async safe and provide interactive shell in signal handler Fixes also (as a side-effect) a possible bug in list function when included files become unreachable after loading by caching the file contents This is already pretty stable; a (restricted) ev and sh may follow. --- phpdbg.c | 23 ++++- phpdbg.h | 26 +++++- phpdbg_break.c | 8 +- phpdbg_cmd.c | 129 +++++++++++++------------- phpdbg_cmd.h | 23 +++-- phpdbg_frame.c | 65 +++++++------ phpdbg_info.c | 231 +++++++++++++++++++++++++++-------------------- phpdbg_list.c | 164 +++++++++++++++++++++------------ phpdbg_list.h | 15 ++- phpdbg_print.c | 46 +++++----- phpdbg_prompt.c | 149 +++++++++++++++--------------- phpdbg_prompt.h | 8 +- phpdbg_set.c | 22 ++--- phpdbg_sigsafe.c | 6 +- phpdbg_sigsafe.h | 4 +- phpdbg_utils.c | 31 +++++++ phpdbg_utils.h | 2 + phpdbg_watch.h | 6 +- 18 files changed, 577 insertions(+), 381 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index a72ddbb1839..15647f2c58b 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -74,6 +74,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->frame.num = 0; pg->input_buflen = 0; pg->sigsafe_mem.mem = NULL; + pg->sigsegv_bailout = NULL; } /* }}} */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ @@ -181,6 +182,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]); zend_hash_destroy(&PHPDBG_G(seek)); zend_hash_destroy(&PHPDBG_G(registered)); + zend_hash_destroy(&PHPDBG_G(file_sources)); zend_hash_destroy(&PHPDBG_G(watchpoints)); zend_llist_destroy(&PHPDBG_G(watchlist_mem)); @@ -188,7 +190,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ efree(PHPDBG_G(buffer)); PHPDBG_G(buffer) = NULL; } - + if (PHPDBG_G(exec)) { efree(PHPDBG_G(exec)); PHPDBG_G(exec) = NULL; @@ -448,7 +450,7 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */ } do { - switch (phpdbg_interactive(TSRMLS_C)) { + switch (phpdbg_interactive(1 TSRMLS_CC)) { case PHPDBG_LEAVE: case PHPDBG_FINISH: case PHPDBG_UNTIL: @@ -817,7 +819,7 @@ void phpdbg_sigio_handler(int sig, siginfo_t *info, void *context) /* {{{ */ { int flags; size_t newlen; - size_t i; + size_t i/*, last_nl*/; TSRMLS_FETCH(); // if (!(info->si_band & POLLIN)) { @@ -853,7 +855,11 @@ void phpdbg_sigio_handler(int sig, siginfo_t *info, void *context) /* {{{ */ PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED; } break; - } +/* case '\n': + zend_llist_add_element(PHPDBG_G(stdin), strndup() + last_nl = PHPDBG_G(stdin_buf).len + i; + break; +*/ } } off += i; } while (0); @@ -870,6 +876,9 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */ switch (sig) { case SIGBUS: case SIGSEGV: + if (PHPDBG_G(sigsegv_bailout)) { + LONGJMP(*PHPDBG_G(sigsegv_bailout), FAILURE); + } is_handled = phpdbg_watchpoint_segfault_handler(info, context TSRMLS_CC); if (is_handled == FAILURE) { #ifdef ZEND_SIGNALS @@ -1255,6 +1264,8 @@ phpdbg_main: zend_activate(TSRMLS_C); + phpdbg_init_list(TSRMLS_C); + PHPDBG_G(original_free_function) = mm_heap->_free; mm_heap->_free = phpdbg_watch_efree; @@ -1291,6 +1302,8 @@ phpdbg_main: php_output_activate(TSRMLS_C); php_output_deactivate(TSRMLS_C); + php_output_activate(TSRMLS_C); + /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ #ifndef _WIN32 @@ -1397,7 +1410,7 @@ phpdbg_interact: /* phpdbg main() */ do { zend_try { - phpdbg_interactive(TSRMLS_C); + phpdbg_interactive(1 TSRMLS_CC); } zend_catch { if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) { FILE *bp_tmp_fp = fopen(bp_tmp_file, "w"); diff --git a/phpdbg.h b/phpdbg.h index 105614c8691..941b539d118 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2014 The PHP Group | + | Copyright (c) 7-4 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 | @@ -149,8 +149,10 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); #define PHPDBG_SHOW_REFCOUNTS (1<<29) +#define PHPDBG_IN_SIGNAL_HANDLER (1<<30) + #define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE) -#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) +#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) #define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP|PHPDBG_HAS_SYM_BP|PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_OPLINE_BP|PHPDBG_HAS_COND_BP|PHPDBG_HAS_OPCODE_BP|PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) #ifndef _WIN32 @@ -174,6 +176,21 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); #define PHPDBG_STDERR 2 #define PHPDBG_IO_FDS 3 /* }}} */ +#define phpdbg_try_access \ + { \ + JMP_BUF *__orig_bailout = PHPDBG_G(sigsegv_bailout); \ + JMP_BUF __bailout; \ + \ + PHPDBG_G(sigsegv_bailout) = &__bailout; \ + if (SETJMP(__bailout) == 0) { +#define phpdbg_catch_access \ + } else { \ + PHPDBG_G(sigsegv_bailout) = __orig_bailout; +#define phpdbg_end_try_access() \ + } \ + PHPDBG_G(sigsegv_bailout) = __orig_bailout; \ + } + /* {{{ structs */ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) @@ -203,6 +220,9 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) int bp_count; /* breakpoint count */ int vmret; /* return from last opcode handler execution */ + zend_op_array *(*compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); + HashTable file_sources; + FILE *oplog; /* opline log */ struct { FILE *ptr; @@ -218,6 +238,8 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) int input_buflen; /* length of stdin input buffer */ phpdbg_signal_safe_mem sigsafe_mem; /* memory to use in async safe environment (only once!) */ + JMP_BUF *sigsegv_bailout; /* bailout address for accesibility probing */ + zend_ulong flags; /* phpdbg flags */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ diff --git a/phpdbg_break.c b/phpdbg_break.c index be76b22b059..386d4d95620 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -28,15 +28,15 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -#define PHPDBG_BREAK_COMMAND_D(f, h, a, m, l, s) \ - PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[10]) +#define PHPDBG_BREAK_COMMAND_D(f, h, a, m, l, s, flags) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[10], flags) /** * Commands */ const phpdbg_command_t phpdbg_break_commands[] = { - PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", '@', break_at, NULL, "*c"), - PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", '~', break_del, NULL, "n"), + PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", '@', break_at, NULL, "*c", 0), + PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", '~', break_del, NULL, "n", 0), PHPDBG_END_COMMAND }; diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 0ea6c121271..e9811dc43b9 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -644,9 +644,9 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * phpdbg_param_t *name = *top; const phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; ulong matches = 0L; - + while (command && command->name && command->handler) { - if ((name->len == 1) || (command->name_len >= name->len)) { + if (name->len == 1 || command->name_len >= name->len) { /* match single letter alias */ if (command->alias && (name->len == 1)) { if (command->alias == (*name->str)) { @@ -654,81 +654,72 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * matches++; } } else { - /* match full, case insensitive, command name */ if (strncasecmp(command->name, name->str, name->len) == SUCCESS) { if (matches < 3) { - /* only allow abbreviating commands that can be aliased */ if (((name->len != command->name_len) && command->alias) || (name->len == command->name_len)) { matched[matches] = command; matches++; } - - + /* exact match */ - if (name->len == command->name_len) + if (name->len == command->name_len) { break; - } else break; + } + } else { + break; + } } } } - + command++; } - + switch (matches) { - case 0: { + case 0: if (parent) { - asprintf( - why, - "The command \"%s %s\" could not be found", - parent->name, name->str); - } else asprintf( - why, - "The command \"%s\" could not be found", - name->str); - } return parent; - - case 1: { + spprintf(why, 0, "The command \"%s %s\" could not be found", parent->name, name->str); + } else { + spprintf(why, 0, "The command \"%s\" could not be found", name->str); + } + return parent; + + case 1: (*top) = (*top)->next; command = matched[0]; - } break; - + break; + default: { char *list = NULL; zend_uint it = 0; size_t pos = 0; - + while (it < matches) { if (!list) { - list = malloc( - matched[it]->name_len + 1 + - ((it+1) < matches ? sizeof(", ")-1 : 0)); + list = emalloc(matched[it]->name_len + 1 + (it + 1 < matches ? sizeof(", ") - 1 : 0)); } else { - list = realloc(list, - (pos + matched[it]->name_len) + 1 + - ((it+1) < matches ? sizeof(", ")-1 : 0)); + list = erealloc(list, (pos + matched[it]->name_len) + 1 + (it + 1 < matches ? sizeof(", ") - 1 : 0)); } memcpy(&list[pos], matched[it]->name, matched[it]->name_len); pos += matched[it]->name_len; - if ((it+1) < matches) { - memcpy(&list[pos], ", ", sizeof(", ")-1); + if ((it + 1) < matches) { + memcpy(&list[pos], ", ", sizeof(", ") - 1); pos += (sizeof(", ") - 1); } - + list[pos] = 0; it++; } - - asprintf( - why, - "The command \"%s\" is ambigious, matching %lu commands (%s)", - name->str, matches, list); - free(list); - } return NULL; + + spprintf(why, 0, "The command \"%s\" is ambigious, matching %lu commands (%s)", name->str, matches, list); + efree(list); + + return NULL; + } } if (command->subs && (*top) && ((*top)->type == STR_PARAM)) { @@ -741,51 +732,64 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * } /* }}} */ /* {{{ */ -PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC) { +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why, zend_bool allow_async_unsafe TSRMLS_DC) { phpdbg_param_t *top = NULL; const phpdbg_command_t *handler = NULL; - + if (stack->type != STACK_PARAM) { - asprintf( - why, "The passed argument was not a stack !!"); + spprintf(why, 0, "The passed argument was not a stack !!"); return FAILURE; } - + if (!stack->len) { - asprintf( - why, "The stack contains nothing !!"); + spprintf(why, 0, "The stack contains nothing !!"); return FAILURE; } - + top = (phpdbg_param_t*) stack->next; - + switch (top->type) { case EVAL_PARAM: - return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); + if (allow_async_unsafe) { + return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); + } + spprintf(why, 0, "ev command is disallowed during hard interrupt"); + return FAILURE; case RUN_PARAM: - return PHPDBG_COMMAND_HANDLER(run)(top TSRMLS_CC); - + if (allow_async_unsafe) { + return PHPDBG_COMMAND_HANDLER(run)(top TSRMLS_CC); + } + spprintf(why, 0, "run command is disallowed during hard interrupt"); + return FAILURE; + case SHELL_PARAM: - return PHPDBG_COMMAND_HANDLER(sh)(top TSRMLS_CC); - + if (allow_async_unsafe) { + return PHPDBG_COMMAND_HANDLER(sh)(top TSRMLS_CC); + } + spprintf(why, 0, "sh command is disallowed during hard interrupt"); + return FAILURE; + case STR_PARAM: { - handler = phpdbg_stack_resolve( - phpdbg_prompt_commands, NULL, &top, why); - + handler = phpdbg_stack_resolve(phpdbg_prompt_commands, NULL, &top, why); + if (handler) { + if (!allow_async_unsafe && !(handler->flags & PHPDBG_ASYNC_SAFE)) { + spprintf(why, 0, "%s command is disallowed during hard interrupt", handler->name); + return FAILURE; + } + if (phpdbg_stack_verify(handler, &top, why TSRMLS_CC) == SUCCESS) { return handler->handler(top TSRMLS_CC); } } } return FAILURE; - + default: - asprintf( - why, "The first parameter makes no sense !!"); + spprintf(why, 0, "The first parameter makes no sense !!"); return FAILURE; } - + return SUCCESS; } /* }}} */ @@ -909,4 +913,3 @@ PHPDBG_API void phpdbg_destroy_input(char **input TSRMLS_DC) /*{{{ */ { efree(*input); } /* }}} */ - diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 571d065f59d..45f15791864 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -86,6 +86,8 @@ struct _phpdbg_param { #define YYSTYPE phpdbg_param_t #endif +#define PHPDBG_ASYNC_SAFE 1 + typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t* TSRMLS_DC); typedef struct _phpdbg_command_t phpdbg_command_t; @@ -97,8 +99,9 @@ struct _phpdbg_command_t { char alias; /* Alias */ phpdbg_command_handler_t handler; /* Command handler */ const phpdbg_command_t *subs; /* Sub Commands */ - char *args; /* Argument Spec */ - const phpdbg_command_t *parent; /* Parent Command */ + char *args; /* Argument Spec */ + const phpdbg_command_t *parent; /* Parent Command */ + zend_bool flags; /* General flags */ }; /* }}} */ @@ -135,7 +138,7 @@ PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param); PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why); PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC); -PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC); +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why, zend_bool allow_async_unsafe TSRMLS_DC); PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack); /* @@ -155,20 +158,20 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) */ #define PHPDBG_COMMAND_HANDLER(name) phpdbg_do_##name -#define PHPDBG_COMMAND_D_EXP(name, tip, alias, handler, children, args, parent) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, parent} +#define PHPDBG_COMMAND_D_EXP(name, tip, alias, handler, children, args, parent, flags) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, parent, flags} -#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, NULL} +#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args, flags) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, NULL, flags} -#define PHPDBG_COMMAND_D(name, tip, alias, children, args) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args, NULL} +#define PHPDBG_COMMAND_D(name, tip, alias, children, args, flags) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args, NULL, flags} #define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param TSRMLS_DC) #define PHPDBG_COMMAND_ARGS param TSRMLS_CC -#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', NULL} +#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', NULL, 0} /* * Default Switch Case diff --git a/phpdbg_frame.c b/phpdbg_frame.c index a235fe8cb04..62b3a66febf 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -56,15 +56,20 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ return; } - while (execute_data) { - if (i++ == frame) { - break; - } + phpdbg_try_access { + while (execute_data) { + if (i++ == frame) { + break; + } - do { - execute_data = execute_data->prev_execute_data; - } while (execute_data && execute_data->opline == NULL); - } + do { + execute_data = execute_data->prev_execute_data; + } while (execute_data && execute_data->opline == NULL); + } + } phpdbg_catch_access { + phpdbg_error("Couldn't switch frames, invalid data source"); + return; + } phpdbg_end_try_access(); if (execute_data == NULL) { phpdbg_error("No frame #%d", frame); @@ -105,16 +110,12 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ zval **funcname, **class, **type, **args, **argstmp; char is_class; - zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), - (void **)&funcname); + zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), (void **) &funcname); - if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp), - "object", sizeof("object"), (void **)&class)) == FAILURE) { - is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"), - (void **)&class); + if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "object", sizeof("object"), (void **) &class)) == FAILURE) { + is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"), (void **)&class); } else { - zend_get_object_classname(*class, (const char **)&Z_STRVAL_PP(class), - (zend_uint *)&Z_STRLEN_PP(class) TSRMLS_CC); + zend_get_object_classname(*class, (const char **) &Z_STRVAL_PP(class), (zend_uint *) &Z_STRLEN_PP(class) TSRMLS_CC); } if (is_class == SUCCESS) { @@ -127,18 +128,22 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ Z_STRVAL_PP(funcname) ); - if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), - (void **)&args) == SUCCESS) { + if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), (void **) &args) == SUCCESS) { HashPosition iterator; - const zend_function *func = phpdbg_get_function( - Z_STRVAL_PP(funcname), is_class == FAILURE ? NULL : Z_STRVAL_PP(class) TSRMLS_CC); - const zend_arg_info *arginfo = func ? func->common.arg_info : NULL; + const zend_function *func; + const zend_arg_info *arginfo = NULL; int j = 0, m = func ? func->common.num_args : 0; zend_bool is_variadic = 0; + phpdbg_try_access { + /* assuming no autoloader call is necessary, class should have been loaded if it's in backtrace ... */ + if ((func = phpdbg_get_function(Z_STRVAL_PP(funcname), is_class == FAILURE ? NULL : Z_STRVAL_PP(class) TSRMLS_CC))) { + arginfo = func->common.arg_info; + } + } phpdbg_end_try_access(); + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); - while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), - (void **) &argstmp, &iterator) == SUCCESS) { + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { if (j) { phpdbg_write(", "); } @@ -174,8 +179,15 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ phpdbg_error("Invalid backtrace size %d", limit); } - zend_fetch_debug_backtrace( - &zbacktrace, 0, 0, limit TSRMLS_CC); + phpdbg_try_access { + zend_fetch_debug_backtrace(&zbacktrace, 0, 0, limit TSRMLS_CC); + } phpdbg_catch_access { + phpdbg_try_access { + zval_dtor(&zbacktrace); + } phpdbg_end_try_access(); + phpdbg_error("Couldn't fetch backtrace, invalid data source"); + return; + } phpdbg_end_try_access(); zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position); zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position); @@ -184,8 +196,7 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ zend_hash_find(Z_ARRVAL_PP(tmp), "line", sizeof("line"), (void **)&line); zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position); - if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), - (void**)&tmp, &position) == FAILURE) { + if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position) == FAILURE) { phpdbg_write("frame #%d: {main} at %s:%ld", i, Z_STRVAL_PP(file), Z_LVAL_PP(line)); break; } diff --git a/phpdbg_info.c b/phpdbg_info.c index a783bf44fcd..8d4bc530dba 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -27,19 +27,19 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -#define PHPDBG_INFO_COMMAND_D(f, h, a, m, l, s) \ - PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[14]) +#define PHPDBG_INFO_COMMAND_D(f, h, a, m, l, s, flags) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[14], flags) const phpdbg_command_t phpdbg_info_commands[] = { - PHPDBG_INFO_COMMAND_D(break, "show breakpoints", 'b', info_break, NULL, 0), - PHPDBG_INFO_COMMAND_D(files, "show included files", 'F', info_files, NULL, 0), - PHPDBG_INFO_COMMAND_D(classes, "show loaded classes", 'c', info_classes, NULL, 0), - PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0), - PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0), - PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0), - PHPDBG_INFO_COMMAND_D(globals, "show superglobals", 'g', info_globals, NULL, 0), - PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0), - PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0), + PHPDBG_INFO_COMMAND_D(break, "show breakpoints", 'b', info_break, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(files, "show included files", 'F', info_files, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(classes, "show loaded classes", 'c', info_classes, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(globals, "show superglobals", 'g', info_globals, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0, PHPDBG_ASYNC_SAFE), PHPDBG_END_COMMAND }; @@ -63,15 +63,21 @@ PHPDBG_INFO(files) /* {{{ */ HashPosition pos; char *fname; - phpdbg_notice("Included files: %d", - zend_hash_num_elements(&EG(included_files))); + phpdbg_try_access { + phpdbg_notice("Included files: %d", zend_hash_num_elements(&EG(included_files))); + } phpdbg_catch_access { + phpdbg_error("Could not fetch included file count, invalid data source"); + } phpdbg_end_try_access(); - zend_hash_internal_pointer_reset_ex(&EG(included_files), &pos); - while (zend_hash_get_current_key_ex(&EG(included_files), &fname, - NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { - phpdbg_writeln("File: %s", fname); - zend_hash_move_forward_ex(&EG(included_files), &pos); - } + phpdbg_try_access { + zend_hash_internal_pointer_reset_ex(&EG(included_files), &pos); + while (zend_hash_get_current_key_ex(&EG(included_files), &fname, NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { + phpdbg_writeln("File: %s", fname); + zend_hash_move_forward_ex(&EG(included_files), &pos); + } + } phpdbg_catch_access { + phpdbg_error("Could not fetch file name, invalid data source, aborting included file listing"); + } phpdbg_end_try_access(); return SUCCESS; } /* }}} */ @@ -79,8 +85,11 @@ PHPDBG_INFO(files) /* {{{ */ PHPDBG_INFO(error) /* {{{ */ { if (PG(last_error_message)) { - phpdbg_writeln("Last error: %s at %s line %d", - PG(last_error_message), PG(last_error_file), PG(last_error_lineno)); + phpdbg_try_access { + phpdbg_writeln("Last error: %s at %s line %d", PG(last_error_message), PG(last_error_file), PG(last_error_lineno)); + } phpdbg_catch_access { + phpdbg_notice("No error found!"); + } phpdbg_end_try_access(); } else { phpdbg_notice("No error found!"); } @@ -89,7 +98,11 @@ PHPDBG_INFO(error) /* {{{ */ static int phpdbg_arm_auto_global(zend_auto_global *auto_global TSRMLS_DC) { if (auto_global->armed) { - auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC); + if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { + phpdbg_notice("Cannot show information about superglobal variable %.*s", auto_global->name_len, auto_global->name); + } else { + auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC); + } } return 0; @@ -117,6 +130,7 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { if (show_globals) { + /* that array should only be manipulated during init, so safe for async access during execution */ zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_arm_auto_global TSRMLS_CC); symtable = &EG(symbol_table); } else { @@ -125,15 +139,18 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { zend_hash_init(&vars, 8, NULL, NULL, 0); - zend_hash_internal_pointer_reset_ex(symtable, &pos); - while (zend_hash_get_current_key_ex(symtable, &var, - NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { - zend_hash_get_current_data_ex(symtable, (void **)&data, &pos); - if (zend_is_auto_global(var, strlen(var) TSRMLS_CC) ^ !show_globals) { - zend_hash_update(&vars, var, strlen(var)+1, (void**)data, sizeof(zval*), NULL); + phpdbg_try_access { + zend_hash_internal_pointer_reset_ex(symtable, &pos); + while (zend_hash_get_current_key_ex(symtable, &var, NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { + zend_hash_get_current_data_ex(symtable, (void **)&data, &pos); + if (zend_is_auto_global(var, strlen(var) TSRMLS_CC) ^ !show_globals) { + zend_hash_update(&vars, var, strlen(var)+1, (void**)data, sizeof(zval*), NULL); + } + zend_hash_move_forward_ex(symtable, &pos); } - zend_hash_move_forward_ex(symtable, &pos); - } + } phpdbg_catch_access { + phpdbg_error("Cannot fetch all data from the symbol table, invalid data source"); + } phpdbg_end_try_access(); if (show_globals) { phpdbg_notice("Superglobal variables (%d)", zend_hash_num_elements(&vars)); @@ -165,54 +182,51 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS; zend_hash_move_forward_ex(&vars, &pos)) { char *var; + zend_bool invalid_data = 1; zend_hash_get_current_key_ex(&vars, &var, NULL, NULL, 0, &pos); - if (*data) { - phpdbg_write( - "%p\t%d\t", - *data, - Z_REFCOUNT_PP(data)); + phpdbg_try_access { + if (!(invalid_data = !*data)) { + phpdbg_write("%p\t%d\t", *data, Z_REFCOUNT_PP(data)); - switch (Z_TYPE_PP(data)) { - case IS_STRING: phpdbg_write("(string)\t"); break; - case IS_LONG: phpdbg_write("(integer)\t"); break; - case IS_DOUBLE: phpdbg_write("(float)\t"); break; - case IS_RESOURCE: phpdbg_write("(resource)\t"); break; - case IS_ARRAY: phpdbg_write("(array)\t"); break; - case IS_OBJECT: phpdbg_write("(object)\t"); break; - case IS_NULL: phpdbg_write("(null)\t"); break; - } - - if (Z_TYPE_PP(data) == IS_RESOURCE) { - int type; - - phpdbg_writeln( - "%s$%s", Z_ISREF_PP(data) ? "&": "", var); - if (zend_list_find(Z_RESVAL_PP(data), &type)) { - phpdbg_write( - "|-------(typeof)------> (%s)", - zend_rsrc_list_get_rsrc_type(type TSRMLS_CC)); - } else { - phpdbg_write( - "|-------(typeof)------> (unknown)"); + switch (Z_TYPE_PP(data)) { + case IS_STRING: phpdbg_write("(string)\t"); break; + case IS_LONG: phpdbg_write("(integer)\t"); break; + case IS_DOUBLE: phpdbg_write("(float)\t"); break; + case IS_RESOURCE: phpdbg_write("(resource)\t"); break; + case IS_ARRAY: phpdbg_write("(array)\t"); break; + case IS_OBJECT: phpdbg_write("(object)\t"); break; + case IS_NULL: phpdbg_write("(null)\t"); break; + } + + phpdbg_writeln("%s$%s", Z_ISREF_PP(data) ? "&": "", var); + + if (Z_TYPE_PP(data) == IS_RESOURCE) { + int type; + + phpdbg_try_access { + if (zend_list_find(Z_RESVAL_PP(data), &type)) { + phpdbg_writeln("|-------(typeof)------> (%s)", zend_rsrc_list_get_rsrc_type(type TSRMLS_CC)); + } else { + phpdbg_writeln("|-------(typeof)------> (unknown)"); + } + } phpdbg_catch_access { + phpdbg_writeln("|-------(typeof)------> (unknown)"); + } phpdbg_end_try_access(); + } else if (Z_TYPE_PP(data) == IS_OBJECT) { + phpdbg_try_access { + phpdbg_writeln("|-----(instanceof)----> (%s)", Z_OBJCE_PP(data)->name); + } phpdbg_catch_access { + phpdbg_writeln("|-----(instanceof)----> (unknown)"); + } phpdbg_end_try_access(); } - phpdbg_writeln(EMPTY); - } else if (Z_TYPE_PP(data) == IS_OBJECT) { - phpdbg_writeln( - "%s$%s", Z_ISREF_PP(data) ? "&": "", var); - phpdbg_write( - "|-----(instanceof)----> (%s)", Z_OBJCE_PP(data)->name); - phpdbg_writeln(EMPTY); - } else { - phpdbg_write( - "%s$%s", Z_ISREF_PP(data) ? "&": "", var); } - } else { - phpdbg_write( - "n/a\tn/a\tn/a\t$%s", var); + } phpdbg_end_try_access(); + + if (invalid_data) { + phpdbg_writeln("n/a\tn/a\tn/a\t$%s", var); } - phpdbg_writeln(EMPTY); } } @@ -233,6 +247,7 @@ PHPDBG_INFO(globals) /* {{{ */ PHPDBG_INFO(literal) /* {{{ */ { + /* literals are assumed to not be manipulated during executing of their op_array and as such async safe */ if ((EG(in_execution) && EG(active_op_array)) || PHPDBG_G(ops)) { zend_op_array *ops = EG(active_op_array) ? EG(active_op_array) : PHPDBG_G(ops); int literal = 0, count = ops->last_literal-1; @@ -258,8 +273,7 @@ PHPDBG_INFO(literal) /* {{{ */ while (literal < ops->last_literal) { if (Z_TYPE(ops->literals[literal].constant) != IS_NULL) { phpdbg_write("|-------- C%u -------> [", literal); - zend_print_zval( - &ops->literals[literal].constant, 0); + zend_print_zval(&ops->literals[literal].constant, 0); phpdbg_write("]"); phpdbg_writeln(EMPTY); } @@ -274,18 +288,31 @@ PHPDBG_INFO(literal) /* {{{ */ PHPDBG_INFO(memory) /* {{{ */ { - if (is_zend_mm(TSRMLS_C)) { + size_t used, real, peak_used, peak_real; + zend_mm_heap *heap; + zend_bool is_mm; + + if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { + heap = zend_mm_set_heap(phpdbg_original_heap_sigsafe_mem(TSRMLS_C) TSRMLS_CC); + } + if ((is_mm = is_zend_mm(TSRMLS_C))) { + used = zend_memory_usage(0 TSRMLS_CC); + real = zend_memory_usage(1 TSRMLS_CC); + peak_used = zend_memory_peak_usage(0 TSRMLS_CC); + peak_real = zend_memory_peak_usage(1 TSRMLS_CC); + } + if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { + zend_mm_set_heap(heap TSRMLS_CC); + } + + if (is_mm) { phpdbg_notice("Memory Manager Information"); phpdbg_notice("Current"); - phpdbg_writeln("|-------> Used:\t%.3f kB", - (float) (zend_memory_usage(0 TSRMLS_CC)/1024)); - phpdbg_writeln("|-------> Real:\t%.3f kB", - (float) (zend_memory_usage(1 TSRMLS_CC)/1024)); + phpdbg_writeln("|-------> Used:\t%.3f kB", (float) (used / 1024)); + phpdbg_writeln("|-------> Real:\t%.3f kB", (float) (real / 1024)); phpdbg_notice("Peak"); - phpdbg_writeln("|-------> Used:\t%.3f kB", - (float) (zend_memory_peak_usage(0 TSRMLS_CC)/1024)); - phpdbg_writeln("|-------> Real:\t%.3f kB", - (float) (zend_memory_peak_usage(1 TSRMLS_CC)/1024)); + phpdbg_writeln("|-------> Used:\t%.3f kB", (float) (peak_used / 1024)); + phpdbg_writeln("|-------> Real:\t%.3f kB", (float) (peak_real / 1024)); } else { phpdbg_error("Memory Manager Disabled!"); } @@ -314,19 +341,21 @@ PHPDBG_INFO(classes) /* {{{ */ zend_hash_init(&classes, 8, NULL, NULL, 0); - for (zend_hash_internal_pointer_reset_ex(EG(class_table), &position); - zend_hash_get_current_data_ex(EG(class_table), (void**)&ce, &position) == SUCCESS; - zend_hash_move_forward_ex(EG(class_table), &position)) { - - if ((*ce)->type == ZEND_USER_CLASS) { - zend_hash_next_index_insert( - &classes, ce, sizeof(ce), NULL); + phpdbg_try_access { + for (zend_hash_internal_pointer_reset_ex(EG(class_table), &position); + zend_hash_get_current_data_ex(EG(class_table), (void**)&ce, &position) == SUCCESS; + zend_hash_move_forward_ex(EG(class_table), &position)) { + if ((*ce)->type == ZEND_USER_CLASS) { + zend_hash_next_index_insert(&classes, ce, sizeof(ce), NULL); + } } - } + } phpdbg_catch_access { + phpdbg_notice("Not all classes could be fetched, possibly invalid data source"); + } phpdbg_end_try_access(); - phpdbg_notice("User Classes (%d)", - zend_hash_num_elements(&classes)); + phpdbg_notice("User Classes (%d)", zend_hash_num_elements(&classes)); + /* once added, assume that classes are stable... until shutdown. */ for (zend_hash_internal_pointer_reset_ex(&classes, &position); zend_hash_get_current_data_ex(&classes, (void**)&ce, &position) == SUCCESS; zend_hash_move_forward_ex(&classes, &position)) { @@ -367,15 +396,17 @@ PHPDBG_INFO(funcs) /* {{{ */ zend_hash_init(&functions, 8, NULL, NULL, 0); - for (zend_hash_internal_pointer_reset_ex(EG(function_table), &position); - zend_hash_get_current_data_ex(EG(function_table), (void**)&zf, &position) == SUCCESS; - zend_hash_move_forward_ex(EG(function_table), &position)) { - - if (zf->type == ZEND_USER_FUNCTION) { - zend_hash_next_index_insert( - &functions, (void**) &zf, sizeof(zend_function), NULL); + phpdbg_try_access { + for (zend_hash_internal_pointer_reset_ex(EG(function_table), &position); + zend_hash_get_current_data_ex(EG(function_table), (void**)&zf, &position) == SUCCESS; + zend_hash_move_forward_ex(EG(function_table), &position)) { + if (zf->type == ZEND_USER_FUNCTION) { + zend_hash_next_index_insert(&functions, (void**) &zf, sizeof(zend_function), NULL); + } } - } + } phpdbg_catch_access { + phpdbg_notice("Not all functions could be fetched, possibly invalid data source"); + } phpdbg_end_try_access(); phpdbg_notice("User Functions (%d)", zend_hash_num_elements(&functions)); diff --git a/phpdbg_list.c b/phpdbg_list.c index e8db4e605c7..5757d33ddad 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -34,14 +34,14 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s) \ - PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[13]) +#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[13], flags) const phpdbg_command_t phpdbg_list_commands[] = { - PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l"), - PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s"), - PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m"), - PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s"), + PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l", PHPDBG_ASYNC_SAFE), + PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s", PHPDBG_ASYNC_SAFE), + PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m", PHPDBG_ASYNC_SAFE), + PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s", PHPDBG_ASYNC_SAFE), PHPDBG_END_COMMAND }; @@ -81,7 +81,7 @@ PHPDBG_LIST(method) /* {{{ */ { zend_class_entry **ce; - if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { + if (phpdbg_safe_class_lookup(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { zend_function *function; char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); @@ -103,7 +103,7 @@ PHPDBG_LIST(class) /* {{{ */ { zend_class_entry **ce; - if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { + if (phpdbg_safe_class_lookup(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { if ((*ce)->type == ZEND_USER_CLASS) { if ((*ce)->info.user.filename) { phpdbg_list_file( @@ -124,59 +124,41 @@ PHPDBG_LIST(class) /* {{{ */ return SUCCESS; } /* }}} */ -void phpdbg_list_file(const char *filename, long count, long offset, int highlight TSRMLS_DC) /* {{{ */ +void phpdbg_list_file(const char *filename, uint count, uint offset, uint highlight TSRMLS_DC) /* {{{ */ { - struct stat st; - char *opened = NULL; - char buffer[8096] = {0,}; - long line = 0; + uint line, lastline; + phpdbg_file_source **data; - php_stream *stream = NULL; - - if (VCWD_STAT(filename, &st) == FAILURE) { - phpdbg_error("Failed to stat file %s", filename); - return; + if (zend_hash_find(&PHPDBG_G(file_sources), filename, strlen(filename), (void **) &data) == FAILURE) { + phpdbg_error("Could not find information about included file..."); } - stream = php_stream_open_wrapper(filename, "rb", USE_PATH, &opened); - - if (!stream) { - phpdbg_error("Failed to open file %s to list", filename); - return; - } - if (offset < 0) { count += offset; offset = 0; } - - while (php_stream_gets(stream, buffer, sizeof(buffer)) != NULL) { - long linelen = strlen(buffer); - ++line; - - if (offset <= line) { - if (!highlight) { - phpdbg_write("%05ld: %s", line, buffer); + lastline = offset + count; + + if (lastline > (*data)->lines) { + lastline = (*data)->lines; + } + + for (line = offset; line < lastline;) { + uint linestart = (*data)->line[line++]; + uint linelen = (*data)->line[line] - linestart; + char *buffer = (*data)->buf + linestart; + + if (!highlight) { + phpdbg_write("%05u: %.*s", line, linelen, buffer); + } else { + if (highlight != line) { + phpdbg_write(" %05u: %.*s", line, linelen, buffer); } else { - if (highlight != line) { - phpdbg_write(" %05ld: %s", line, buffer); - } else { - phpdbg_write(">%05ld: %s", line, buffer); - } + phpdbg_write(">%05u: %.*s", line, linelen, buffer); } - - if (buffer[linelen - 1] != '\n') { - phpdbg_write("\n"); - } - } - - if (count > 0 && count + offset - 1 < line) { - break; } } - - php_stream_close(stream); } /* }}} */ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */ @@ -188,10 +170,9 @@ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */ return; } - ops = (zend_op_array*)fbc; + ops = (zend_op_array *)fbc; - phpdbg_list_file(ops->filename, - ops->line_end - ops->line_start + 1, ops->line_start, 0 TSRMLS_CC); + phpdbg_list_file(ops->filename, ops->line_end - ops->line_start + 1, ops->line_start, 0 TSRMLS_CC); } /* }}} */ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ */ @@ -222,12 +203,83 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ * /* use lowercase names, case insensitive */ func_name = zend_str_tolower_dup(func_name, func_name_len); - if (zend_hash_find(func_table, func_name, func_name_len+1, (void**)&fbc) == SUCCESS) { - phpdbg_list_function(fbc TSRMLS_CC); - } else { - phpdbg_error("Function %s not found", func_name); - } + phpdbg_try_access { + if (zend_hash_find(func_table, func_name, func_name_len+1, (void**)&fbc) == SUCCESS) { + phpdbg_list_function(fbc TSRMLS_CC); + } else { + phpdbg_error("Function %s not found", func_name); + } + } phpdbg_catch_access { + phpdbg_error("Could not list function %s, invalid data source", func_name); + } phpdbg_end_try_access(); efree(func_name); } /* }}} */ +zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) { + phpdbg_file_source data, *dataptr; + zend_file_handle fake = {0}; + zend_op_array *ret; + char *filename = (char *)(file->opened_path ? file->opened_path : file->filename); + uint line; + char *bufptr, *endptr; + + zend_stream_fixup(file, &data.buf, &data.len TSRMLS_CC); + + 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 HAVE_MMAP + if (file->handle.stream.mmap.map) { + data.map = file->handle.stream.mmap.map; + } +#endif + + 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 = NULL; + fake.filename = filename; + + *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data; + zend_hash_add(&PHPDBG_G(file_sources), filename, strlen(filename), &dataptr, sizeof(phpdbg_file_source *), NULL); + + for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) { + if (*bufptr == '\n') { + dataptr->line[++line] = (uint)(bufptr - data.buf) + 1; + } + } + dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line); + dataptr->lines = ++line; + + ret = PHPDBG_G(compile_file)(&fake, type TSRMLS_CC); + + zend_file_handle_dtor(&fake TSRMLS_CC); + + 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 + if (data->buf) { + efree(data->buf); + } + + efree(data); +} + +void phpdbg_init_list(TSRMLS_D) { + PHPDBG_G(compile_file) = zend_compile_file; + zend_hash_init(&PHPDBG_G(file_sources), 1, NULL, (dtor_func_t) phpdbg_free_file_source, 0); + zend_compile_file = phpdbg_compile_file; +} diff --git a/phpdbg_list.h b/phpdbg_list.h index 14905f65673..385ae205804 100644 --- a/phpdbg_list.h +++ b/phpdbg_list.h @@ -34,8 +34,21 @@ PHPDBG_LIST(func); void phpdbg_list_function_byname(const char *, size_t TSRMLS_DC); void phpdbg_list_function(const zend_function* TSRMLS_DC); -void phpdbg_list_file(const char*, long, long, int TSRMLS_DC); +void phpdbg_list_file(const char*, uint, uint, uint TSRMLS_DC); extern const phpdbg_command_t phpdbg_list_commands[]; +void phpdbg_init_list(TSRMLS_D); + +typedef struct { + char *filename; + char *buf; + size_t len; +#if HAVE_MMAP + void *map; +#endif + uint lines; + uint line[1]; +} phpdbg_file_source; + #endif /* PHPDBG_LIST_H */ diff --git a/phpdbg_print.c b/phpdbg_print.c index 76321a5042d..e2b4dd229cb 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -26,16 +26,16 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -#define PHPDBG_PRINT_COMMAND_D(f, h, a, m, l, s) \ - PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[9]) +#define PHPDBG_PRINT_COMMAND_D(f, h, a, m, l, s, flags) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[9], flags) const phpdbg_command_t phpdbg_print_commands[] = { - PHPDBG_PRINT_COMMAND_D(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0), - PHPDBG_PRINT_COMMAND_D(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0), - PHPDBG_PRINT_COMMAND_D(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s"), - PHPDBG_PRINT_COMMAND_D(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m"), - PHPDBG_PRINT_COMMAND_D(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s"), - PHPDBG_PRINT_COMMAND_D(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0), + PHPDBG_PRINT_COMMAND_D(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_PRINT_COMMAND_D(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_PRINT_COMMAND_D(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s", PHPDBG_ASYNC_SAFE), + PHPDBG_PRINT_COMMAND_D(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m", PHPDBG_ASYNC_SAFE), + PHPDBG_PRINT_COMMAND_D(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s", PHPDBG_ASYNC_SAFE), + PHPDBG_PRINT_COMMAND_D(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0, PHPDBG_ASYNC_SAFE), PHPDBG_END_COMMAND }; @@ -108,7 +108,7 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) PHPDBG_PRINT(exec) /* {{{ */ { if (PHPDBG_G(exec)) { - if (!PHPDBG_G(ops)) { + if (!PHPDBG_G(ops) && !(PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER)) { phpdbg_compile(TSRMLS_C); } @@ -154,7 +154,7 @@ PHPDBG_PRINT(class) /* {{{ */ { zend_class_entry **ce; - if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { + if (phpdbg_safe_class_lookup(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { phpdbg_notice("%s %s: %s", ((*ce)->type == ZEND_USER_CLASS) ? "User" : "Internal", @@ -187,7 +187,7 @@ PHPDBG_PRINT(method) /* {{{ */ { zend_class_entry **ce; - if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { + if (phpdbg_safe_class_lookup(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { zend_function *fbc; char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); @@ -234,18 +234,22 @@ PHPDBG_PRINT(func) /* {{{ */ func_table = EG(function_table); } - lcname = zend_str_tolower_dup(func_name, func_name_len); + lcname = zend_str_tolower_dup(func_name, func_name_len); - if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { - phpdbg_notice("%s %s %s", - (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", - (fbc->common.scope) ? "Method" : "Function", - fbc->common.function_name); + phpdbg_try_access { + if (zend_hash_find(func_table, lcname, func_name_len + 1, (void **) &fbc) == SUCCESS) { + phpdbg_notice("%s %s %s", + (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", + (fbc->common.scope) ? "Method" : "Function", + fbc->common.function_name); - phpdbg_print_function_helper(fbc TSRMLS_CC); - } else { - phpdbg_error("The function %s could not be found", func_name); - } + phpdbg_print_function_helper(fbc TSRMLS_CC); + } else { + phpdbg_error("The function %s could not be found", func_name); + } + } phpdbg_catch_access { + phpdbg_error("Couldn't fetch function %.*s, invalid data source", func_name_len, func_name); + } phpdbg_end_try_access(); efree(lcname); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 367926abd5f..7bb84077303 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -40,30 +40,30 @@ /* {{{ command declarations */ const phpdbg_command_t phpdbg_prompt_commands[] = { - PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s"), - PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0), - PHPDBG_COMMAND_D(continue,"continue execution", 'c', NULL, 0), - PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s"), - PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"), - PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0), - PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0), - PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0), - PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, 0), - PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "|*c"), - PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n"), - PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n"), - PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*"), - PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, "s"), - PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0), - PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0), - PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s"), - PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s"), - PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), - PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s"), - PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s"), - PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"), - PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), - PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss"), + PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s", 0), + PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(continue,"continue execution", 'c', NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s", 0), + PHPDBG_COMMAND_D(ev, "evaluate some code", 0 , NULL, "i", 0), /* restricted ASYNC_SAFE */ + PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0, 0), + PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0, 0), + PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0, 0), + PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, 0, 0), + PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "|*c", 0), + PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n", PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n", PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*", PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, "s", PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0, 0), + PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0, 0), + PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s", PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s", PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s", 0), + PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s", 0), + PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s", PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(sh, "shell a command", 0 , NULL, "i", 0), + PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss", 0), PHPDBG_END_COMMAND }; /* }}} */ @@ -250,21 +250,17 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ phpdbg_init_param(&stack, STACK_PARAM); if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { - switch (phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { + switch (phpdbg_stack_execute(&stack, &why, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) { case FAILURE: -// if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { - phpdbg_error( - "Unrecognized command in %s:%d: %s, %s!", - init_file, line, input, why); - } -// } + if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + phpdbg_error("Unrecognized command in %s:%d: %s, %s!", init_file, line, input, why); + } break; } } if (why) { - free(why); + efree(why); why = NULL; } @@ -992,7 +988,7 @@ PHPDBG_COMMAND(watch) /* {{{ */ return SUCCESS; } /* }}} */ -int phpdbg_interactive(TSRMLS_D) /* {{{ */ +int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */ { int ret = SUCCESS; char *why = NULL; @@ -1008,10 +1004,10 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ phpdbg_init_param(&stack, STACK_PARAM); if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { - switch (ret = phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { + switch (ret = phpdbg_stack_execute(&stack, &why, allow_async_unsafe TSRMLS_CC)) { case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + if (!allow_async_unsafe || phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { if (why) { phpdbg_error("%s", why); } @@ -1019,7 +1015,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } if (why) { - free(why); + efree(why); why = NULL; } break; @@ -1037,13 +1033,12 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } if (why) { - free(why); + efree(why); why = NULL; } phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); - } while ((input = phpdbg_read_input(NULL TSRMLS_CC))); } @@ -1054,7 +1049,7 @@ out: } if (why) { - free(why); + efree(why); } if (EG(in_execution)) { @@ -1145,6 +1140,27 @@ static inline zend_execute_data *phpdbg_create_execute_data(zend_op_array *op_ar #endif } /* }}} */ +#define DO_INTERACTIVE(allow_async_unsafe) do { \ + if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { \ + phpdbg_list_file( \ + zend_get_executed_filename(TSRMLS_C), \ + 3, \ + zend_get_executed_lineno(TSRMLS_C)-1, \ + zend_get_executed_lineno(TSRMLS_C) \ + TSRMLS_CC \ + ); \ + } \ + \ + switch (phpdbg_interactive(allow_async_unsafe TSRMLS_CC)) { \ + case PHPDBG_LEAVE: \ + case PHPDBG_FINISH: \ + case PHPDBG_UNTIL: \ + case PHPDBG_NEXT:{ \ + goto next; \ + } \ + } \ +} while (0) + #if PHP_VERSION_ID >= 50500 void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ { @@ -1181,41 +1197,17 @@ zend_vm_enter: #endif while (1) { - if ((PHPDBG_G(flags) & PHPDBG_BP_RESOLVE_MASK)) { /* resolve nth opline breakpoints */ phpdbg_resolve_op_array_breaks(EG(active_op_array) TSRMLS_CC); } - + #ifdef ZEND_WIN32 if (EG(timed_out)) { zend_timeout(0); } #endif -#define DO_INTERACTIVE() do { \ - if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { \ - phpdbg_list_file( \ - zend_get_executed_filename(TSRMLS_C), \ - 3, \ - zend_get_executed_lineno(TSRMLS_C)-1, \ - zend_get_executed_lineno(TSRMLS_C) \ - TSRMLS_CC \ - ); \ - } \ - \ -/* do { */\ - switch (phpdbg_interactive(TSRMLS_C)) { \ - case PHPDBG_LEAVE: \ - case PHPDBG_FINISH: \ - case PHPDBG_UNTIL: \ - case PHPDBG_NEXT:{ \ - goto next; \ - } \ - } \ -/* } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); */\ -} while (0) - /* allow conditional breakpoints and initialization to access the vm uninterrupted */ if ((PHPDBG_G(flags) & PHPDBG_IN_COND_BP) || @@ -1263,7 +1255,7 @@ zend_vm_enter: zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C) ); - DO_INTERACTIVE(); + DO_INTERACTIVE(1); } else { /* skip possible breakpoints */ goto next; @@ -1277,13 +1269,13 @@ zend_vm_enter: if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING && (PHPDBG_G(flags) & PHPDBG_STEP_OPCODE || execute_data->opline->lineno != PHPDBG_G(last_line))) { PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; - DO_INTERACTIVE(); + DO_INTERACTIVE(1); } /* check if some watchpoint was hit */ { if (phpdbg_print_changed_zvals(TSRMLS_C) == SUCCESS) { - DO_INTERACTIVE(); + DO_INTERACTIVE(1); } } @@ -1295,18 +1287,19 @@ zend_vm_enter: && (brake = phpdbg_find_breakpoint(execute_data TSRMLS_CC)) && (brake->type != PHPDBG_BREAK_FILE || execute_data->opline->lineno != PHPDBG_G(last_line))) { phpdbg_hit_breakpoint(brake, 1 TSRMLS_CC); - DO_INTERACTIVE(); + DO_INTERACTIVE(1); } } -next: if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { phpdbg_writeln(EMPTY); phpdbg_notice("Program received signal SIGINT"); - PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED; - DO_INTERACTIVE(); + DO_INTERACTIVE(1); } + PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED; +next: + PHPDBG_G(last_line) = execute_data->opline->lineno; PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); @@ -1335,9 +1328,12 @@ next: zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen"); } /* }}} */ +/* only if *not* interactive and while executing */ void phpdbg_force_interruption(TSRMLS_D) { zend_execute_data *data = EG(current_execute_data); /* should be always readable if not NULL */ + PHPDBG_G(flags) |= PHPDBG_IN_SIGNAL_HANDLER; + if (data) { if (data->op_array) { phpdbg_notice("Current opline: %p (op #%lu) in %s:%u", data->opline, (data->opline - data->op_array->opcodes) / sizeof(data->opline), data->op_array->filename, data->opline->lineno); @@ -1347,4 +1343,13 @@ void phpdbg_force_interruption(TSRMLS_D) { } else { phpdbg_notice("No information available about executing context"); } + + DO_INTERACTIVE(0); + +next: + PHPDBG_G(flags) &= ~PHPDBG_IN_SIGNAL_HANDLER; + + if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) { + zend_bailout(); + } } diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 5909407e7df..4247a440887 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -24,9 +24,11 @@ /* {{{ */ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC); void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC); -int phpdbg_interactive(TSRMLS_D); +int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC); int phpdbg_compile(TSRMLS_D); -void phpdbg_clean(zend_bool full TSRMLS_DC); /* }}} */ +void phpdbg_clean(zend_bool full TSRMLS_DC); +void phpdbg_force_interruption(TSRMLS_D); +/* }}} */ /* {{{ phpdbg command handlers */ PHPDBG_COMMAND(exec); @@ -64,6 +66,4 @@ void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC); void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC); #endif /* }}} */ -void phpdbg_force_interruption(TSRMLS_D); - #endif /* PHPDBG_PROMPT_H */ diff --git a/phpdbg_set.c b/phpdbg_set.c index 54269a81931..e7699a0c77f 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -27,21 +27,21 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -#define PHPDBG_SET_COMMAND_D(f, h, a, m, l, s) \ - PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[18]) +#define PHPDBG_SET_COMMAND_D(f, h, a, m, l, s, flags) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[18], flags) const phpdbg_command_t phpdbg_set_commands[] = { - PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt []", 'p', set_prompt, NULL, "|s"), + PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt []", 'p', set_prompt, NULL, "|s", 0), #ifndef _WIN32 - PHPDBG_SET_COMMAND_D(color, "usage: set color ", 'c', set_color, NULL, "ss"), - PHPDBG_SET_COMMAND_D(colors, "usage: set colors []", 'C', set_colors, NULL, "|b"), + PHPDBG_SET_COMMAND_D(color, "usage: set color ", 'c', set_color, NULL, "ss", PHPDBG_ASYNC_SAFE), + PHPDBG_SET_COMMAND_D(colors, "usage: set colors []", 'C', set_colors, NULL, "|b", PHPDBG_ASYNC_SAFE), #endif - PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog []", 'O', set_oplog, NULL, "|s"), - PHPDBG_SET_COMMAND_D(break, "usage: set break id []", 'b', set_break, NULL, "l|b"), - PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks []", 'B', set_breaks, NULL, "|b"), - PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet []", 'q', set_quiet, NULL, "|b"), - PHPDBG_SET_COMMAND_D(stepping, "usage: set stepping []", 's', set_stepping, NULL, "|s"), - PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount []", 'r', set_refcount, NULL, "|b"), + PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog []", 'O', set_oplog, NULL, "|s", 0), + PHPDBG_SET_COMMAND_D(break, "usage: set break id []", 'b', set_break, NULL, "l|b", PHPDBG_ASYNC_SAFE), + PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks []", 'B', set_breaks, NULL, "|b", PHPDBG_ASYNC_SAFE), + PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet []", 'q', set_quiet, NULL, "|b", PHPDBG_ASYNC_SAFE), + PHPDBG_SET_COMMAND_D(stepping, "usage: set stepping []", 's', set_stepping, NULL, "|s", PHPDBG_ASYNC_SAFE), + PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount []", 'r', set_refcount, NULL, "|b", PHPDBG_ASYNC_SAFE), PHPDBG_END_COMMAND }; diff --git a/phpdbg_sigsafe.c b/phpdbg_sigsafe.c index 96ac713f232..7238ad102fb 100644 --- a/phpdbg_sigsafe.c +++ b/phpdbg_sigsafe.c @@ -96,9 +96,13 @@ void phpdbg_set_sigsafe_mem(char *buffer TSRMLS_DC) { mem->heap.reserve_size = 0; } +zend_mm_heap *phpdbg_original_heap_sigsafe_mem(TSRMLS_D) { + return PHPDBG_G(sigsafe_mem).old_heap; +} + void phpdbg_clear_sigsafe_mem(TSRMLS_D) { + zend_mm_set_heap(phpdbg_original_heap_sigsafe_mem(TSRMLS_C) TSRMLS_CC); PHPDBG_G(sigsafe_mem).mem = NULL; - zend_mm_set_heap(PHPDBG_G(sigsafe_mem).old_heap TSRMLS_CC); } zend_bool phpdbg_active_sigsafe_mem(TSRMLS_D) { diff --git a/phpdbg_sigsafe.h b/phpdbg_sigsafe.h index 810e07c789c..6ed74f53db9 100644 --- a/phpdbg_sigsafe.h +++ b/phpdbg_sigsafe.h @@ -7,7 +7,7 @@ typedef struct { char *mem; - zend_bool allocated;; + zend_bool allocated; zend_mm_heap heap; zend_mm_heap *old_heap; zend_mm_storage storage; @@ -20,4 +20,6 @@ zend_bool phpdbg_active_sigsafe_mem(TSRMLS_D); void phpdbg_set_sigsafe_mem(char *mem TSRMLS_DC); void phpdbg_clear_sigsafe_mem(TSRMLS_D); +zend_mm_heap *phpdbg_original_heap_sigsafe_mem(TSRMLS_D); + #endif diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 4d3eb4cde68..d12a304d129 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -475,3 +475,34 @@ PHPDBG_API void phpdbg_set_async_io(int fd) { fcntl(STDIN_FILENO, F_SETFL, flags | FASYNC); #endif } + +int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) { + if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { + char *lc_name, *lc_free; + int lc_length, ret = FAILURE; + + if (name == NULL || !name_length) { + return FAILURE; + } + + lc_free = lc_name = emalloc(name_length + 1); + zend_str_tolower_copy(lc_name, name, name_length); + lc_length = name_length + 1; + + if (lc_name[0] == '\\') { + lc_name += 1; + lc_length -= 1; + } + + phpdbg_try_access { + ret = zend_hash_find(EG(class_table), lc_name, lc_length, (void **) &ce); + } phpdbg_catch_access { + phpdbg_error("Could not fetch class %.*s, invalid data source", name_length, name); + } phpdbg_end_try_access(); + + efree(lc_free); + return ret; + } else { + return zend_lookup_class(name, name_length, ce TSRMLS_CC); + } +} diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 9686d769480..01aa8490fe5 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -146,4 +146,6 @@ static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, Ha } #endif +int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC); + #endif /* PHPDBG_UTILS_H */ diff --git a/phpdbg_watch.h b/phpdbg_watch.h index d00bcff77e5..5c0079057cf 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -42,9 +42,9 @@ PHPDBG_WATCH(recursive); */ static const phpdbg_command_t phpdbg_watch_commands[] = { - PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, "s"), - PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, "s"), - PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, "s"), + PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, "s", 0), + PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, "s", 0), + PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, "s", 0), PHPDBG_END_COMMAND }; From 323e59adfc2410704261186643d03c2bc01cb870 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 3 Oct 2014 12:43:32 +0200 Subject: [PATCH 025/125] Added support for a restricted ev (variables only) in async safe contexts --- phpdbg_cmd.c | 6 +-- phpdbg_prompt.c | 29 +++++++++-- phpdbg_utils.c | 114 ++++++++++++++++++++++++++++++++++++++++ phpdbg_utils.h | 8 +++ phpdbg_watch.c | 134 +++++++++--------------------------------------- 5 files changed, 170 insertions(+), 121 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index e9811dc43b9..8fb86a5cbd8 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -750,11 +750,7 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why, zend_bool switch (top->type) { case EVAL_PARAM: - if (allow_async_unsafe) { - return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); - } - spprintf(why, 0, "ev command is disallowed during hard interrupt"); - return FAILURE; + return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); case RUN_PARAM: if (allow_async_unsafe) { diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 7bb84077303..a993c6c8293 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -44,7 +44,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0, PHPDBG_ASYNC_SAFE), PHPDBG_COMMAND_D(continue,"continue execution", 'c', NULL, 0, PHPDBG_ASYNC_SAFE), PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s", 0), - PHPDBG_COMMAND_D(ev, "evaluate some code", 0 , NULL, "i", 0), /* restricted ASYNC_SAFE */ + PHPDBG_COMMAND_D(ev, "evaluate some code", 0 , NULL, "i", PHPDBG_ASYNC_SAFE), /* restricted ASYNC_SAFE */ PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0, 0), PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0, 0), PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0, 0), @@ -671,13 +671,32 @@ out: return SUCCESS; } /* }}} */ +int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv TSRMLS_DC) { + phpdbg_notice("Printing variable %.*s", (int) len, name); + zend_print_zval_r(*zv, 0 TSRMLS_CC); + phpdbg_writeln(EMPTY); + efree(name); + efree(keyname); + + return SUCCESS; +} + PHPDBG_COMMAND(ev) /* {{{ */ { zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)==PHPDBG_IS_STEPPING); zval retval; + if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { + phpdbg_try_access { + phpdbg_parse_variable(param->str, param->len, &EG(symbol_table), 0, phpdbg_output_ev_variable, 0 TSRMLS_CC); + } phpdbg_catch_access { + phpdbg_error("Could not fetch data, invalid data source"); + } phpdbg_end_try_access(); + return SUCCESS; + } + if (!(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { - PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; + PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; } /* disable stepping while eval() in progress */ @@ -685,8 +704,7 @@ PHPDBG_COMMAND(ev) /* {{{ */ zend_try { if (zend_eval_stringl(param->str, param->len, &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { - zend_print_zval_r( - &retval, 0 TSRMLS_CC); + zend_print_zval_r(&retval, 0 TSRMLS_CC); phpdbg_writeln(EMPTY); zval_dtor(&retval); } @@ -1292,12 +1310,13 @@ zend_vm_enter: } if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { + PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED; + phpdbg_writeln(EMPTY); phpdbg_notice("Program received signal SIGINT"); DO_INTERACTIVE(1); } - PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED; next: PHPDBG_G(last_line) = execute_data->opline->lineno; diff --git a/phpdbg_utils.c b/phpdbg_utils.c index d12a304d129..aba0d60241f 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -506,3 +506,117 @@ int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry return zend_lookup_class(name, name_length, ce TSRMLS_CC); } } + +char *phpdbg_get_property_key(char *key) { + if (*key != 0) { + return key; + } + return strchr(key + 1, 0) + 1; +} + +static int phpdbg_parse_variable_arg_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv, phpdbg_parse_var_func callback TSRMLS_DC) { + return callback(name, len, keyname, keylen, parent, zv TSRMLS_CC); +} + +PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, zend_bool silent TSRMLS_DC) { + return phpdbg_parse_variable_with_arg(input, len, parent, i, (phpdbg_parse_var_with_arg_func) phpdbg_parse_variable_arg_wrapper, silent, callback TSRMLS_CC); +} + +PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, zend_bool silent, void *arg TSRMLS_DC) { + int ret = FAILURE; + zend_bool new_index = 1; + char *last_index; + size_t index_len = 0; + zval **zv; + + if (len < 2 || *input != '$') { + goto error; + } + + while (i++ < len) { + if (i == len) { + new_index = 1; + } else { + switch (input[i]) { + case '[': + new_index = 1; + break; + case ']': + break; + case '>': + if (last_index[index_len - 1] == '-') { + new_index = 1; + index_len--; + } + break; + + default: + if (new_index) { + last_index = input + i; + new_index = 0; + } + if (input[i - 1] == ']') { + goto error; + } + index_len++; + } + } + + if (new_index && index_len == 0) { + HashPosition position; + for (zend_hash_internal_pointer_reset_ex(parent, &position); + zend_hash_get_current_data_ex(parent, (void **)&zv, &position) == SUCCESS; + zend_hash_move_forward_ex(parent, &position)) { + if (i == len || (i == len - 1 && input[len - 1] == ']')) { + zval *key = emalloc(sizeof(zval)); + size_t namelen; + char *name; + char *keyname = estrndup(last_index, index_len); + zend_hash_get_current_key_zval_ex(parent, key, &position); + convert_to_string(key); + name = emalloc(i + Z_STRLEN_P(key) + 2); + namelen = sprintf(name, "%.*s%s%s", (int)i, input, phpdbg_get_property_key(Z_STRVAL_P(key)), input[len - 1] == ']'?"]":""); + efree(key); + + ret = callback(name, namelen, keyname, index_len, parent, zv, arg TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + } else if (Z_TYPE_PP(zv) == IS_OBJECT) { + phpdbg_parse_variable_with_arg(input, len, Z_OBJPROP_PP(zv), i, callback, silent, arg TSRMLS_CC); + } else if (Z_TYPE_PP(zv) == IS_ARRAY) { + phpdbg_parse_variable_with_arg(input, len, Z_ARRVAL_PP(zv), i, callback, silent, arg TSRMLS_CC); + } else { + /* Ignore silently */ + } + } + return ret; + } else if (new_index) { + char last_chr = last_index[index_len]; + last_index[index_len] = 0; + if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) { + if (!silent) { + phpdbg_error("%.*s is undefined", (int)i, input); + } + return FAILURE; + } + last_index[index_len] = last_chr; + if (i == len) { + char *name = estrndup(input, len); + char *keyname = estrndup(last_index, index_len); + + ret = callback(name, len, keyname, index_len, parent, zv, arg TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + } else if (Z_TYPE_PP(zv) == IS_OBJECT) { + parent = Z_OBJPROP_PP(zv); + } else if (Z_TYPE_PP(zv) == IS_ARRAY) { + parent = Z_ARRVAL_PP(zv); + } else { + phpdbg_error("%.*s is nor an array nor an object", (int)i, input); + return FAILURE; + } + index_len = 0; + } + } + + return ret; + error: + phpdbg_error("Malformed input"); + return FAILURE; +} diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 01aa8490fe5..b54a1d46841 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -148,4 +148,12 @@ static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, Ha int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC); +char *phpdbg_get_property_key(char *key); + +typedef int (*phpdbg_parse_var_func)(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv TSRMLS_DC); +typedef int (*phpdbg_parse_var_with_arg_func)(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv, void *arg TSRMLS_DC); + +PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, zend_bool silent TSRMLS_DC); +PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, zend_bool silent, void *arg TSRMLS_DC); + #endif /* PHPDBG_UTILS_H */ diff --git a/phpdbg_watch.c b/phpdbg_watch.c index e88622444bf..ee937f90631 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -138,13 +138,6 @@ static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) return SUCCESS; } -static char *phpdbg_get_property_key(char *key) { - if (*key != 0) { - return key; - } - return strchr(key + 1, 0) + 1; -} - static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { HashTable *ht; @@ -281,118 +274,37 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) { ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); } - free(tmp_watch->str); + efree(tmp_watch->str); + efree(tmp_watch->name_in_parent); efree(tmp_watch); return ret; } -static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC), zend_bool silent TSRMLS_DC) { - int ret = FAILURE; - zend_bool new_index = 1; - char *last_index; - int index_len = 0; - zval **zv; +static int phpdbg_watchpoint_parse_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { + int ret; + phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); + watch->flags = 0; + watch->str = name; + watch->str_len = len; + watch->name_in_parent = keyname; + watch->name_in_parent_len = keylen; + watch->parent_container = parent; + phpdbg_create_zval_watchpoint(*zv, watch); - if (len < 2 || *input != '$') { - goto error; - } + ret = callback(watch TSRMLS_CC); - while (i++ < len) { - if (i == len) { - new_index = 1; - } else { - switch (input[i]) { - case '[': - new_index = 1; - break; - case ']': - break; - case '>': - if (last_index[index_len - 1] == '-') { - new_index = 1; - index_len--; - } - break; - - default: - if (new_index) { - last_index = input + i; - new_index = 0; - } - if (input[i - 1] == ']') { - goto error; - } - index_len++; - } - } - - if (new_index && index_len == 0) { - HashPosition position; - for (zend_hash_internal_pointer_reset_ex(parent, &position); - zend_hash_get_current_data_ex(parent, (void **)&zv, &position) == SUCCESS; - zend_hash_move_forward_ex(parent, &position)) { - if (i == len || (i == len - 1 && input[len - 1] == ']')) { - zval *key = emalloc(sizeof(zval)); - phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); - watch->flags = 0; - zend_hash_get_current_key_zval_ex(parent, key, &position); - convert_to_string(key); - watch->str = malloc(i + Z_STRLEN_P(key) + 2); - watch->str_len = sprintf(watch->str, "%.*s%s%s", (int)i, input, phpdbg_get_property_key(Z_STRVAL_P(key)), input[len - 1] == ']'?"]":""); - efree(key); - watch->name_in_parent = zend_strndup(last_index, index_len); - watch->name_in_parent_len = index_len; - watch->parent_container = parent; - phpdbg_create_zval_watchpoint(*zv, watch); - - ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; - } else if (Z_TYPE_PP(zv) == IS_OBJECT) { - phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback, silent TSRMLS_CC); - } else if (Z_TYPE_PP(zv) == IS_ARRAY) { - phpdbg_watchpoint_parse_input(input, len, Z_ARRVAL_PP(zv), i, callback, silent TSRMLS_CC); - } else { - /* Ignore silently */ - } - } - return ret; - } else if (new_index) { - char last_chr = last_index[index_len]; - last_index[index_len] = 0; - if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) { - if (!silent) { - phpdbg_error("%.*s is undefined", (int)i, input); - } - return FAILURE; - } - last_index[index_len] = last_chr; - if (i == len) { - phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); - watch->flags = 0; - watch->str = zend_strndup(input, len); - watch->str_len = len; - watch->name_in_parent = zend_strndup(last_index, index_len); - watch->name_in_parent_len = index_len; - watch->parent_container = parent; - phpdbg_create_zval_watchpoint(*zv, watch); - - ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; - } else if (Z_TYPE_PP(zv) == IS_OBJECT) { - parent = Z_OBJPROP_PP(zv); - } else if (Z_TYPE_PP(zv) == IS_ARRAY) { - parent = Z_ARRVAL_PP(zv); - } else { - phpdbg_error("%.*s is nor an array nor an object", (int)i, input); - return FAILURE; - } - index_len = 0; - } + if (ret != SUCCESS) { + efree(watch); + efree(name); + efree(keyname); } return ret; - error: - phpdbg_error("Malformed input"); - return FAILURE; +} + +PHPDBG_API int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC), zend_bool silent TSRMLS_DC) { + phpdbg_parse_variable_with_arg(input, len, parent, i, (phpdbg_parse_var_with_arg_func) phpdbg_watchpoint_parse_wrapper, 0, callback TSRMLS_CC); } static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { @@ -550,8 +462,8 @@ static void phpdbg_watch_dtor(void *pDest) { phpdbg_deactivate_watchpoint(watch TSRMLS_CC); phpdbg_remove_watchpoint(watch TSRMLS_CC); - free(watch->str); - free(watch->name_in_parent); + efree(watch->str); + efree(watch->name_in_parent); efree(watch); } From 490aa1f984ee55bf31ac4f1d49385fbaf5fab0f5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 4 Oct 2014 16:31:34 +0200 Subject: [PATCH 026/125] Use or instead of and for libedit and readline --- phpdbg_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 8fb86a5cbd8..8ada61a43ec 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -807,7 +807,7 @@ disconnect: return NULL; } -#define USE_LIB_STAR (defined(HAVE_LIBREADLINE) && defined(HAVE_LIBEDIT)) +#define USE_LIB_STAR (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)) #if !USE_LIB_STAR if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { if (!phpdbg_write("%s", phpdbg_get_prompt(TSRMLS_C))) { From 9d96cde268b85511dfb6526a907947bacd68b8e2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 4 Oct 2014 17:02:44 +0200 Subject: [PATCH 027/125] LIBREADLINE => HAVE_LIBREADLINE --- phpdbg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg.h b/phpdbg.h index 941b539d118..4541004f848 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -64,7 +64,7 @@ # include "TSRM.h" #endif -#ifdef LIBREADLINE +#ifdef HAVE_LIBREADLINE # include # include #endif From 62465b6d821d3e074af06880d7d3e25fb7a9a038 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 4 Oct 2014 23:30:57 +0200 Subject: [PATCH 028/125] Fix issues with path names and cwd --- phpdbg_list.c | 2 ++ phpdbg_print.c | 2 +- phpdbg_prompt.c | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/phpdbg_list.c b/phpdbg_list.c index 5757d33ddad..96eacd47665 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -246,6 +246,7 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) { fake.free_filename = 0; fake.opened_path = NULL; fake.filename = filename; + fake.opened_path = file->opened_path; *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data; zend_hash_add(&PHPDBG_G(file_sources), filename, strlen(filename), &dataptr, sizeof(phpdbg_file_source *), NULL); @@ -260,6 +261,7 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) { ret = PHPDBG_G(compile_file)(&fake, type TSRMLS_CC); + fake.opened_path = NULL; zend_file_handle_dtor(&fake TSRMLS_CC); return ret; diff --git a/phpdbg_print.c b/phpdbg_print.c index e2b4dd229cb..594fc9a052b 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -248,7 +248,7 @@ PHPDBG_PRINT(func) /* {{{ */ phpdbg_error("The function %s could not be found", func_name); } } phpdbg_catch_access { - phpdbg_error("Couldn't fetch function %.*s, invalid data source", func_name_len, func_name); + phpdbg_error("Couldn't fetch function %.*s, invalid data source", (int) func_name_len, func_name); } phpdbg_end_try_access(); efree(lcname); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index a993c6c8293..0abb75ae85b 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -351,7 +351,9 @@ PHPDBG_COMMAND(exec) /* {{{ */ PHPDBG_G(exec) = res; PHPDBG_G(exec_len) = res_len; - + + VCWD_CHDIR_FILE(res); + *SG(request_info).argv = PHPDBG_G(exec); php_hash_environment(TSRMLS_C); From f48fc67c86cebb4526cfa14c84530dd31ab2ff3f Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 5 Oct 2014 00:16:19 +0200 Subject: [PATCH 029/125] Fix (system) ini entry transfer --- phpdbg_wait.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/phpdbg_wait.c b/phpdbg_wait.c index 286be365259..4b06700dc0d 100644 --- a/phpdbg_wait.c +++ b/phpdbg_wait.c @@ -312,9 +312,12 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { if (Z_TYPE_PP(ini_entry) == IS_STRING) { if (zend_hash_find(EG(ini_directives), Z_STRVAL(key), Z_STRLEN(key) + 1, (void **) &original_ini) == SUCCESS) { if (!original_ini->on_modify || original_ini->on_modify(original_ini, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), original_ini->mh_arg1, original_ini->mh_arg2, original_ini->mh_arg3, ZEND_INI_STAGE_ACTIVATE TSRMLS_CC) == SUCCESS) { + if (original_ini->modified && original_ini->orig_value != original_ini->value) { + efree(original_ini->value); + } original_ini->value = Z_STRVAL_PP(ini_entry); original_ini->value_length = Z_STRLEN_PP(ini_entry); - continue; /* don't free the string */ + Z_TYPE_PP(ini_entry) = IS_NULL; /* don't free the value */ } } } From c55dbad54672e0c8c8979f87f4a6250f7d11dc34 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 5 Oct 2014 02:27:51 +0200 Subject: [PATCH 030/125] Disable automatic resetting of imported auto_globals --- phpdbg_wait.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/phpdbg_wait.c b/phpdbg_wait.c index 4b06700dc0d..e2bded08750 100644 --- a/phpdbg_wait.c +++ b/phpdbg_wait.c @@ -35,12 +35,14 @@ static void phpdbg_rebuild_http_globals_array(int type, const char *name TSRMLS_ } } -/* -static int phpdbg_remove_rearm_autoglobals(zend_auto_global *auto_global TSRMLS_DC) { -// zend_hash_del(&EG(symbol_table), auto_global->name, auto_global->name_len + 1); - return 1; -}*/ +static int phpdbg_dearm_autoglobals(zend_auto_global *auto_global TSRMLS_DC) { + if (auto_global->name_len != sizeof("GLOBALS") - 1 || memcmp(auto_global->name, "GLOBALS", sizeof("GLOBALS") - 1)) { + auto_global->armed = 0; + } + + return ZEND_HASH_APPLY_KEEP; +} typedef struct { HashTable *ht[2]; @@ -139,12 +141,9 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { /* Reapply symbol table */ if (zend_hash_find(ht, "GLOBALS", sizeof("GLOBALS"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) { - zend_hash_clean(&EG(symbol_table)); - EG(symbol_table) = *Z_ARRVAL_PP(zvpp); - { zval **srv; - if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &srv) == SUCCESS && Z_TYPE_PP(srv) == IS_ARRAY) { + if (zend_hash_find(Z_ARRVAL_PP(zvpp), "_SERVER", sizeof("_SERVER"), (void **) &srv) == SUCCESS && Z_TYPE_PP(srv) == IS_ARRAY) { zval **script; if (zend_hash_find(Z_ARRVAL_PP(srv), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &script) == SUCCESS && Z_TYPE_PP(script) == IS_STRING) { phpdbg_param_t param; @@ -154,6 +153,12 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { } } + PG(auto_globals_jit) = 0; + zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_dearm_autoglobals TSRMLS_CC); + + zend_hash_clean(&EG(symbol_table)); + EG(symbol_table) = *Z_ARRVAL_PP(zvpp); + /* Rebuild cookies, env vars etc. from GLOBALS (PG(http_globals)) */ phpdbg_rebuild_http_globals_array(TRACK_VARS_POST, "_POST" TSRMLS_CC); phpdbg_rebuild_http_globals_array(TRACK_VARS_GET, "_GET" TSRMLS_CC); @@ -350,12 +355,6 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { efree(free_zv); } - /* Remove and readd autoglobals */ -/* php_hash_environment(TSRMLS_C); - zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_remove_rearm_autoglobals TSRMLS_CC); - php_startup_auto_globals(TSRMLS_C); - zend_activate_auto_globals(TSRMLS_C); -*/ /* Reapply raw input */ /* ??? */ } From 9cc73b5c75e4951e3d06c11412b318790c814275 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 5 Oct 2014 11:57:14 +0200 Subject: [PATCH 031/125] Fix precision handling in strings --- phpdbg_utils.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index bec222e3282..1151f3f1192 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -435,7 +435,7 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca } else precision = 0; - if (precision > FORMAT_CONV_MAX_PRECISION) { + if (precision > FORMAT_CONV_MAX_PRECISION && *fmt != 's' && *fmt != 'v' && *fmt != 'b') { precision = FORMAT_CONV_MAX_PRECISION; } } else @@ -705,10 +705,10 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca case 'v': s = va_arg(ap, char *); if (s != NULL) { - s_len = strlen(s); - - if (adjust_precision && precision < s_len) { + if (adjust_precision) { s_len = precision; + } else { + s_len = strlen(s); } if (escape_xml) { @@ -760,7 +760,7 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca s_len = PHPDBG_G(err_buf).msglen; } - if (adjust_precision && precision < s_len) { + if (adjust_precision && precision != s_len) { s_len = precision; } } else { From bedd503c3faa238c52e206af7fac9b69a66fed5e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 5 Oct 2014 12:33:24 +0200 Subject: [PATCH 032/125] Consistency in breakpoint tags, => --- phpdbg_bp.c | 32 ++++++++++++++++---------------- phpdbg_prompt.c | 4 ++-- xml.md | 14 +++++++------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 87952cba270..f2ef4228ea1 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -252,19 +252,19 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML zend_hash_index_update( broken, line_num, (void**)&new_break, sizeof(phpdbg_breakfile_t), NULL); - phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld", + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line); PHPDBG_BREAK_MAPPING(new_break.id, broken); } else { - phpdbg_error("breakpoint", "type=\"exists\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num); + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num); } } else { - phpdbg_error("breakpoint", "type=\"notregular\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path); + phpdbg_error("breakpoint", "type=\"notregular\" add=\"fail\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path); } } else { - phpdbg_error("breakpoint", "type=\"nofile\" file=\"%s\"", "Cannot stat %s, it does not exist", path); + phpdbg_error("breakpoint", "type=\"nofile\" add=\"fail\" file=\"%s\"", "Cannot stat %s, it does not exist", path); } } /* }}} */ @@ -281,12 +281,12 @@ PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len T zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol, name_len, &new_break, sizeof(phpdbg_breaksymbol_t), NULL); - phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" function=\"%s\"", "Breakpoint #%d added at %s", + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" function=\"%s\"", "Breakpoint #%d added at %s", new_break.id, new_break.symbol); PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); } else { - phpdbg_error("breakpoint", "type=\"exists\" function=\"%s\"", "Breakpoint exists at %s", name); + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" function=\"%s\"", "Breakpoint exists at %s", name); } } /* }}} */ @@ -320,12 +320,12 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char zend_hash_update(class_table, lcname, func_len, &new_break, sizeof(phpdbg_breakmethod_t), NULL); - phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" method=\"%s::%s\"", "Breakpoint #%d added at %s::%s", + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" method=\"%s::%s\"", "Breakpoint #%d added at %s::%s", new_break.id, class_name, func_name); PHPDBG_BREAK_MAPPING(new_break.id, class_table); } else { - phpdbg_error("breakpoint", "type=\"exists\" method=\"%s::%s\"", "Breakpoint exists at %s::%s", class_name, func_name); + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" method=\"%s::%s\"", "Breakpoint exists at %s::%s", class_name, func_name); } efree(lcname); @@ -346,11 +346,11 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, &new_break, sizeof(phpdbg_breakline_t), NULL); - phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx", + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx", new_break.id, new_break.opline); PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); } else { - phpdbg_error("breakpoint", "type=\"exists\" opline=\"%#lx\"", "Breakpoint exists at %#lx", opline); + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" opline=\"%#lx\"", "Breakpoint exists at %#lx", opline); } } /* }}} */ @@ -359,11 +359,11 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o phpdbg_breakline_t opline_break; if (op_array->last <= brake->opline_num) { if (brake->class_name == NULL) { - phpdbg_error("breakpoint", "type=\"maxoplines\" maxoplinenum=\"%d\" function=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" function=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num); } else if (brake->func_name == NULL) { - phpdbg_error("breakpoint", "type=\"maxoplines\" maxoplinenum=\"%d\" file=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" file=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num); } else { - phpdbg_error("breakpoint", "type=\"maxoplines\" maxoplinenum=\"%d\" method=\"%s::%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" method=\"%s::%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num); } return FAILURE; @@ -419,7 +419,7 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC zend_hash_internal_pointer_end(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); zend_hash_get_current_data(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void **)&opline_break); - phpdbg_notice("breakpoint", "success=\"success\" id=\"%d\" symbol=\"%s\" num=\"%ld\" opline=\"%#lx\"", "Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)", + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" symbol=\"%s\" num=\"%ld\" opline=\"%#lx\"", "Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)", brake->id, brake->class_name?brake->class_name:"", brake->class_name&&brake->func_name?"::":"", @@ -1131,10 +1131,10 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ break; } - phpdbg_notice("breakpoint", "deleted=\"deleted\" id=\"%ld\"", "Deleted breakpoint #%ld", num); + phpdbg_notice("breakpoint", "deleted=\"success\" id=\"%ld\"", "Deleted breakpoint #%ld", num); PHPDBG_BREAK_UNMAPPING(num); } else { - phpdbg_error("breakpoint", "type=\"nobreakpoint\" id=\"%ld\"", "Failed to find breakpoint #%ld", num); + phpdbg_error("breakpoint", "type=\"nobreakpoint\" deleted=\"fail\" id=\"%ld\"", "Failed to find breakpoint #%ld", num); } } /* }}} */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 3f5d5afdd6c..9c24e943637 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -609,14 +609,14 @@ PHPDBG_COMMAND(run) /* {{{ */ PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; zend_execute(EG(active_op_array) TSRMLS_CC); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; - phpdbg_notice("run", "type=\"end\"", "Script ended normally"); + phpdbg_notice("stop", "type=\"normal\"", "Script ended normally"); } zend_catch { EG(active_op_array) = orig_op_array; EG(opline_ptr) = orig_opline; EG(return_value_ptr_ptr) = orig_retval_ptr; if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - phpdbg_error("run", "type=\"bailout\"", "Caught exit/error from VM"); + phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM"); restore = 0; } } zend_end_try(); diff --git a/xml.md b/xml.md index c0554847cec..a178ca74db9 100644 --- a/xml.md +++ b/xml.md @@ -116,7 +116,7 @@ command - invalidcommand: command input is totally invalid - (nostack: should not happen: is an internal error) - (emptystack: should not happen: is an internal error) -p- command: passed command +- command: passed command - subcommand: passed subcommand (present if the error is related to the subcommand) - expected: count of expected arguments - got: type of argument for type "wrongarg" @@ -160,9 +160,9 @@ break / info break - id: the breakpoint id (if the leave command was executed, the id has the value "leave") - num: the nth opline of a function/method/file -- success: has value "success": a brekpoint was successfully added +- add: has value "success"/"fail": a brekpoint was successfully/not added - pending: the breakpoint is waiting for resolving (e.g. a file opline on a not yet loaded file) -- deleted: has value "deleted": a breakpoint was successfully deleted +- deleted: has value "success"/"fail": a breakpoint was successfully/not deleted - eval: the condition on conditional breakpoints - file - opline @@ -382,12 +382,12 @@ exec - invalid: given context (attribute) is not matching a valid file or symlink - notfound: given context (attribute) does not exist -run ---- +run / tag +---------------- - runs the script (set via exec command) -- <run type="end" />: script execution ended normally -- (error) <run type="bailout" /> the VM bailed out (usually because there was some error) +- <stop type="end" />: script execution ended normally +- (error) <stop type="bailout" /> the VM bailed out (usually because there was some error) - compile failures see under exec, errors, <compile> step From 38e981bbdc69983fbe86c33054d8a53b97077482 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 5 Oct 2014 13:29:56 +0200 Subject: [PATCH 033/125] Fix infinite recursion issues (segfaults) --- phpdbg_prompt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 9c24e943637..a72292eb56a 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1248,7 +1248,12 @@ next: PHPDBG_G(last_line) = execute_data->opline->lineno; + /* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */ + if ((execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME || execute_data->opline->opcode == ZEND_DO_FCALL) && execute_data->function_state.function->type == ZEND_USER_FUNCTION) { + zend_execute_ex = execute_ex; + } PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); + zend_execute_ex = phpdbg_execute_ex; if (PHPDBG_G(vmret) > 0) { switch (PHPDBG_G(vmret)) { From 2f6317c4835b1256679fa0a3127e9301fed66b69 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 5 Oct 2014 13:29:56 +0200 Subject: [PATCH 034/125] Fix infinite recursion issues (segfaults) --- phpdbg_prompt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 0abb75ae85b..9341f5aafb0 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1323,7 +1323,12 @@ next: PHPDBG_G(last_line) = execute_data->opline->lineno; + /* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */ + if ((execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME || execute_data->opline->opcode == ZEND_DO_FCALL) && execute_data->function_state.function->type == ZEND_USER_FUNCTION) { + zend_execute_ex = execute_ex; + } PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); + zend_execute_ex = phpdbg_execute_ex; if (PHPDBG_G(vmret) > 0) { switch (PHPDBG_G(vmret)) { From 8b6d707df079529d4bf13098aa7f2b9686c14e59 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 5 Oct 2014 13:57:35 +0200 Subject: [PATCH 035/125] Use PHP 5.4 compatible zend_execute in #if --- phpdbg_prompt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 9341f5aafb0..9333e0f7172 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1325,10 +1325,18 @@ next: /* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */ if ((execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME || execute_data->opline->opcode == ZEND_DO_FCALL) && execute_data->function_state.function->type == ZEND_USER_FUNCTION) { +#if PHP_VERSION_ID < 50500 + zend_execute = execute; +#else zend_execute_ex = execute_ex; +#endif } PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); +#if PHP_VERSION_ID < 50500 + zend_execute = phpdbg_execute_ex; +#else zend_execute_ex = phpdbg_execute_ex; +#endif if (PHPDBG_G(vmret) > 0) { switch (PHPDBG_G(vmret)) { From fb763168196a9701b0b43c33adccaf34edcdd100 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 6 Oct 2014 11:26:08 +0200 Subject: [PATCH 036/125] Add request_id possibility for xml output --- phpdbg.c | 1 + phpdbg.h | 1 + phpdbg_lexer.c | 865 ++++++++++++++++++++++++++---------------------- phpdbg_lexer.l | 9 +- phpdbg_parser.c | 245 +++++++------- phpdbg_parser.h | 4 +- phpdbg_parser.y | 17 +- phpdbg_prompt.c | 2 + phpdbg_utils.c | 11 +- 9 files changed, 631 insertions(+), 524 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 457f4f85ea0..06eeb63cea1 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -74,6 +74,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->io[PHPDBG_STDERR] = NULL; pg->frame.num = 0; + pg->req_id = 0; pg->err_buf.active = 0; pg->err_buf.type = 0; } /* }}} */ diff --git a/phpdbg.h b/phpdbg.h index 74d0fda5f73..b56d6d8d532 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -208,6 +208,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) char *xml; int xmllen; } err_buf; /* error buffer */ + zend_ulong req_id; /* "request id" to keep track of commands */ char *prompt[2]; /* prompt */ const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */ diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 3092dc396dd..5ead27981be 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -1,5 +1,5 @@ /* Generated by re2c 0.13.5 */ -#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 1 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" /* * phpdbg_lexer.l */ @@ -44,7 +44,7 @@ restart: LEX(text) = YYCURSOR; -#line 48 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 48 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -62,7 +62,7 @@ yyc_INITIAL: { static const unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 128, 128, 0, 0, 128, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, @@ -98,28 +98,22 @@ yyc_INITIAL: YYDEBUG(0, *YYCURSOR); YYFILL(4); yych = *YYCURSOR; - if (yych <= 'D') { + if (yych <= 'E') { if (yych <= '\n') { - if (yych <= 0x00) goto yy6; + if (yych <= 0x00) goto yy4; if (yych <= 0x08) goto yy11; - if (yych >= '\n') goto yy4; + if (yych >= '\n') goto yy5; } else { - if (yych <= '\r') { - if (yych <= '\f') goto yy11; - } else { - if (yych != ' ') goto yy11; - } + if (yych == ' ') goto yy2; + if (yych <= 'D') goto yy11; + goto yy7; } } else { if (yych <= 'd') { - if (yych <= 'Q') { - if (yych <= 'E') goto yy7; - goto yy11; - } else { - if (yych <= 'R') goto yy10; - if (yych <= 'S') goto yy8; - goto yy11; - } + if (yych <= 'Q') goto yy11; + if (yych <= 'R') goto yy10; + if (yych <= 'S') goto yy8; + goto yy11; } else { if (yych <= 'q') { if (yych <= 'e') goto yy7; @@ -131,48 +125,36 @@ yyc_INITIAL: } } } +yy2: YYDEBUG(2, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) <= '\f') { - if (yych <= 0x08) goto yy3; - if (yych <= '\n') goto yy26; - } else { - if (yych <= '\r') goto yy26; - if (yych == ' ') goto yy26; - } + if ((yych = *YYCURSOR) == '\t') goto yy26; + if (yych == ' ') goto yy26; yy3: YYDEBUG(3, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 161 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 168 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(NORMAL); YYCURSOR = LEX(text); goto restart; } -#line 154 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 144 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy4: YYDEBUG(4, *YYCURSOR); - ++YYCURSOR; - if ((yych = *YYCURSOR) <= '\f') { - if (yych <= 0x08) goto yy5; - if (yych <= '\n') goto yy26; - } else { - if (yych <= '\r') goto yy26; - if (yych == ' ') goto yy26; - } + yych = *++YYCURSOR; + goto yy3; yy5: YYDEBUG(5, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(6, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 172 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy6: - YYDEBUG(6, *YYCURSOR); - yych = *++YYCURSOR; - goto yy3; +#line 158 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy7: YYDEBUG(7, *YYCURSOR); yyaccept = 0; @@ -235,109 +217,81 @@ yy15: } YYDEBUG(17, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 155 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 162 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_RUN; } -#line 245 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 227 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy18: YYDEBUG(18, *YYCURSOR); yych = *++YYCURSOR; - if (yych <= '\f') { - if (yych <= 0x08) goto yy13; - if (yych >= '\v') goto yy13; - } else { - if (yych <= '\r') goto yy19; - if (yych != ' ') goto yy13; - } + if (yych == '\t') goto yy19; + if (yych != ' ') goto yy13; yy19: YYDEBUG(19, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; YYDEBUG(20, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy21; - if (yych <= '\n') goto yy19; - } else { - if (yych <= '\r') goto yy19; - if (yych == ' ') goto yy19; - } -yy21: + if (yych == '\t') goto yy19; + if (yych == ' ') goto yy19; YYDEBUG(21, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 150 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 157 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } -#line 278 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 249 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy22: YYDEBUG(22, *YYCURSOR); yych = *++YYCURSOR; - if (yych <= '\f') { - if (yych <= 0x08) goto yy13; - if (yych >= '\v') goto yy13; - } else { - if (yych <= '\r') goto yy23; - if (yych != ' ') goto yy13; - } + if (yych == '\t') goto yy23; + if (yych != ' ') goto yy13; yy23: YYDEBUG(23, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; YYDEBUG(24, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy25; - if (yych <= '\n') goto yy23; - } else { - if (yych <= '\r') goto yy23; - if (yych == ' ') goto yy23; - } -yy25: + if (yych == '\t') goto yy23; + if (yych == ' ') goto yy23; YYDEBUG(25, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 145 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 152 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_EVAL; } -#line 311 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 271 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy26: YYDEBUG(26, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; YYDEBUG(27, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy28; - if (yych <= '\n') goto yy26; - } else { - if (yych <= '\r') goto yy26; - if (yych == ' ') goto yy26; - } -yy28: + if (yych == '\t') goto yy26; + if (yych == ' ') goto yy26; YYDEBUG(28, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ goto restart; } -#line 334 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 288 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" } /* *********************************** */ yyc_NORMAL: { static const unsigned char yybm[] = { 0, 16, 16, 16, 16, 16, 16, 16, - 16, 8, 8, 16, 16, 8, 16, 16, + 16, 8, 0, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 0, 16, 16, 16, 16, @@ -372,15 +326,16 @@ yyc_NORMAL: YYDEBUG(29, *YYCURSOR); YYFILL(11); yych = *YYCURSOR; + if (yybm[0+yych] & 8) { + goto yy32; + } YYDEBUG(-1, yych); switch (yych) { - case 0x00: goto yy36; - case '\t': - case '\r': - case ' ': goto yy31; - case '\n': goto yy34; + case 0x00: + case '\n': goto yy35; + case '\r': goto yy31; case '#': goto yy55; - case '-': goto yy41; + case '-': goto yy37; case '.': case '1': case '2': @@ -400,7 +355,7 @@ yyc_NORMAL: case 'F': case 'f': goto yy48; case 'I': - case 'i': goto yy37; + case 'i': goto yy39; case 'N': case 'n': goto yy49; case 'O': @@ -411,83 +366,96 @@ yyc_NORMAL: case 'y': goto yy52; case 'Z': goto yy53; case 'z': goto yy54; - default: goto yy39; + default: goto yy40; } yy31: YYDEBUG(31, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 2) { + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy38; + } else { + goto yy44; + } + } else { + goto yy71; + } + } else { + if (yyaccept <= 3) { + goto yy104; + } else { + goto yy115; + } + } +yy32: + YYDEBUG(32, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(32, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy31; - } YYDEBUG(33, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy32; + } + YYDEBUG(34, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ goto restart; } -#line 434 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy34: - YYDEBUG(34, *YYCURSOR); - ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 8) { - goto yy31; - } +#line 409 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy35: YYDEBUG(35, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(36, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 448 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy36: - YYDEBUG(36, *YYCURSOR); - yych = *++YYCURSOR; - goto yy35; +#line 419 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy37: YYDEBUG(37, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'F') goto yy106; - if (yych == 'f') goto yy106; - goto yy40; + if (yybm[0+yych] & 32) { + goto yy42; + } + if (yych == 'r') goto yy109; + goto yy41; yy38: YYDEBUG(38, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 125 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 132 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_ID; } -#line 470 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 439 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy39: YYDEBUG(39, *YYCURSOR); yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'F') goto yy105; + if (yych == 'f') goto yy105; + goto yy41; +yy40: + YYDEBUG(40, *YYCURSOR); + yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; -yy40: - YYDEBUG(40, *YYCURSOR); +yy41: + YYDEBUG(41, *YYCURSOR); if (yybm[0+yych] & 16) { - goto yy39; + goto yy40; } if (yych <= '9') goto yy38; goto yy62; -yy41: - YYDEBUG(41, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy42; - } - goto yy40; yy42: YYDEBUG(42, *YYCURSOR); yyaccept = 1; @@ -501,29 +469,29 @@ yy42: if (yych <= 0x1F) { if (yych <= '\n') { if (yych <= 0x00) goto yy44; - if (yych <= 0x08) goto yy39; + if (yych <= 0x08) goto yy40; } else { - if (yych != '\r') goto yy39; + if (yych != '\r') goto yy40; } } else { if (yych <= '#') { if (yych <= ' ') goto yy44; - if (yych <= '"') goto yy39; + if (yych <= '"') goto yy40; } else { if (yych == ':') goto yy62; - goto yy39; + goto yy40; } } yy44: YYDEBUG(44, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 106 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 113 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } -#line 527 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 495 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy45: YYDEBUG(45, *YYCURSOR); yyaccept = 1; @@ -534,505 +502,560 @@ yy45: if (yych <= 0x1F) { if (yych <= '\n') { if (yych <= 0x00) goto yy44; - if (yych <= 0x08) goto yy40; + if (yych <= 0x08) goto yy41; goto yy44; } else { if (yych == '\r') goto yy44; - goto yy40; + goto yy41; } } else { if (yych <= '#') { if (yych <= ' ') goto yy44; - if (yych <= '"') goto yy40; + if (yych <= '"') goto yy41; goto yy44; } else { - if (yych == 'x') goto yy102; - goto yy40; + if (yych == 'x') goto yy101; + goto yy41; } } yy46: YYDEBUG(46, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'I') goto yy96; - if (yych == 'i') goto yy96; - goto yy40; + if (yych == 'I') goto yy95; + if (yych == 'i') goto yy95; + goto yy41; yy47: YYDEBUG(47, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'N') goto yy91; - if (yych == 'n') goto yy91; - goto yy40; + if (yych == 'N') goto yy90; + if (yych == 'n') goto yy90; + goto yy41; yy48: YYDEBUG(48, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy88; - if (yych == 'a') goto yy88; - goto yy40; + if (yych == 'A') goto yy87; + if (yych == 'a') goto yy87; + goto yy41; yy49: YYDEBUG(49, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'O') goto yy84; - if (yych == 'o') goto yy84; - goto yy40; + if (yych == 'O') goto yy83; + if (yych == 'o') goto yy83; + goto yy41; yy50: YYDEBUG(50, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'N') { - if (yych == 'F') goto yy83; - if (yych <= 'M') goto yy40; - goto yy77; + if (yych == 'F') goto yy82; + if (yych <= 'M') goto yy41; + goto yy76; } else { if (yych <= 'f') { - if (yych <= 'e') goto yy40; - goto yy83; + if (yych <= 'e') goto yy41; + goto yy82; } else { - if (yych == 'n') goto yy77; - goto yy40; + if (yych == 'n') goto yy76; + goto yy41; } } yy51: YYDEBUG(51, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'R') goto yy81; - if (yych == 'r') goto yy81; - goto yy40; + if (yych == 'R') goto yy80; + if (yych == 'r') goto yy80; + goto yy41; yy52: YYDEBUG(52, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy76; - if (yych == 'e') goto yy76; - goto yy40; + if (yych == 'E') goto yy75; + if (yych == 'e') goto yy75; + goto yy41; yy53: YYDEBUG(53, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy73; - goto yy40; + if (yych == 'E') goto yy72; + goto yy41; yy54: YYDEBUG(54, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych == 'e') goto yy61; - goto yy40; + goto yy41; yy55: YYDEBUG(55, *YYCURSOR); ++YYCURSOR; YYDEBUG(56, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 84 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 91 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return T_POUND; } -#line 634 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 602 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy57: YYDEBUG(57, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == ':') goto yy59; YYDEBUG(58, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 90 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 97 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return T_COLON; } -#line 645 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 613 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy59: YYDEBUG(59, *YYCURSOR); ++YYCURSOR; YYDEBUG(60, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 87 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 94 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return T_DCOLON; } -#line 655 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 623 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy61: YYDEBUG(61, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'n') goto yy67; - goto yy40; + if (yych == 'n') goto yy66; + goto yy41; yy62: YYDEBUG(62, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '/') goto yy64; -yy63: + if (yych != '/') goto yy31; YYDEBUG(63, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 1) { - if (yyaccept <= 0) { - goto yy38; - } else { - goto yy44; - } - } else { - if (yyaccept <= 2) { - goto yy72; - } else { - goto yy105; - } - } -yy64: - YYDEBUG(64, *YYCURSOR); yych = *++YYCURSOR; - if (yych != '/') goto yy63; - YYDEBUG(65, *YYCURSOR); + if (yych != '/') goto yy31; + YYDEBUG(64, *YYCURSOR); ++YYCURSOR; - YYDEBUG(66, *YYCURSOR); + YYDEBUG(65, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 78 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 85 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_PROTO; } -#line 697 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy67: +#line 648 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy66: + YYDEBUG(66, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != 'd') goto yy41; YYDEBUG(67, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'd') goto yy40; + if (yych != '_') goto yy41; +yy68: YYDEBUG(68, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych != '_') goto yy40; + if (yybm[0+yych] & 64) { + goto yy69; + } + goto yy41; yy69: YYDEBUG(69, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy70; - } - goto yy40; -yy70: - YYDEBUG(70, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(71, *YYCURSOR); + YYDEBUG(70, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy70; + goto yy69; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy72; - if (yych <= 0x08) goto yy39; + if (yych <= 0x00) goto yy71; + if (yych <= 0x08) goto yy40; } else { - if (yych != '\r') goto yy39; + if (yych != '\r') goto yy40; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy72; - if (yych <= '"') goto yy39; + if (yych <= ' ') goto yy71; + if (yych <= '"') goto yy40; } else { if (yych == ':') goto yy62; - goto yy39; + goto yy40; } } -yy72: - YYDEBUG(72, *YYCURSOR); +yy71: + YYDEBUG(71, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 118 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 125 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_OPCODE; } -#line 751 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy73: +#line 702 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy72: + YYDEBUG(72, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != 'N') goto yy41; YYDEBUG(73, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'N') goto yy40; + if (yych != 'D') goto yy41; YYDEBUG(74, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'D') goto yy40; + if (yych == '_') goto yy68; + goto yy41; +yy75: YYDEBUG(75, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == '_') goto yy69; - goto yy40; + if (yych == 'S') goto yy76; + if (yych != 's') goto yy41; yy76: YYDEBUG(76, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy77; - if (yych != 's') goto yy40; + if (yych == '\t') goto yy77; + if (yych != ' ') goto yy41; yy77: YYDEBUG(77, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy40; - if (yych >= '\v') goto yy40; - } else { - if (yych <= '\r') goto yy78; - if (yych != ' ') goto yy40; - } -yy78: - YYDEBUG(78, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; + YYDEBUG(78, *YYCURSOR); + if (yych == '\t') goto yy77; + if (yych == ' ') goto yy77; YYDEBUG(79, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy80; - if (yych <= '\n') goto yy78; - } else { - if (yych <= '\r') goto yy78; - if (yych == ' ') goto yy78; - } -yy80: - YYDEBUG(80, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 94 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 101 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return T_TRUTHY; } -#line 805 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 745 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy80: + YYDEBUG(80, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'U') goto yy81; + if (yych != 'u') goto yy41; yy81: YYDEBUG(81, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'U') goto yy82; - if (yych != 'u') goto yy40; + if (yych == 'E') goto yy76; + if (yych == 'e') goto yy76; + goto yy41; yy82: YYDEBUG(82, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy77; - if (yych == 'e') goto yy77; - goto yy40; + if (yych == 'F') goto yy83; + if (yych != 'f') goto yy41; yy83: YYDEBUG(83, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'F') goto yy84; - if (yych != 'f') goto yy40; + if (yych == '\t') goto yy84; + if (yych != ' ') goto yy41; yy84: YYDEBUG(84, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy40; - if (yych >= '\v') goto yy40; - } else { - if (yych <= '\r') goto yy85; - if (yych != ' ') goto yy40; - } -yy85: - YYDEBUG(85, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; + YYDEBUG(85, *YYCURSOR); + if (yych == '\t') goto yy84; + if (yych == ' ') goto yy84; YYDEBUG(86, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy87; - if (yych <= '\n') goto yy85; - } else { - if (yych <= '\r') goto yy85; - if (yych == ' ') goto yy85; - } -yy87: - YYDEBUG(87, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 100 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 107 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return T_FALSY; } -#line 858 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 787 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy87: + YYDEBUG(87, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'L') goto yy88; + if (yych != 'l') goto yy41; yy88: YYDEBUG(88, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy89; - if (yych != 'l') goto yy40; + if (yych == 'S') goto yy89; + if (yych != 's') goto yy41; yy89: YYDEBUG(89, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy90; - if (yych != 's') goto yy40; + if (yych == 'E') goto yy83; + if (yych == 'e') goto yy83; + goto yy41; yy90: YYDEBUG(90, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy84; - if (yych == 'e') goto yy84; - goto yy40; + if (yych == 'A') goto yy91; + if (yych != 'a') goto yy41; yy91: YYDEBUG(91, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy92; - if (yych != 'a') goto yy40; + if (yych == 'B') goto yy92; + if (yych != 'b') goto yy41; yy92: YYDEBUG(92, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'B') goto yy93; - if (yych != 'b') goto yy40; + if (yych == 'L') goto yy93; + if (yych != 'l') goto yy41; yy93: YYDEBUG(93, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy94; - if (yych != 'l') goto yy40; + if (yych == 'E') goto yy94; + if (yych != 'e') goto yy41; yy94: YYDEBUG(94, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy95; - if (yych != 'e') goto yy40; + if (yych == 'D') goto yy76; + if (yych == 'd') goto yy76; + goto yy41; yy95: YYDEBUG(95, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'D') goto yy77; - if (yych == 'd') goto yy77; - goto yy40; + if (yych == 'S') goto yy96; + if (yych != 's') goto yy41; yy96: YYDEBUG(96, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy97; - if (yych != 's') goto yy40; + if (yych == 'A') goto yy97; + if (yych != 'a') goto yy41; yy97: YYDEBUG(97, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy98; - if (yych != 'a') goto yy40; + if (yych == 'B') goto yy98; + if (yych != 'b') goto yy41; yy98: YYDEBUG(98, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'B') goto yy99; - if (yych != 'b') goto yy40; + if (yych == 'L') goto yy99; + if (yych != 'l') goto yy41; yy99: YYDEBUG(99, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy100; - if (yych != 'l') goto yy40; + if (yych == 'E') goto yy100; + if (yych != 'e') goto yy41; yy100: YYDEBUG(100, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy101; - if (yych != 'e') goto yy40; + if (yych == 'D') goto yy83; + if (yych == 'd') goto yy83; + goto yy41; yy101: YYDEBUG(101, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'D') goto yy84; - if (yych == 'd') goto yy84; - goto yy40; + if (yybm[0+yych] & 128) { + goto yy102; + } + goto yy41; yy102: YYDEBUG(102, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy103; - } - goto yy40; -yy103: - YYDEBUG(103, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(104, *YYCURSOR); + YYDEBUG(103, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy103; + goto yy102; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy105; - if (yych <= 0x08) goto yy39; + if (yych <= 0x00) goto yy104; + if (yych <= 0x08) goto yy40; } else { - if (yych != '\r') goto yy39; + if (yych != '\r') goto yy40; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy105; - if (yych <= '"') goto yy39; + if (yych <= ' ') goto yy104; + if (yych <= '"') goto yy40; } else { if (yych == ':') goto yy62; - goto yy39; + goto yy40; } } -yy105: - YYDEBUG(105, *YYCURSOR); +yy104: + YYDEBUG(104, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 112 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 119 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, 0, 16); return T_ADDR; } -#line 989 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy106: - YYDEBUG(106, *YYCURSOR); +#line 918 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy105: + YYDEBUG(105, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy40; - if (yych >= '\v') goto yy40; - } else { - if (yych <= '\r') goto yy107; - if (yych != ' ') goto yy40; - } -yy107: - YYDEBUG(107, *YYCURSOR); + if (yych == '\t') goto yy106; + if (yych != ' ') goto yy41; +yy106: + YYDEBUG(106, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; + YYDEBUG(107, *YYCURSOR); + if (yych == '\t') goto yy106; + if (yych == ' ') goto yy106; YYDEBUG(108, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy109; - if (yych <= '\n') goto yy107; - } else { - if (yych <= '\r') goto yy107; - if (yych == ' ') goto yy107; - } -yy109: - YYDEBUG(109, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 72 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 79 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_IF; } -#line 1023 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 941 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy109: + YYDEBUG(109, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= ',') { + if (yych <= '\t') { + if (yych <= 0x08) goto yy41; + } else { + if (yych != ' ') goto yy41; + } + } else { + if (yych <= '.') { + if (yych <= '-') goto yy112; + goto yy113; + } else { + if (yych <= '/') goto yy41; + if (yych <= '9') goto yy113; + goto yy41; + } + } +yy110: + YYDEBUG(110, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(111, *YYCURSOR); + if (yych <= ',') { + if (yych <= '\t') { + if (yych <= 0x08) goto yy31; + goto yy110; + } else { + if (yych == ' ') goto yy110; + goto yy31; + } + } else { + if (yych <= '.') { + if (yych <= '-') goto yy116; + goto yy117; + } else { + if (yych <= '/') goto yy31; + if (yych <= '9') goto yy117; + goto yy31; + } + } +yy112: + YYDEBUG(112, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == '.') goto yy113; + if (yych <= '/') goto yy41; + if (yych >= ':') goto yy41; +yy113: + YYDEBUG(113, *YYCURSOR); + yyaccept = 4; + YYMARKER = ++YYCURSOR; + YYFILL(3); + yych = *YYCURSOR; + YYDEBUG(114, *YYCURSOR); + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy115; + if (yych <= 0x08) goto yy40; + } else { + if (yych == '\r') goto yy115; + if (yych <= 0x1F) goto yy40; + } + } else { + if (yych <= '.') { + if (yych == '#') goto yy115; + if (yych <= '-') goto yy40; + goto yy113; + } else { + if (yych <= '/') goto yy40; + if (yych <= '9') goto yy113; + if (yych <= ':') goto yy62; + goto yy40; + } + } +yy115: + YYDEBUG(115, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 72 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" + { + char *text = yytext + 2; + while (*++text < '0'); + yylval->num = atoi(text); + return T_REQ_ID; +} +#line 1030 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy116: + YYDEBUG(116, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '.') goto yy117; + if (yych <= '/') goto yy31; + if (yych >= ':') goto yy31; +yy117: + YYDEBUG(117, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(118, *YYCURSOR); + if (yych == '.') goto yy117; + if (yych <= '/') goto yy115; + if (yych <= '9') goto yy117; + goto yy115; } /* *********************************** */ yyc_RAW: { static const unsigned char yybm[] = { 0, 64, 64, 64, 64, 64, 64, 64, - 64, 224, 128, 64, 64, 224, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 224, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, + 64, 96, 0, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 96, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 192, 64, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, @@ -1058,86 +1081,120 @@ yyc_RAW: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, }; - YYDEBUG(110, *YYCURSOR); + YYDEBUG(119, *YYCURSOR); YYFILL(2); yych = *YYCURSOR; if (yybm[0+yych] & 32) { - goto yy112; + goto yy121; } - if (yych <= 0x00) goto yy117; - if (yych == '\n') goto yy115; - goto yy118; -yy112: - YYDEBUG(112, *YYCURSOR); + if (yych <= '\n') { + if (yych <= 0x00) goto yy124; + if (yych <= '\t') goto yy127; + goto yy124; + } else { + if (yych == '-') goto yy126; + goto yy127; + } +yy121: + YYDEBUG(121, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(113, *YYCURSOR); + YYDEBUG(122, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy112; + goto yy121; } - if (yych <= 0x00) goto yy114; - if (yych == '\n') goto yy120; - goto yy118; -yy114: - YYDEBUG(114, *YYCURSOR); + if (yych <= 0x00) goto yy123; + if (yych != '\n') goto yy127; +yy123: + YYDEBUG(123, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 132 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 139 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_INPUT; } -#line 1093 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy115: - YYDEBUG(115, *YYCURSOR); +#line 1120 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy124: + YYDEBUG(124, *YYCURSOR); ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 128) { - goto yy120; - } -yy116: - YYDEBUG(116, *YYCURSOR); + YYDEBUG(125, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 1107 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy117: - YYDEBUG(117, *YYCURSOR); +#line 1130 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy126: + YYDEBUG(126, *YYCURSOR); yych = *++YYCURSOR; - goto yy116; -yy118: - YYDEBUG(118, *YYCURSOR); + if (yych == 'r') goto yy129; + goto yy128; +yy127: + YYDEBUG(127, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(119, *YYCURSOR); +yy128: + YYDEBUG(128, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy118; + goto yy127; } - goto yy114; -yy120: - YYDEBUG(120, *YYCURSOR); + goto yy123; +yy129: + YYDEBUG(129, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(130, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy132; + } + if (yych <= '\n') { + if (yych <= 0x00) goto yy123; + if (yych <= 0x08) goto yy127; + if (yych <= '\t') goto yy129; + goto yy123; + } else { + if (yych <= ' ') { + if (yych <= 0x1F) goto yy127; + goto yy129; + } else { + if (yych != '-') goto yy127; + } + } + YYDEBUG(131, *YYCURSOR); + yych = *++YYCURSOR; + if (yybm[0+yych] & 128) { + goto yy132; + } + goto yy128; +yy132: + YYDEBUG(132, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(121, *YYCURSOR); + YYDEBUG(133, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy120; + goto yy132; } - YYDEBUG(122, *YYCURSOR); + if (yych <= 0x00) goto yy134; + if (yych != '\n') goto yy127; +yy134: + YYDEBUG(134, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 72 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { - /* ignore whitespace */ - - goto restart; + char *text = yytext + 2; + while (*++text < '0'); + yylval->num = atoi(text); + return T_REQ_ID; } -#line 1139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 1196 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" } } -#line 168 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 175 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" } diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 7b3ce38c472..85603b7b529 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -56,7 +56,7 @@ T_SHELL 'sh' T_IF 'if' T_RUN 'run' T_RUN_SHORT "r" -WS [ \r\n\t]+ +WS [ \t]+ DIGITS [-]?[0-9\.]+ ID [^ \r\n\t:#\000]+ ADDR [0][x][a-fA-F0-9]+ @@ -69,6 +69,13 @@ INPUT [^\n\000]+ return 0; } +[-][r]{WS}?{DIGITS} { + char *text = yytext + 2; + while (*++text < '0'); + yylval->num = atoi(text); + return T_REQ_ID; +} + {T_IF}{WS} { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 6331cbc59e6..b50ab12f246 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -162,7 +162,8 @@ typedef void* yyscan_t; T_OPCODE = 272, T_ID = 273, T_INPUT = 274, - T_UNEXPECTED = 275 + T_UNEXPECTED = 275, + T_REQ_ID = 276 }; #endif /* Tokens. */ @@ -184,6 +185,7 @@ typedef void* yyscan_t; #define T_ID 273 #define T_INPUT 274 #define T_UNEXPECTED 275 +#define T_REQ_ID 276 @@ -200,7 +202,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 204 "sapi/phpdbg/phpdbg_parser.c" +#line 206 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -417,22 +419,22 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 25 +#define YYFINAL 26 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 42 +#define YYLAST 48 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 21 +#define YYNTOKENS 22 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 5 +#define YYNNTS 6 /* YYNRULES -- Number of rules. */ -#define YYNRULES 25 +#define YYNRULES 28 /* YYNRULES -- Number of states. */ -#define YYNSTATES 38 +#define YYNSTATES 43 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 275 +#define YYMAXUTOK 276 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -467,7 +469,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20 + 15, 16, 17, 18, 19, 20, 21 }; #if YYDEBUG @@ -475,30 +477,31 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 5, 7, 8, 10, 13, 17, 22, - 27, 33, 37, 43, 47, 50, 52, 54, 56, 58, - 60, 62, 64, 67, 70, 72 + 0, 0, 3, 5, 7, 8, 10, 13, 16, 20, + 25, 30, 36, 40, 46, 50, 53, 55, 57, 59, + 61, 63, 65, 67, 69, 70, 74, 78, 81 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 22, 0, -1, 23, -1, 25, -1, -1, 24, -1, - 23, 24, -1, 18, 10, 14, -1, 18, 10, 12, - 14, -1, 13, 18, 10, 14, -1, 13, 18, 10, - 12, 14, -1, 18, 11, 18, -1, 18, 11, 18, - 12, 14, -1, 18, 12, 14, -1, 6, 19, -1, - 17, -1, 16, -1, 15, -1, 7, -1, 8, -1, - 14, -1, 18, -1, 3, 19, -1, 5, 19, -1, - 4, -1, 4, 19, -1 + 23, 0, -1, 24, -1, 27, -1, -1, 25, -1, + 24, 25, -1, 24, 26, -1, 18, 10, 14, -1, + 18, 10, 12, 14, -1, 13, 18, 10, 14, -1, + 13, 18, 10, 12, 14, -1, 18, 11, 18, -1, + 18, 11, 18, 12, 14, -1, 18, 12, 14, -1, + 6, 19, -1, 17, -1, 16, -1, 15, -1, 7, + -1, 8, -1, 14, -1, 18, -1, 21, -1, -1, + 3, 26, 19, -1, 5, 26, 19, -1, 4, 26, + -1, 4, 26, 19, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 66, 66, 67, 68, 72, 73, 77, 82, 87, - 97, 107, 112, 118, 124, 129, 130, 131, 132, 133, - 134, 135, 139, 144, 149, 153 + 0, 67, 67, 68, 69, 73, 74, 75, 79, 84, + 89, 99, 109, 114, 120, 126, 131, 132, 133, 134, + 135, 136, 137, 141, 142, 146, 151, 156, 160 }; #endif @@ -514,8 +517,9 @@ static const char *const yytname[] = "\":: (double colon)\"", "\"# (pound sign)\"", "\"protocol (file://)\"", "\"digits (numbers)\"", "\"literal (string)\"", "\"address\"", "\"opcode\"", "\"identifier (command or function name)\"", - "\"input (input string or data)\"", "\"input\"", "$accept", "input", - "parameters", "parameter", "full_expression", 0 + "\"input (input string or data)\"", "\"input\"", + "\"request id (-r %d)\"", "$accept", "input", "parameters", "parameter", + "req_id", "full_expression", 0 }; #endif @@ -526,24 +530,24 @@ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275 + 275, 276 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 21, 22, 22, 22, 23, 23, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 25, 25, 25, 25 + 0, 22, 23, 23, 23, 24, 24, 24, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 26, 26, 27, 27, 27, 27 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 1, 0, 1, 2, 3, 4, 4, - 5, 3, 5, 3, 2, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 1, 2 + 0, 2, 1, 1, 0, 1, 2, 2, 3, 4, + 4, 5, 3, 5, 3, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 3, 3, 2, 3 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -551,33 +555,35 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 4, 0, 24, 0, 0, 18, 19, 0, 20, 17, - 16, 15, 21, 0, 2, 5, 3, 22, 25, 23, - 14, 0, 0, 0, 0, 1, 6, 0, 0, 7, - 11, 13, 0, 9, 8, 0, 10, 12 + 4, 24, 24, 24, 0, 19, 20, 0, 21, 18, + 17, 16, 22, 0, 2, 5, 3, 23, 0, 27, + 0, 15, 0, 0, 0, 0, 1, 6, 7, 25, + 28, 26, 0, 0, 8, 12, 14, 0, 10, 9, + 0, 11, 13 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 13, 14, 15, 16 + -1, 13, 14, 15, 18, 16 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -11 +#define YYPACT_NINF -16 static const yytype_int8 yypact[] = { - -3, -10, 11, 12, 13, -11, -11, 15, -11, -11, - -11, -11, -4, 29, 10, -11, -11, -11, -11, -11, - -11, 24, 7, 17, 22, -11, -11, 8, 23, -11, - 26, -11, 25, -11, -11, 27, -11, -11 + -3, -15, -15, -15, -10, -16, -16, 3, -16, -16, + -16, -16, 22, 29, 10, -16, -16, -16, 11, 17, + 19, -16, 30, 8, 21, 27, -16, -16, -16, -16, + -16, -16, 23, 28, -16, 31, -16, 32, -16, -16, + 33, -16, -16 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -11, -11, -11, 28, -11 + -16, -16, -16, 34, 5, -16 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -586,26 +592,26 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 1, 2, 3, 4, 5, 6, 22, 23, 24, 17, + 1, 2, 3, 4, 5, 6, 17, 19, 20, 21, 7, 8, 9, 10, 11, 12, 4, 5, 6, 28, - 32, 29, 33, 7, 8, 9, 10, 11, 12, 25, - 18, 19, 20, 21, 27, 30, 31, 34, 35, 36, - 0, 37, 26 + 33, 22, 34, 7, 8, 9, 10, 11, 12, 26, + 29, 17, 23, 24, 25, 37, 30, 38, 31, 35, + 32, 36, 39, 40, 0, 0, 41, 42, 27 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-11)) + ((yystate) == (-16)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = { - 3, 4, 5, 6, 7, 8, 10, 11, 12, 19, - 13, 14, 15, 16, 17, 18, 6, 7, 8, 12, - 12, 14, 14, 13, 14, 15, 16, 17, 18, 0, - 19, 19, 19, 18, 10, 18, 14, 14, 12, 14, - -1, 14, 14 + 3, 4, 5, 6, 7, 8, 21, 2, 3, 19, + 13, 14, 15, 16, 17, 18, 6, 7, 8, 14, + 12, 18, 14, 13, 14, 15, 16, 17, 18, 0, + 19, 21, 10, 11, 12, 12, 19, 14, 19, 18, + 10, 14, 14, 12, -1, -1, 14, 14, 14 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -613,9 +619,10 @@ static const yytype_int8 yycheck[] = static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 6, 7, 8, 13, 14, 15, - 16, 17, 18, 22, 23, 24, 25, 19, 19, 19, - 19, 18, 10, 11, 12, 0, 24, 10, 12, 14, - 18, 14, 12, 14, 14, 12, 14, 14 + 16, 17, 18, 23, 24, 25, 27, 21, 26, 26, + 26, 19, 18, 10, 11, 12, 0, 25, 26, 19, + 19, 19, 10, 12, 14, 18, 14, 12, 14, 14, + 12, 14, 14 }; #define yyerrok (yyerrstatus = 0) @@ -1457,28 +1464,35 @@ yyreduce: case 3: /* Line 1806 of yacc.c */ -#line 67 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); } break; case 5: /* Line 1806 of yacc.c */ -#line 72 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 73 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); } break; case 6: /* Line 1806 of yacc.c */ -#line 73 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 74 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(2) - (2)])); } break; case 7: /* Line 1806 of yacc.c */ -#line 77 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 75 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (2)]); } + break; + + case 8: + +/* Line 1806 of yacc.c */ +#line 79 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = FILE_PARAM; (yyval).file.name = (yyvsp[(2) - (3)]).str; @@ -1486,10 +1500,10 @@ yyreduce: } break; - case 8: + case 9: /* Line 1806 of yacc.c */ -#line 82 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 84 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; (yyval).file.name = (yyvsp[(1) - (4)]).str; @@ -1497,10 +1511,10 @@ yyreduce: } break; - case 9: + case 10: /* Line 1806 of yacc.c */ -#line 87 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 89 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = FILE_PARAM; (yyval).file.name = malloc((yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len + 1); @@ -1513,10 +1527,10 @@ yyreduce: } break; - case 10: + case 11: /* Line 1806 of yacc.c */ -#line 97 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 99 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; (yyval).file.name = malloc((yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len + 1); @@ -1529,10 +1543,10 @@ yyreduce: } break; - case 11: + case 12: /* Line 1806 of yacc.c */ -#line 107 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 109 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (3)]).str; @@ -1540,10 +1554,10 @@ yyreduce: } break; - case 12: + case 13: /* Line 1806 of yacc.c */ -#line 112 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 114 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (5)]).str; @@ -1552,10 +1566,10 @@ yyreduce: } break; - case 13: + case 14: /* Line 1806 of yacc.c */ -#line 118 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 120 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FUNCTION_PARAM; (yyval).str = (yyvsp[(1) - (3)]).str; @@ -1564,10 +1578,10 @@ yyreduce: } break; - case 14: + case 15: /* Line 1806 of yacc.c */ -#line 124 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 126 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = COND_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1575,102 +1589,109 @@ yyreduce: } break; - case 15: - -/* Line 1806 of yacc.c */ -#line 129 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - case 16: -/* Line 1806 of yacc.c */ -#line 130 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 17: - /* Line 1806 of yacc.c */ #line 131 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 18: + case 17: /* Line 1806 of yacc.c */ #line 132 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 19: + case 18: /* Line 1806 of yacc.c */ #line 133 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 20: + case 19: /* Line 1806 of yacc.c */ #line 134 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 21: + case 20: /* Line 1806 of yacc.c */ #line 135 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; + case 21: + +/* Line 1806 of yacc.c */ +#line 136 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + case 22: /* Line 1806 of yacc.c */ -#line 139 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" - { - (yyval).type = EVAL_PARAM; - (yyval).str = (yyvsp[(2) - (2)]).str; - (yyval).len = (yyvsp[(2) - (2)]).len; - } +#line 137 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 23: /* Line 1806 of yacc.c */ -#line 144 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" - { - (yyval).type = SHELL_PARAM; - (yyval).str = (yyvsp[(2) - (2)]).str; - (yyval).len = (yyvsp[(2) - (2)]).len; +#line 141 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" + { PHPDBG_G(req_id) = (yyvsp[(1) - (1)]).num; } + break; + + case 25: + +/* Line 1806 of yacc.c */ +#line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = EVAL_PARAM; + (yyval).str = (yyvsp[(2) - (3)]).str; + (yyval).len = (yyvsp[(2) - (3)]).len; } break; - case 24: + case 26: /* Line 1806 of yacc.c */ -#line 149 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 151 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" + { + (yyval).type = SHELL_PARAM; + (yyval).str = (yyvsp[(2) - (3)]).str; + (yyval).len = (yyvsp[(2) - (3)]).len; + } + break; + + case 27: + +/* Line 1806 of yacc.c */ +#line 156 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; (yyval).len = 0; } break; - case 25: + case 28: /* Line 1806 of yacc.c */ -#line 153 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 160 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; - (yyval).str = (yyvsp[(2) - (2)]).str; - (yyval).len = (yyvsp[(2) - (2)]).len; + (yyval).str = (yyvsp[(2) - (3)]).str; + (yyval).len = (yyvsp[(2) - (3)]).len; } break; /* Line 1806 of yacc.c */ -#line 1674 "sapi/phpdbg/phpdbg_parser.c" +#line 1695 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1901,7 +1922,7 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 160 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" +#line 167 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" static int yyerror(void ***tsrm_ls, const char *msg) { diff --git a/phpdbg_parser.h b/phpdbg_parser.h index 286e7ff1084..dfa155d7184 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -69,7 +69,8 @@ typedef void* yyscan_t; T_OPCODE = 272, T_ID = 273, T_INPUT = 274, - T_UNEXPECTED = 275 + T_UNEXPECTED = 275, + T_REQ_ID = 276 }; #endif /* Tokens. */ @@ -91,6 +92,7 @@ typedef void* yyscan_t; #define T_ID 273 #define T_INPUT 274 #define T_UNEXPECTED 275 +#define T_REQ_ID 276 diff --git a/phpdbg_parser.y b/phpdbg_parser.y index 702bf78455d..3af4552538d 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -59,6 +59,7 @@ typedef void* yyscan_t; %token T_ID "identifier (command or function name)" %token T_INPUT "input (input string or data)" %token T_UNEXPECTED "input" +%token T_REQ_ID "request id (-r %d)" %% /* Rules */ @@ -71,6 +72,7 @@ input parameters : parameter { phpdbg_stack_push(PHPDBG_G(parser_stack), &$1); } | parameters parameter { phpdbg_stack_push(PHPDBG_G(parser_stack), &$2); } + | parameters req_id { $$ = $1; } ; parameter @@ -135,22 +137,27 @@ parameter | T_ID { $$ = $1; } ; +req_id + : T_REQ_ID { PHPDBG_G(req_id) = $1.num; } + | /* empty */ +; + full_expression - : T_EVAL T_INPUT { + : T_EVAL req_id T_INPUT { $$.type = EVAL_PARAM; $$.str = $2.str; $$.len = $2.len; } - | T_SHELL T_INPUT { + | T_SHELL req_id T_INPUT { $$.type = SHELL_PARAM; $$.str = $2.str; $$.len = $2.len; } - | T_RUN { + | T_RUN req_id { $$.type = RUN_PARAM; $$.len = 0; } - | T_RUN T_INPUT { + | T_RUN req_id T_INPUT { $$.type = RUN_PARAM; $$.str = $2.str; $$.len = $2.len; @@ -160,7 +167,7 @@ full_expression %% static int yyerror(void ***tsrm_ls, const char *msg) { - phpdbg_error("Parse Error: %s", msg); + phpdbg_error("command", "type=\"parseerror\" msg=\"%s\"", "Parse Error: %s", msg); { const phpdbg_param_t *top = PHPDBG_G(parser_stack); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index a72292eb56a..c34217019b8 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -992,6 +992,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); + PHPDBG_G(req_id) = 0; } while ((input = phpdbg_read_input(NULL TSRMLS_CC))); } @@ -999,6 +1000,7 @@ out: if (input) { phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); + PHPDBG_G(req_id) = 0; } if (EG(in_execution)) { diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 1151f3f1192..782a8f085f9 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1150,7 +1150,12 @@ static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char } - if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + if (PHPDBG_G(req_id)) { + char *xmlbuf = NULL; + xmllen = asprintf(&xmlbuf, "req=\"%lu\" %.*s", PHPDBG_G(req_id), xmllen, xml); + xml = xmlbuf; + } if (msgout) { buf = php_escape_html_entities((unsigned char *) msgout, msgoutlen, (size_t *) &buflen, 0, ENT_COMPAT, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); xmloutlen = fprintf(fp, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf); @@ -1163,6 +1168,10 @@ static int phpdbg_process_print(FILE *fp, int type, const char *tag, const char fprintf(fp, "%.*s", msgoutlen, msgout); } + if (PHPDBG_G(req_id) && (PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { + free((char *) xml); + } + if (msgout) { free(msgout); } From abd75ea2c5d28f61ca02092aaea600917ddc008c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 6 Oct 2014 11:46:39 +0200 Subject: [PATCH 037/125] Fix frames output --- phpdbg_frame.c | 31 +++++++++++++++++-------------- phpdbg_utils.c | 8 +++++++- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 8c7b1084ea9..eb4a9a8b4d1 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -104,6 +104,7 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ { zval **funcname, **class, **type, **args, **argstmp; char is_class; + int has_args = FAILURE; zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), (void **)&funcname); @@ -121,19 +122,26 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type); } + has_args = zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), (void **)&args) == SUCCESS; + phpdbg_xml(" symbol=\"%s%s%s\"", is_class == FAILURE?"":Z_STRVAL_PP(class), is_class == FAILURE?"":Z_STRVAL_PP(type), Z_STRVAL_PP(funcname) ); + if (has_args) { + phpdbg_xml(">"); + } else { + phpdbg_xml(" />"); + } + phpdbg_out("%s%s%s(", is_class == FAILURE?"":Z_STRVAL_PP(class), is_class == FAILURE?"":Z_STRVAL_PP(type), Z_STRVAL_PP(funcname) ); - if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), - (void **)&args) == SUCCESS) { + if (has_args) { HashPosition iterator; const zend_function *func = phpdbg_get_function( Z_STRVAL_PP(funcname), is_class == FAILURE ? NULL : Z_STRVAL_PP(class) TSRMLS_CC); @@ -141,8 +149,6 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ int j = 0, m = func ? func->common.num_args : 0; zend_bool is_variadic = 0; - phpdbg_xml(">"); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { @@ -154,15 +160,14 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ #if PHP_VERSION_ID >= 50600 is_variadic = arginfo[j].is_variadic; #endif - phpdbg_xml(" variadic=\"%s\" name=\"%s\"", is_variadic ? "variadic" : "", arginfo[j].name); + phpdbg_xml(" variadic=\"%s\" name=\"%s\">", is_variadic ? "variadic" : "", arginfo[j].name); + phpdbg_out("%s=%s", arginfo[j].name, is_variadic ? "[": ""); - phpdbg_out("%s=%s", - arginfo[j].name, is_variadic ? "[": ""); + } else { + phpdbg_xml(">"); } ++j; - phpdbg_xml(">"); - zend_print_flat_zval_r(*argstmp TSRMLS_CC); zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); @@ -172,8 +177,6 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ phpdbg_out("]"); } phpdbg_xml(""); - } else { - phpdbg_xml(" />"); } phpdbg_out(")"); } @@ -210,13 +213,13 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ } if (user_defined == SUCCESS) { - phpdbg_xml(" "); + phpdbg_xml(""); + phpdbg_xml(""); } /* }}} */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 782a8f085f9..c303bc16654 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -771,6 +771,12 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca break; + case 'r': + s_len = asprintf(&s, "req=\"%lu\"", PHPDBG_G(req_id)); + free_s = s; + break; + + case 'f': case 'F': case 'e': @@ -1279,7 +1285,7 @@ PHPDBG_API int phpdbg_xml_internal(FILE *fp TSRMLS_DC, const char *fmt, ...) { int buflen; va_start(args, fmt); - buflen = vspprintf(&buffer, 0, fmt, args); + buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); va_end(args); if (PHPDBG_G(in_script_xml)) { From 699497e99f27571c21b45d3bc8335a207ad75cdd Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 6 Oct 2014 13:20:04 +0200 Subject: [PATCH 038/125] Add request id to --- phpdbg_frame.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index eb4a9a8b4d1..ea631223dec 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -155,7 +155,7 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ if (j) { phpdbg_out(", "); } - phpdbg_xml("= 50600 is_variadic = arginfo[j].is_variadic; @@ -194,7 +194,7 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ phpdbg_error("backtrace", "type=\"minnum\"", "Invalid backtrace size %d", limit); } - phpdbg_xml(""); + phpdbg_xml(""); zend_fetch_debug_backtrace( &zbacktrace, 0, 0, limit TSRMLS_CC); From 2422c70c4f722c3afbdc5547116c6ecadfaf4954 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 6 Oct 2014 22:34:41 +0200 Subject: [PATCH 039/125] " => &quot; in md document --- xml.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml.md b/xml.md index a178ca74db9..15920d2ac7f 100644 --- a/xml.md +++ b/xml.md @@ -16,7 +16,7 @@ severity msgout ------ -- text message output related to the xml data (e.g. <intro severity="normal" help="help" msgout="To get help using phpdbg type "help" and press enter" />) +- text message output related to the xml data (e.g. <intro severity="normal" help="help" msgout="To get help using phpdbg type &quot;help&quot; and press enter" />) file ---- From 556ed2d3f46b277ad38261ffcc4eb2faa5d14282 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 7 Oct 2014 10:28:21 +0100 Subject: [PATCH 040/125] fix mistake in help --- phpdbg_help.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 57d70c3581b..c3b8b467e70 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -643,7 +643,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **break** **b** show current breakpoints" CR " **files** **F** show included files" CR " **classes** **c** show loaded classes" CR -" **funcs** **f** show loaded classes" CR +" **funcs** **f** show loaded functions" CR " **error** **e** show last error" CR " **vars** **v** show active variables" CR " **globals** **g** show superglobal variables" CR From f545ef48eba6c3c9e8b849a15deefdda76920807 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 7 Oct 2014 11:30:26 +0100 Subject: [PATCH 041/125] fix case insensitivity for registered functions --- phpdbg_prompt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 2196c21e925..ef2ba6fa3ba 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -91,19 +91,23 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * phpdbg_param_t *name = NULL; if (stack->type == STACK_PARAM) { + char *lc_name; + name = stack->next; if (!name || name->type != STR_PARAM) { return FAILURE; } + lc_name = zend_str_tolower_dup(name->str, name->len); + if (zend_hash_exists( - &PHPDBG_G(registered), name->str, name->len+1)) { + &PHPDBG_G(registered), lc_name, name->len+1)) { zval fname, *fretval; zend_fcall_info fci; - ZVAL_STRINGL(&fname, name->str, name->len, 1); + ZVAL_STRINGL(&fname, lc_name, name->len, 1); memset(&fci, 0, sizeof(zend_fcall_info)); @@ -195,9 +199,12 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * } zval_dtor(&fname); + efree(lc_name); return SUCCESS; } + + efree(lc_name); } return FAILURE; From 4b3a11debbead58c9034dbf34218b9cd2bb885a5 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 7 Oct 2014 12:36:03 +0100 Subject: [PATCH 042/125] make build work moar --- phpdbg_wait.c | 5 ++++- phpdbg_webdata_transfer.c | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/phpdbg_wait.c b/phpdbg_wait.c index e2bded08750..11279a9ab29 100644 --- a/phpdbg_wait.c +++ b/phpdbg_wait.c @@ -127,6 +127,7 @@ static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) { } void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { +#ifdef HAVE_JSON zval *free_zv = NULL; zval zv, **zvpp; HashTable *ht; @@ -357,10 +358,12 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) { /* Reapply raw input */ /* ??? */ +#endif } PHPDBG_COMMAND(wait) /* {{{ */ { +#ifdef HAVE_JSON struct sockaddr_un local, remote; int rlen, sr, sl; unlink(PHPDBG_G(socket_path)); @@ -412,5 +415,5 @@ PHPDBG_COMMAND(wait) /* {{{ */ phpdbg_notice("Successfully imported request data, stopped before executing"); return SUCCESS; +#endif } /* }}} */ - diff --git a/phpdbg_webdata_transfer.c b/phpdbg_webdata_transfer.c index 8ca308556c6..e7438ea01ab 100644 --- a/phpdbg_webdata_transfer.c +++ b/phpdbg_webdata_transfer.c @@ -20,6 +20,7 @@ #include "ext/json/php_json.h" PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) { +#ifdef HAVE_JSON smart_str buf = {0}; zval array; HashTable *ht; @@ -180,4 +181,5 @@ PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) { *msg = buf.c; *len = buf.len; zval_dtor(&array); +#endif } From eabcdb2eb28e423aff6bb5ff575416c42a0dc3e6 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 8 Oct 2014 00:14:31 +0200 Subject: [PATCH 043/125] Fix bug which causes inf loop on \r\n --- phpdbg_lexer.c | 1292 +++++++++++++++++++++++++----------------------- phpdbg_lexer.l | 2 +- 2 files changed, 681 insertions(+), 613 deletions(-) diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 3092dc396dd..af044937e3b 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -1,5 +1,5 @@ /* Generated by re2c 0.13.5 */ -#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 1 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" /* * phpdbg_lexer.l */ @@ -44,7 +44,7 @@ restart: LEX(text) = YYCURSOR; -#line 48 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 48 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -62,10 +62,10 @@ yyc_INITIAL: { static const unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 128, 128, 0, 0, 128, 0, 0, + 0, 192, 96, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 0, 0, 0, + 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -98,1016 +98,1049 @@ yyc_INITIAL: YYDEBUG(0, *YYCURSOR); YYFILL(4); yych = *YYCURSOR; - if (yych <= 'D') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy6; - if (yych <= 0x08) goto yy11; - if (yych >= '\n') goto yy4; + if (yybm[0+yych] & 32) { + goto yy4; + } + if (yych <= 'E') { + if (yych <= '\f') { + if (yych <= 0x00) goto yy7; + if (yych != '\t') goto yy12; } else { - if (yych <= '\r') { - if (yych <= '\f') goto yy11; + if (yych <= 0x1F) { + if (yych >= 0x0E) goto yy12; } else { - if (yych != ' ') goto yy11; + if (yych <= ' ') goto yy2; + if (yych <= 'D') goto yy12; + goto yy8; } } } else { if (yych <= 'd') { - if (yych <= 'Q') { - if (yych <= 'E') goto yy7; - goto yy11; - } else { - if (yych <= 'R') goto yy10; - if (yych <= 'S') goto yy8; - goto yy11; - } + if (yych <= 'Q') goto yy12; + if (yych <= 'R') goto yy11; + if (yych <= 'S') goto yy9; + goto yy12; } else { if (yych <= 'q') { - if (yych <= 'e') goto yy7; - goto yy11; + if (yych <= 'e') goto yy8; + goto yy12; } else { - if (yych <= 'r') goto yy9; - if (yych <= 's') goto yy8; - goto yy11; + if (yych <= 'r') goto yy10; + if (yych <= 's') goto yy9; + goto yy12; } } } +yy2: YYDEBUG(2, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '\f') { + if (yych <= 0x00) goto yy29; if (yych <= 0x08) goto yy3; - if (yych <= '\n') goto yy26; + if (yych <= '\n') goto yy29; } else { - if (yych <= '\r') goto yy26; - if (yych == ' ') goto yy26; + if (yych <= '\r') goto yy29; + if (yych == ' ') goto yy29; } yy3: YYDEBUG(3, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 161 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 161 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(NORMAL); YYCURSOR = LEX(text); goto restart; } -#line 154 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 156 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy4: YYDEBUG(4, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) <= '\f') { - if (yych <= 0x08) goto yy5; - if (yych <= '\n') goto yy26; - } else { - if (yych <= '\r') goto yy26; - if (yych == ' ') goto yy26; - } -yy5: + YYFILL(1); + yych = *YYCURSOR; YYDEBUG(5, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy28; + } + if (yych <= 0x00) goto yy27; + if (yych == '\n') goto yy4; +yy6: + YYDEBUG(6, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 68 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 172 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy6: - YYDEBUG(6, *YYCURSOR); - yych = *++YYCURSOR; - goto yy3; +#line 175 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy7: YYDEBUG(7, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'V') goto yy22; - if (yych == 'v') goto yy22; + yych = *++YYCURSOR; goto yy3; yy8: YYDEBUG(8, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'H') goto yy18; - if (yych == 'h') goto yy18; + if (yych == 'V') goto yy23; + if (yych == 'v') goto yy23; goto yy3; yy9: YYDEBUG(9, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy15; - } - if (yych == 'U') goto yy12; - if (yych == 'u') goto yy12; + if (yych == 'H') goto yy19; + if (yych == 'h') goto yy19; goto yy3; yy10: YYDEBUG(10, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'U') goto yy12; - if (yych == 'u') goto yy12; + if (yybm[0+yych] & 64) { + goto yy16; + } + if (yych == 'U') goto yy13; + if (yych == 'u') goto yy13; goto yy3; yy11: YYDEBUG(11, *YYCURSOR); - yych = *++YYCURSOR; + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'U') goto yy13; + if (yych == 'u') goto yy13; goto yy3; yy12: YYDEBUG(12, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy14; - if (yych == 'n') goto yy14; + goto yy3; yy13: YYDEBUG(13, *YYCURSOR); - YYCURSOR = YYMARKER; - goto yy3; + yych = *++YYCURSOR; + if (yych == 'N') goto yy15; + if (yych == 'n') goto yy15; yy14: YYDEBUG(14, *YYCURSOR); - yych = *++YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy15; - } - goto yy13; + YYCURSOR = YYMARKER; + goto yy3; yy15: YYDEBUG(15, *YYCURSOR); + yych = *++YYCURSOR; + if (yybm[0+yych] & 64) { + goto yy16; + } + goto yy14; +yy16: + YYDEBUG(16, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(16, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy15; - } YYDEBUG(17, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy16; + } + YYDEBUG(18, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 155 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 155 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_RUN; } -#line 245 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy18: - YYDEBUG(18, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\f') { - if (yych <= 0x08) goto yy13; - if (yych >= '\v') goto yy13; - } else { - if (yych <= '\r') goto yy19; - if (yych != ' ') goto yy13; - } +#line 248 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy19: YYDEBUG(19, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\f') { + if (yych <= 0x08) goto yy14; + if (yych >= '\v') goto yy14; + } else { + if (yych <= '\r') goto yy20; + if (yych != ' ') goto yy14; + } +yy20: + YYDEBUG(20, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(20, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy21; - if (yych <= '\n') goto yy19; - } else { - if (yych <= '\r') goto yy19; - if (yych == ' ') goto yy19; - } -yy21: YYDEBUG(21, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy22; + if (yych <= '\n') goto yy20; + } else { + if (yych <= '\r') goto yy20; + if (yych == ' ') goto yy20; + } +yy22: + YYDEBUG(22, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 150 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 150 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } -#line 278 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy22: - YYDEBUG(22, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\f') { - if (yych <= 0x08) goto yy13; - if (yych >= '\v') goto yy13; - } else { - if (yych <= '\r') goto yy23; - if (yych != ' ') goto yy13; - } +#line 281 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy23: YYDEBUG(23, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\f') { + if (yych <= 0x08) goto yy14; + if (yych >= '\v') goto yy14; + } else { + if (yych <= '\r') goto yy24; + if (yych != ' ') goto yy14; + } +yy24: + YYDEBUG(24, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(24, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy25; - if (yych <= '\n') goto yy23; - } else { - if (yych <= '\r') goto yy23; - if (yych == ' ') goto yy23; - } -yy25: YYDEBUG(25, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy26; + if (yych <= '\n') goto yy24; + } else { + if (yych <= '\r') goto yy24; + if (yych == ' ') goto yy24; + } +yy26: + YYDEBUG(26, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 145 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 145 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_EVAL; } -#line 311 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy26: - YYDEBUG(26, *YYCURSOR); +#line 314 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy27: + YYDEBUG(27, *YYCURSOR); + yych = *++YYCURSOR; + goto yy6; +yy28: + YYDEBUG(28, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(27, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy28; - if (yych <= '\n') goto yy26; - } else { - if (yych <= '\r') goto yy26; - if (yych == ' ') goto yy26; +yy29: + YYDEBUG(29, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy28; } -yy28: - YYDEBUG(28, *YYCURSOR); + if (yych <= 0x00) goto yy27; + if (yych == '\n') goto yy4; + YYDEBUG(30, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 139 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ goto restart; } -#line 334 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 339 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" } /* *********************************** */ yyc_NORMAL: { static const unsigned char yybm[] = { - 0, 16, 16, 16, 16, 16, 16, 16, - 16, 8, 8, 16, 16, 8, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 16, 0, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 48, 16, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 0, 16, 16, 16, 16, 16, - 16, 208, 208, 208, 208, 208, 208, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 16, 16, 16, 16, 16, - 16, 208, 208, 208, 208, 208, 208, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, + 0, 8, 8, 8, 8, 8, 8, 8, + 8, 66, 68, 8, 8, 66, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 66, 8, 8, 0, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 24, 8, + 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 0, 8, 8, 8, 8, 8, + 8, 168, 168, 168, 168, 168, 168, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 8, 8, 8, 8, 8, + 8, 168, 168, 168, 168, 168, 168, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, }; - YYDEBUG(29, *YYCURSOR); + YYDEBUG(31, *YYCURSOR); YYFILL(11); yych = *YYCURSOR; - YYDEBUG(-1, yych); - switch (yych) { - case 0x00: goto yy36; - case '\t': - case '\r': - case ' ': goto yy31; - case '\n': goto yy34; - case '#': goto yy55; - case '-': goto yy41; - case '.': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy42; - case '0': goto yy45; - case ':': goto yy57; - case 'D': - case 'd': goto yy46; - case 'E': - case 'e': goto yy47; - case 'F': - case 'f': goto yy48; - case 'I': - case 'i': goto yy37; - case 'N': - case 'n': goto yy49; - case 'O': - case 'o': goto yy50; - case 'T': - case 't': goto yy51; - case 'Y': - case 'y': goto yy52; - case 'Z': goto yy53; - case 'z': goto yy54; - default: goto yy39; + if (yybm[0+yych] & 2) { + goto yy33; } -yy31: - YYDEBUG(31, *YYCURSOR); + if (yych <= 'N') { + if (yych <= '0') { + if (yych <= '#') { + if (yych <= '\t') { + if (yych <= 0x00) goto yy39; + goto yy42; + } else { + if (yych <= '\n') goto yy36; + if (yych <= '"') goto yy42; + goto yy58; + } + } else { + if (yych <= '-') { + if (yych <= ',') goto yy42; + goto yy44; + } else { + if (yych <= '.') goto yy45; + if (yych <= '/') goto yy42; + goto yy48; + } + } + } else { + if (yych <= 'E') { + if (yych <= ':') { + if (yych <= '9') goto yy45; + goto yy60; + } else { + if (yych <= 'C') goto yy42; + if (yych <= 'D') goto yy49; + goto yy50; + } + } else { + if (yych <= 'H') { + if (yych <= 'F') goto yy51; + goto yy42; + } else { + if (yych <= 'I') goto yy40; + if (yych <= 'M') goto yy42; + goto yy52; + } + } + } + } else { + if (yych <= 'f') { + if (yych <= 'Y') { + if (yych <= 'S') { + if (yych <= 'O') goto yy53; + goto yy42; + } else { + if (yych <= 'T') goto yy54; + if (yych <= 'X') goto yy42; + goto yy55; + } + } else { + if (yych <= 'c') { + if (yych <= 'Z') goto yy56; + goto yy42; + } else { + if (yych <= 'd') goto yy49; + if (yych <= 'e') goto yy50; + goto yy51; + } + } + } else { + if (yych <= 'o') { + if (yych <= 'i') { + if (yych <= 'h') goto yy42; + goto yy40; + } else { + if (yych <= 'm') goto yy42; + if (yych <= 'n') goto yy52; + goto yy53; + } + } else { + if (yych <= 'x') { + if (yych == 't') goto yy54; + goto yy42; + } else { + if (yych <= 'y') goto yy55; + if (yych <= 'z') goto yy57; + goto yy42; + } + } + } + } +yy33: + YYDEBUG(33, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(32, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy31; + YYDEBUG(34, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy33; } - YYDEBUG(33, *YYCURSOR); + if (yych <= 0x00) goto yy39; + if (yych == '\n') goto yy36; + YYDEBUG(35, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 139 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ goto restart; } -#line 434 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy34: - YYDEBUG(34, *YYCURSOR); - ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 8) { - goto yy31; - } -yy35: - YYDEBUG(35, *YYCURSOR); - yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" - { - return 0; -} -#line 448 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 488 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy36: YYDEBUG(36, *YYCURSOR); - yych = *++YYCURSOR; - goto yy35; -yy37: + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; YYDEBUG(37, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'F') goto yy106; - if (yych == 'f') goto yy106; - goto yy40; + if (yybm[0+yych] & 2) { + goto yy33; + } + if (yych <= 0x00) goto yy39; + if (yych == '\n') goto yy36; yy38: YYDEBUG(38, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 125 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 68 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + return 0; +} +#line 507 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy39: + YYDEBUG(39, *YYCURSOR); + yych = *++YYCURSOR; + goto yy38; +yy40: + YYDEBUG(40, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'F') goto yy109; + if (yych == 'f') goto yy109; + goto yy43; +yy41: + YYDEBUG(41, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 125 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_ID; } -#line 470 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy39: - YYDEBUG(39, *YYCURSOR); +#line 529 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy42: + YYDEBUG(42, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; -yy40: - YYDEBUG(40, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy39; - } - if (yych <= '9') goto yy38; - goto yy62; -yy41: - YYDEBUG(41, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 32) { +yy43: + YYDEBUG(43, *YYCURSOR); + if (yybm[0+yych] & 8) { goto yy42; } - goto yy40; -yy42: - YYDEBUG(42, *YYCURSOR); + if (yych <= '9') goto yy41; + goto yy65; +yy44: + YYDEBUG(44, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy45; + } + goto yy43; +yy45: + YYDEBUG(45, *YYCURSOR); yyaccept = 1; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(43, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy42; + YYDEBUG(46, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy45; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy44; - if (yych <= 0x08) goto yy39; + if (yych <= 0x00) goto yy47; + if (yych <= 0x08) goto yy42; } else { - if (yych != '\r') goto yy39; + if (yych != '\r') goto yy42; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy44; - if (yych <= '"') goto yy39; + if (yych <= ' ') goto yy47; + if (yych <= '"') goto yy42; } else { - if (yych == ':') goto yy62; - goto yy39; + if (yych == ':') goto yy65; + goto yy42; } } -yy44: - YYDEBUG(44, *YYCURSOR); +yy47: + YYDEBUG(47, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 106 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 106 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } -#line 527 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy45: - YYDEBUG(45, *YYCURSOR); +#line 586 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy48: + YYDEBUG(48, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy42; + if (yybm[0+yych] & 16) { + goto yy45; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy44; - if (yych <= 0x08) goto yy40; - goto yy44; + if (yych <= 0x00) goto yy47; + if (yych <= 0x08) goto yy43; + goto yy47; } else { - if (yych == '\r') goto yy44; - goto yy40; + if (yych == '\r') goto yy47; + goto yy43; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy44; - if (yych <= '"') goto yy40; - goto yy44; + if (yych <= ' ') goto yy47; + if (yych <= '"') goto yy43; + goto yy47; } else { - if (yych == 'x') goto yy102; - goto yy40; + if (yych == 'x') goto yy105; + goto yy43; } } -yy46: - YYDEBUG(46, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'I') goto yy96; - if (yych == 'i') goto yy96; - goto yy40; -yy47: - YYDEBUG(47, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'N') goto yy91; - if (yych == 'n') goto yy91; - goto yy40; -yy48: - YYDEBUG(48, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy88; - if (yych == 'a') goto yy88; - goto yy40; yy49: YYDEBUG(49, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'O') goto yy84; - if (yych == 'o') goto yy84; - goto yy40; + if (yych == 'I') goto yy99; + if (yych == 'i') goto yy99; + goto yy43; yy50: YYDEBUG(50, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 'N') { - if (yych == 'F') goto yy83; - if (yych <= 'M') goto yy40; - goto yy77; - } else { - if (yych <= 'f') { - if (yych <= 'e') goto yy40; - goto yy83; - } else { - if (yych == 'n') goto yy77; - goto yy40; - } - } + if (yych == 'N') goto yy94; + if (yych == 'n') goto yy94; + goto yy43; yy51: YYDEBUG(51, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'R') goto yy81; - if (yych == 'r') goto yy81; - goto yy40; + if (yych == 'A') goto yy91; + if (yych == 'a') goto yy91; + goto yy43; yy52: YYDEBUG(52, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy76; - if (yych == 'e') goto yy76; - goto yy40; + if (yych == 'O') goto yy87; + if (yych == 'o') goto yy87; + goto yy43; yy53: YYDEBUG(53, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy73; - goto yy40; + if (yych <= 'N') { + if (yych == 'F') goto yy86; + if (yych <= 'M') goto yy43; + goto yy80; + } else { + if (yych <= 'f') { + if (yych <= 'e') goto yy43; + goto yy86; + } else { + if (yych == 'n') goto yy80; + goto yy43; + } + } yy54: YYDEBUG(54, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'e') goto yy61; - goto yy40; + if (yych == 'R') goto yy84; + if (yych == 'r') goto yy84; + goto yy43; yy55: YYDEBUG(55, *YYCURSOR); - ++YYCURSOR; + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy79; + if (yych == 'e') goto yy79; + goto yy43; +yy56: YYDEBUG(56, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy76; + goto yy43; +yy57: + YYDEBUG(57, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'e') goto yy64; + goto yy43; +yy58: + YYDEBUG(58, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(59, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 84 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 84 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_POUND; } -#line 634 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy57: - YYDEBUG(57, *YYCURSOR); +#line 693 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy60: + YYDEBUG(60, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == ':') goto yy59; - YYDEBUG(58, *YYCURSOR); + if ((yych = *YYCURSOR) == ':') goto yy62; + YYDEBUG(61, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 90 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 90 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_COLON; } -#line 645 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy59: - YYDEBUG(59, *YYCURSOR); +#line 704 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy62: + YYDEBUG(62, *YYCURSOR); ++YYCURSOR; - YYDEBUG(60, *YYCURSOR); + YYDEBUG(63, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 87 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 87 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_DCOLON; } -#line 655 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy61: - YYDEBUG(61, *YYCURSOR); +#line 714 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy64: + YYDEBUG(64, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'n') goto yy67; - goto yy40; -yy62: - YYDEBUG(62, *YYCURSOR); + if (yych == 'n') goto yy70; + goto yy43; +yy65: + YYDEBUG(65, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '/') goto yy64; -yy63: - YYDEBUG(63, *YYCURSOR); + if (yych == '/') goto yy67; +yy66: + YYDEBUG(66, *YYCURSOR); YYCURSOR = YYMARKER; if (yyaccept <= 1) { if (yyaccept <= 0) { - goto yy38; + goto yy41; } else { - goto yy44; + goto yy47; } } else { if (yyaccept <= 2) { - goto yy72; + goto yy75; } else { - goto yy105; + goto yy108; } } -yy64: - YYDEBUG(64, *YYCURSOR); +yy67: + YYDEBUG(67, *YYCURSOR); yych = *++YYCURSOR; - if (yych != '/') goto yy63; - YYDEBUG(65, *YYCURSOR); + if (yych != '/') goto yy66; + YYDEBUG(68, *YYCURSOR); ++YYCURSOR; - YYDEBUG(66, *YYCURSOR); + YYDEBUG(69, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 78 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 78 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_PROTO; } -#line 697 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy67: - YYDEBUG(67, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'd') goto yy40; - YYDEBUG(68, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych != '_') goto yy40; -yy69: - YYDEBUG(69, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy70; - } - goto yy40; +#line 756 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy70: YYDEBUG(70, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != 'd') goto yy43; + YYDEBUG(71, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != '_') goto yy43; +yy72: + YYDEBUG(72, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy73; + } + goto yy43; +yy73: + YYDEBUG(73, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(71, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy70; + YYDEBUG(74, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy73; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy72; - if (yych <= 0x08) goto yy39; + if (yych <= 0x00) goto yy75; + if (yych <= 0x08) goto yy42; } else { - if (yych != '\r') goto yy39; + if (yych != '\r') goto yy42; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy72; - if (yych <= '"') goto yy39; + if (yych <= ' ') goto yy75; + if (yych <= '"') goto yy42; } else { - if (yych == ':') goto yy62; - goto yy39; + if (yych == ':') goto yy65; + goto yy42; } } -yy72: - YYDEBUG(72, *YYCURSOR); +yy75: + YYDEBUG(75, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 118 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 118 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_OPCODE; } -#line 751 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy73: - YYDEBUG(73, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'N') goto yy40; - YYDEBUG(74, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'D') goto yy40; - YYDEBUG(75, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == '_') goto yy69; - goto yy40; +#line 810 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy76: YYDEBUG(76, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy77; - if (yych != 's') goto yy40; -yy77: + if (yych != 'N') goto yy43; YYDEBUG(77, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy40; - if (yych >= '\v') goto yy40; - } else { - if (yych <= '\r') goto yy78; - if (yych != ' ') goto yy40; - } -yy78: + if (yych != 'D') goto yy43; YYDEBUG(78, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == '_') goto yy72; + goto yy43; +yy79: + YYDEBUG(79, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'S') goto yy80; + if (yych != 's') goto yy43; +yy80: + YYDEBUG(80, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy81; + } + goto yy43; +yy81: + YYDEBUG(81, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(79, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy80; - if (yych <= '\n') goto yy78; - } else { - if (yych <= '\r') goto yy78; - if (yych == ' ') goto yy78; + YYDEBUG(82, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy81; } -yy80: - YYDEBUG(80, *YYCURSOR); + YYDEBUG(83, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 94 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 94 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return T_TRUTHY; } -#line 805 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy81: - YYDEBUG(81, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'U') goto yy82; - if (yych != 'u') goto yy40; -yy82: - YYDEBUG(82, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy77; - if (yych == 'e') goto yy77; - goto yy40; -yy83: - YYDEBUG(83, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'F') goto yy84; - if (yych != 'f') goto yy40; +#line 856 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy84: YYDEBUG(84, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy40; - if (yych >= '\v') goto yy40; - } else { - if (yych <= '\r') goto yy85; - if (yych != ' ') goto yy40; - } + if (yych == 'U') goto yy85; + if (yych != 'u') goto yy43; yy85: YYDEBUG(85, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy80; + if (yych == 'e') goto yy80; + goto yy43; +yy86: + YYDEBUG(86, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'F') goto yy87; + if (yych != 'f') goto yy43; +yy87: + YYDEBUG(87, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy43; + if (yych >= '\v') goto yy43; + } else { + if (yych <= '\r') goto yy88; + if (yych != ' ') goto yy43; + } +yy88: + YYDEBUG(88, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(86, *YYCURSOR); + YYDEBUG(89, *YYCURSOR); if (yych <= '\f') { - if (yych <= 0x08) goto yy87; - if (yych <= '\n') goto yy85; + if (yych <= 0x08) goto yy90; + if (yych <= '\n') goto yy88; } else { - if (yych <= '\r') goto yy85; - if (yych == ' ') goto yy85; + if (yych <= '\r') goto yy88; + if (yych == ' ') goto yy88; } -yy87: - YYDEBUG(87, *YYCURSOR); +yy90: + YYDEBUG(90, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 100 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 100 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return T_FALSY; } -#line 858 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy88: - YYDEBUG(88, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy89; - if (yych != 'l') goto yy40; -yy89: - YYDEBUG(89, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy90; - if (yych != 's') goto yy40; -yy90: - YYDEBUG(90, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy84; - if (yych == 'e') goto yy84; - goto yy40; +#line 909 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy91: YYDEBUG(91, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy92; - if (yych != 'a') goto yy40; + if (yych == 'L') goto yy92; + if (yych != 'l') goto yy43; yy92: YYDEBUG(92, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'B') goto yy93; - if (yych != 'b') goto yy40; + if (yych == 'S') goto yy93; + if (yych != 's') goto yy43; yy93: YYDEBUG(93, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy94; - if (yych != 'l') goto yy40; + if (yych == 'E') goto yy87; + if (yych == 'e') goto yy87; + goto yy43; yy94: YYDEBUG(94, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy95; - if (yych != 'e') goto yy40; + if (yych == 'A') goto yy95; + if (yych != 'a') goto yy43; yy95: YYDEBUG(95, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'D') goto yy77; - if (yych == 'd') goto yy77; - goto yy40; + if (yych == 'B') goto yy96; + if (yych != 'b') goto yy43; yy96: YYDEBUG(96, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy97; - if (yych != 's') goto yy40; + if (yych == 'L') goto yy97; + if (yych != 'l') goto yy43; yy97: YYDEBUG(97, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy98; - if (yych != 'a') goto yy40; + if (yych == 'E') goto yy98; + if (yych != 'e') goto yy43; yy98: YYDEBUG(98, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'B') goto yy99; - if (yych != 'b') goto yy40; + if (yych == 'D') goto yy80; + if (yych == 'd') goto yy80; + goto yy43; yy99: YYDEBUG(99, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy100; - if (yych != 'l') goto yy40; + if (yych == 'S') goto yy100; + if (yych != 's') goto yy43; yy100: YYDEBUG(100, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy101; - if (yych != 'e') goto yy40; + if (yych == 'A') goto yy101; + if (yych != 'a') goto yy43; yy101: YYDEBUG(101, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'D') goto yy84; - if (yych == 'd') goto yy84; - goto yy40; + if (yych == 'B') goto yy102; + if (yych != 'b') goto yy43; yy102: YYDEBUG(102, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy103; - } - goto yy40; + if (yych == 'L') goto yy103; + if (yych != 'l') goto yy43; yy103: YYDEBUG(103, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy104; + if (yych != 'e') goto yy43; +yy104: + YYDEBUG(104, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'D') goto yy87; + if (yych == 'd') goto yy87; + goto yy43; +yy105: + YYDEBUG(105, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy106; + } + goto yy43; +yy106: + YYDEBUG(106, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(104, *YYCURSOR); + YYDEBUG(107, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy103; + goto yy106; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy105; - if (yych <= 0x08) goto yy39; + if (yych <= 0x00) goto yy108; + if (yych <= 0x08) goto yy42; } else { - if (yych != '\r') goto yy39; + if (yych != '\r') goto yy42; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy105; - if (yych <= '"') goto yy39; + if (yych <= ' ') goto yy108; + if (yych <= '"') goto yy42; } else { - if (yych == ':') goto yy62; - goto yy39; + if (yych == ':') goto yy65; + goto yy42; } } -yy105: - YYDEBUG(105, *YYCURSOR); +yy108: + YYDEBUG(108, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 112 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 112 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, 0, 16); return T_ADDR; } -#line 989 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy106: - YYDEBUG(106, *YYCURSOR); +#line 1040 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy109: + YYDEBUG(109, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '\f') { - if (yych <= 0x08) goto yy40; - if (yych >= '\v') goto yy40; + if (yych <= 0x08) goto yy43; + if (yych >= '\v') goto yy43; } else { - if (yych <= '\r') goto yy107; - if (yych != ' ') goto yy40; + if (yych <= '\r') goto yy110; + if (yych != ' ') goto yy43; } -yy107: - YYDEBUG(107, *YYCURSOR); +yy110: + YYDEBUG(110, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(108, *YYCURSOR); + YYDEBUG(111, *YYCURSOR); if (yych <= '\f') { - if (yych <= 0x08) goto yy109; - if (yych <= '\n') goto yy107; + if (yych <= 0x08) goto yy112; + if (yych <= '\n') goto yy110; } else { - if (yych <= '\r') goto yy107; - if (yych == ' ') goto yy107; + if (yych <= '\r') goto yy110; + if (yych == ' ') goto yy110; } -yy109: - YYDEBUG(109, *YYCURSOR); +yy112: + YYDEBUG(112, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 72 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 72 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_IF; } -#line 1023 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 1074 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" } /* *********************************** */ yyc_RAW: { static const unsigned char yybm[] = { - 0, 64, 64, 64, 64, 64, 64, 64, - 64, 224, 128, 64, 64, 224, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 224, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, + 0, 128, 128, 128, 128, 128, 128, 128, + 128, 160, 64, 128, 128, 160, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 160, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, }; - YYDEBUG(110, *YYCURSOR); - YYFILL(2); + YYDEBUG(113, *YYCURSOR); + YYFILL(1); yych = *YYCURSOR; if (yybm[0+yych] & 32) { - goto yy112; + goto yy115; } - if (yych <= 0x00) goto yy117; - if (yych == '\n') goto yy115; - goto yy118; -yy112: - YYDEBUG(112, *YYCURSOR); + if (yych <= 0x00) goto yy121; + if (yych == '\n') goto yy118; + goto yy122; +yy115: + YYDEBUG(115, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(113, *YYCURSOR); + YYDEBUG(116, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy112; + goto yy115; } - if (yych <= 0x00) goto yy114; - if (yych == '\n') goto yy120; - goto yy118; -yy114: - YYDEBUG(114, *YYCURSOR); + if (yych <= 0x00) goto yy121; + if (yych == '\n') goto yy118; + goto yy122; +yy117: + YYDEBUG(117, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 132 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 132 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_INPUT; } -#line 1093 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy115: - YYDEBUG(115, *YYCURSOR); - ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 128) { - goto yy120; - } -yy116: - YYDEBUG(116, *YYCURSOR); - yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" - { - return 0; -} -#line 1107 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" -yy117: - YYDEBUG(117, *YYCURSOR); - yych = *++YYCURSOR; - goto yy116; +#line 1144 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" yy118: YYDEBUG(118, *YYCURSOR); ++YYCURSOR; @@ -1117,27 +1150,62 @@ yy118: if (yybm[0+yych] & 64) { goto yy118; } - goto yy114; + if (yych <= '\f') { + if (yych <= 0x00) goto yy121; + if (yych == '\t') goto yy124; + } else { + if (yych <= '\r') goto yy124; + if (yych == ' ') goto yy124; + } yy120: YYDEBUG(120, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 68 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" + { + return 0; +} +#line 1168 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +yy121: + YYDEBUG(121, *YYCURSOR); + yych = *++YYCURSOR; + goto yy120; +yy122: + YYDEBUG(122, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(121, *YYCURSOR); + YYDEBUG(123, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy120; + goto yy122; } - YYDEBUG(122, *YYCURSOR); + goto yy117; +yy124: + YYDEBUG(124, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(125, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy118; + } + if (yych <= '\f') { + if (yych <= 0x00) goto yy121; + if (yych == '\t') goto yy124; + } else { + if (yych <= '\r') goto yy124; + if (yych == ' ') goto yy124; + } + YYDEBUG(126, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 139 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ goto restart; } -#line 1139 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.c" +#line 1207 "/root/php-src/sapi/phpdbg/phpdbg_lexer.c" } } -#line 168 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 168 "/root/php-src/sapi/phpdbg/phpdbg_lexer.l" } diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 7b3ce38c472..dc86559b20b 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -65,7 +65,7 @@ INPUT [^\n\000]+ := yyleng = (size_t) YYCURSOR - (size_t) yytext; -<*>[\n\000] { +<*>{WS}?[\n\000] { return 0; } From 0ef8b4caf359e79319a61f58e9448a0883cb1579 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 8 Oct 2014 00:35:17 +0200 Subject: [PATCH 044/125] Revert WS change from "[\r\n\t ]+" to "[\t ]+" --- phpdbg_lexer.c | 1493 +++++++++++++++++++++++++++--------------------- phpdbg_lexer.l | 2 +- 2 files changed, 857 insertions(+), 638 deletions(-) diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index bca4754c809..68895b4e3dd 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -62,10 +62,10 @@ yyc_INITIAL: { static const unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 128, 0, 0, 0, 0, 0, 0, + 0, 192, 96, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 0, 0, 0, + 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -98,41 +98,49 @@ yyc_INITIAL: YYDEBUG(0, *YYCURSOR); YYFILL(4); yych = *YYCURSOR; + if (yybm[0+yych] & 32) { + goto yy4; + } if (yych <= 'E') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy4; - if (yych <= 0x08) goto yy11; - if (yych >= '\n') goto yy5; + if (yych <= '\f') { + if (yych <= 0x00) goto yy7; + if (yych != '\t') goto yy12; } else { - if (yych == ' ') goto yy2; - if (yych <= 'D') goto yy11; - goto yy7; + if (yych <= 0x1F) { + if (yych >= 0x0E) goto yy12; + } else { + if (yych <= ' ') goto yy2; + if (yych <= 'D') goto yy12; + goto yy8; + } } } else { if (yych <= 'd') { - if (yych <= 'Q') goto yy11; - if (yych <= 'R') goto yy10; - if (yych <= 'S') goto yy8; - goto yy11; + if (yych <= 'Q') goto yy12; + if (yych <= 'R') goto yy11; + if (yych <= 'S') goto yy9; + goto yy12; } else { if (yych <= 'q') { - if (yych <= 'e') goto yy7; - goto yy11; + if (yych <= 'e') goto yy8; + goto yy12; } else { - if (yych <= 'r') goto yy9; - if (yych <= 's') goto yy8; - goto yy11; + if (yych <= 'r') goto yy10; + if (yych <= 's') goto yy9; + goto yy12; } } } yy2: YYDEBUG(2, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) <= '\n') { - if (yych <= 0x00) goto yy27; - if (yych >= '\t') goto yy27; + if ((yych = *YYCURSOR) <= '\f') { + if (yych <= 0x00) goto yy29; + if (yych <= 0x08) goto yy3; + if (yych <= '\n') goto yy29; } else { - if (yych == ' ') goto yy27; + if (yych <= '\r') goto yy29; + if (yych == ' ') goto yy29; } yy3: YYDEBUG(3, *YYCURSOR); @@ -144,82 +152,91 @@ yy3: YYCURSOR = LEX(text); goto restart; } -#line 148 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 156 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy4: YYDEBUG(4, *YYCURSOR); - yych = *++YYCURSOR; - goto yy3; -yy5: - YYDEBUG(5, *YYCURSOR); ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(5, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy28; + } + if (yych <= 0x00) goto yy27; + if (yych == '\n') goto yy4; +yy6: YYDEBUG(6, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 162 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 175 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy7: YYDEBUG(7, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'V') goto yy22; - if (yych == 'v') goto yy22; + yych = *++YYCURSOR; goto yy3; yy8: YYDEBUG(8, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'H') goto yy18; - if (yych == 'h') goto yy18; + if (yych == 'V') goto yy23; + if (yych == 'v') goto yy23; goto yy3; yy9: YYDEBUG(9, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy15; - } - if (yych == 'U') goto yy12; - if (yych == 'u') goto yy12; + if (yych == 'H') goto yy19; + if (yych == 'h') goto yy19; goto yy3; yy10: YYDEBUG(10, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'U') goto yy12; - if (yych == 'u') goto yy12; + if (yybm[0+yych] & 64) { + goto yy16; + } + if (yych == 'U') goto yy13; + if (yych == 'u') goto yy13; goto yy3; yy11: YYDEBUG(11, *YYCURSOR); - yych = *++YYCURSOR; + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'U') goto yy13; + if (yych == 'u') goto yy13; goto yy3; yy12: YYDEBUG(12, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy14; - if (yych == 'n') goto yy14; + goto yy3; yy13: YYDEBUG(13, *YYCURSOR); - YYCURSOR = YYMARKER; - goto yy3; + yych = *++YYCURSOR; + if (yych == 'N') goto yy15; + if (yych == 'n') goto yy15; yy14: YYDEBUG(14, *YYCURSOR); - yych = *++YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy15; - } - goto yy13; + YYCURSOR = YYMARKER; + goto yy3; yy15: YYDEBUG(15, *YYCURSOR); + yych = *++YYCURSOR; + if (yybm[0+yych] & 64) { + goto yy16; + } + goto yy14; +yy16: + YYDEBUG(16, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(16, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy15; - } YYDEBUG(17, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy16; + } + YYDEBUG(18, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 162 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -227,21 +244,32 @@ yy15: phpdbg_init_param(yylval, EMPTY_PARAM); return T_RUN; } -#line 231 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy18: - YYDEBUG(18, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\t') goto yy19; - if (yych != ' ') goto yy13; +#line 248 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy19: YYDEBUG(19, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\f') { + if (yych <= 0x08) goto yy14; + if (yych >= '\v') goto yy14; + } else { + if (yych <= '\r') goto yy20; + if (yych != ' ') goto yy14; + } +yy20: + YYDEBUG(20, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(20, *YYCURSOR); - if (yych == '\t') goto yy19; - if (yych == ' ') goto yy19; YYDEBUG(21, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy22; + if (yych <= '\n') goto yy20; + } else { + if (yych <= '\r') goto yy20; + if (yych == ' ') goto yy20; + } +yy22: + YYDEBUG(22, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 157 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -249,21 +277,32 @@ yy19: phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } -#line 253 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy22: - YYDEBUG(22, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\t') goto yy23; - if (yych != ' ') goto yy13; +#line 281 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy23: YYDEBUG(23, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\f') { + if (yych <= 0x08) goto yy14; + if (yych >= '\v') goto yy14; + } else { + if (yych <= '\r') goto yy24; + if (yych != ' ') goto yy14; + } +yy24: + YYDEBUG(24, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(24, *YYCURSOR); - if (yych == '\t') goto yy23; - if (yych == ' ') goto yy23; YYDEBUG(25, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy26; + if (yych <= '\n') goto yy24; + } else { + if (yych <= '\r') goto yy24; + if (yych == ' ') goto yy24; + } +yy26: + YYDEBUG(26, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 152 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -271,22 +310,24 @@ yy23: phpdbg_init_param(yylval, EMPTY_PARAM); return T_EVAL; } -#line 275 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy26: - YYDEBUG(26, *YYCURSOR); +#line 314 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy27: + YYDEBUG(27, *YYCURSOR); + yych = *++YYCURSOR; + goto yy6; +yy28: + YYDEBUG(28, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy27: - YYDEBUG(27, *YYCURSOR); - if (yych <= '\t') { - if (yych <= 0x00) goto yy5; - if (yych >= '\t') goto yy26; - } else { - if (yych <= '\n') goto yy5; - if (yych == ' ') goto yy26; +yy29: + YYDEBUG(29, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy28; } - YYDEBUG(28, *YYCURSOR); + if (yych <= 0x00) goto yy27; + if (yych == '\n') goto yy4; + YYDEBUG(30, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -294,122 +335,148 @@ yy27: goto restart; } -#line 298 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 339 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" } /* *********************************** */ yyc_NORMAL: { static const unsigned char yybm[] = { - 0, 16, 16, 16, 16, 16, 16, 16, - 16, 8, 0, 16, 16, 0, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 16, 0, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 48, 16, - 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 0, 16, 16, 16, 16, 16, - 16, 208, 208, 208, 208, 208, 208, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 16, 16, 16, 16, 16, - 16, 208, 208, 208, 208, 208, 208, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, + 0, 8, 8, 8, 8, 8, 8, 8, + 8, 66, 68, 8, 8, 66, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 66, 8, 8, 0, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 24, 8, + 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 0, 8, 8, 8, 8, 8, + 8, 168, 168, 168, 168, 168, 168, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 8, 8, 8, 8, 8, + 8, 168, 168, 168, 168, 168, 168, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, }; - YYDEBUG(29, *YYCURSOR); + YYDEBUG(31, *YYCURSOR); YYFILL(11); yych = *YYCURSOR; - if (yybm[0+yych] & 8) { - goto yy32; + if (yybm[0+yych] & 2) { + goto yy33; } - YYDEBUG(-1, yych); - switch (yych) { - case 0x00: - case '\n': goto yy35; - case '\r': goto yy31; - case '#': goto yy55; - case '-': goto yy37; - case '.': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy42; - case '0': goto yy45; - case ':': goto yy57; - case 'D': - case 'd': goto yy46; - case 'E': - case 'e': goto yy47; - case 'F': - case 'f': goto yy48; - case 'I': - case 'i': goto yy39; - case 'N': - case 'n': goto yy49; - case 'O': - case 'o': goto yy50; - case 'T': - case 't': goto yy51; - case 'Y': - case 'y': goto yy52; - case 'Z': goto yy53; - case 'z': goto yy54; - default: goto yy40; - } -yy31: - YYDEBUG(31, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 2) { - if (yyaccept <= 1) { - if (yyaccept <= 0) { - goto yy38; + if (yych <= 'N') { + if (yych <= '0') { + if (yych <= '#') { + if (yych <= '\t') { + if (yych <= 0x00) goto yy39; + goto yy43; + } else { + if (yych <= '\n') goto yy36; + if (yych <= '"') goto yy43; + goto yy58; + } } else { - goto yy44; + if (yych <= '-') { + if (yych <= ',') goto yy43; + goto yy40; + } else { + if (yych <= '.') goto yy45; + if (yych <= '/') goto yy43; + goto yy48; + } } } else { - goto yy71; + if (yych <= 'E') { + if (yych <= ':') { + if (yych <= '9') goto yy45; + goto yy60; + } else { + if (yych <= 'C') goto yy43; + if (yych <= 'D') goto yy49; + goto yy50; + } + } else { + if (yych <= 'H') { + if (yych <= 'F') goto yy51; + goto yy43; + } else { + if (yych <= 'I') goto yy42; + if (yych <= 'M') goto yy43; + goto yy52; + } + } } } else { - if (yyaccept <= 3) { - goto yy104; + if (yych <= 'f') { + if (yych <= 'Y') { + if (yych <= 'S') { + if (yych <= 'O') goto yy53; + goto yy43; + } else { + if (yych <= 'T') goto yy54; + if (yych <= 'X') goto yy43; + goto yy55; + } + } else { + if (yych <= 'c') { + if (yych <= 'Z') goto yy56; + goto yy43; + } else { + if (yych <= 'd') goto yy49; + if (yych <= 'e') goto yy50; + goto yy51; + } + } } else { - goto yy115; + if (yych <= 'o') { + if (yych <= 'i') { + if (yych <= 'h') goto yy43; + goto yy42; + } else { + if (yych <= 'm') goto yy43; + if (yych <= 'n') goto yy52; + goto yy53; + } + } else { + if (yych <= 'x') { + if (yych == 't') goto yy54; + goto yy43; + } else { + if (yych <= 'y') goto yy55; + if (yych <= 'z') goto yy57; + goto yy43; + } + } } } -yy32: - YYDEBUG(32, *YYCURSOR); +yy33: + YYDEBUG(33, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(33, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy32; - } - if (yych <= 0x00) goto yy35; - if (yych == '\n') goto yy35; YYDEBUG(34, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy33; + } + if (yych <= 0x00) goto yy39; + if (yych == '\n') goto yy36; + YYDEBUG(35, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -417,28 +484,41 @@ yy32: goto restart; } -#line 421 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy35: - YYDEBUG(35, *YYCURSOR); - ++YYCURSOR; +#line 488 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy36: YYDEBUG(36, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(37, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy33; + } + if (yych <= 0x00) goto yy39; + if (yych == '\n') goto yy36; +yy38: + YYDEBUG(38, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 431 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy37: - YYDEBUG(37, *YYCURSOR); +#line 507 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy39: + YYDEBUG(39, *YYCURSOR); + yych = *++YYCURSOR; + goto yy38; +yy40: + YYDEBUG(40, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy42; + if (yybm[0+yych] & 16) { + goto yy45; } - if (yych == 'r') goto yy109; - goto yy41; -yy38: - YYDEBUG(38, *YYCURSOR); + if (yych == 'r') goto yy113; + goto yy44; +yy41: + YYDEBUG(41, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 132 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -447,55 +527,55 @@ yy38: yylval->len = yyleng; return T_ID; } -#line 451 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy39: - YYDEBUG(39, *YYCURSOR); +#line 531 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy42: + YYDEBUG(42, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'F') goto yy105; - if (yych == 'f') goto yy105; - goto yy41; -yy40: - YYDEBUG(40, *YYCURSOR); + if (yych == 'F') goto yy109; + if (yych == 'f') goto yy109; + goto yy44; +yy43: + YYDEBUG(43, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; -yy41: - YYDEBUG(41, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy40; +yy44: + YYDEBUG(44, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy43; } - if (yych <= '9') goto yy38; - goto yy62; -yy42: - YYDEBUG(42, *YYCURSOR); + if (yych <= '9') goto yy41; + goto yy65; +yy45: + YYDEBUG(45, *YYCURSOR); yyaccept = 1; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(43, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy42; + YYDEBUG(46, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy45; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy44; - if (yych <= 0x08) goto yy40; + if (yych <= 0x00) goto yy47; + if (yych <= 0x08) goto yy43; } else { - if (yych != '\r') goto yy40; + if (yych != '\r') goto yy43; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy44; - if (yych <= '"') goto yy40; + if (yych <= ' ') goto yy47; + if (yych <= '"') goto yy43; } else { - if (yych == ':') goto yy62; - goto yy40; + if (yych == ':') goto yy65; + goto yy43; } } -yy44: - YYDEBUG(44, *YYCURSOR); +yy47: + YYDEBUG(47, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 113 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -503,151 +583,172 @@ yy44: yylval->num = atoi(yytext); return T_DIGITS; } -#line 507 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy45: - YYDEBUG(45, *YYCURSOR); +#line 587 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy48: + YYDEBUG(48, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy42; + if (yybm[0+yych] & 16) { + goto yy45; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy44; - if (yych <= 0x08) goto yy41; - goto yy44; + if (yych <= 0x00) goto yy47; + if (yych <= 0x08) goto yy44; + goto yy47; } else { - if (yych == '\r') goto yy44; - goto yy41; + if (yych == '\r') goto yy47; + goto yy44; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy44; - if (yych <= '"') goto yy41; - goto yy44; + if (yych <= ' ') goto yy47; + if (yych <= '"') goto yy44; + goto yy47; } else { - if (yych == 'x') goto yy101; - goto yy41; + if (yych == 'x') goto yy105; + goto yy44; } } -yy46: - YYDEBUG(46, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'I') goto yy95; - if (yych == 'i') goto yy95; - goto yy41; -yy47: - YYDEBUG(47, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'N') goto yy90; - if (yych == 'n') goto yy90; - goto yy41; -yy48: - YYDEBUG(48, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy87; - if (yych == 'a') goto yy87; - goto yy41; yy49: YYDEBUG(49, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'O') goto yy83; - if (yych == 'o') goto yy83; - goto yy41; + if (yych == 'I') goto yy99; + if (yych == 'i') goto yy99; + goto yy44; yy50: YYDEBUG(50, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 'N') { - if (yych == 'F') goto yy82; - if (yych <= 'M') goto yy41; - goto yy76; - } else { - if (yych <= 'f') { - if (yych <= 'e') goto yy41; - goto yy82; - } else { - if (yych == 'n') goto yy76; - goto yy41; - } - } + if (yych == 'N') goto yy94; + if (yych == 'n') goto yy94; + goto yy44; yy51: YYDEBUG(51, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'R') goto yy80; - if (yych == 'r') goto yy80; - goto yy41; + if (yych == 'A') goto yy91; + if (yych == 'a') goto yy91; + goto yy44; yy52: YYDEBUG(52, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy75; - if (yych == 'e') goto yy75; - goto yy41; + if (yych == 'O') goto yy87; + if (yych == 'o') goto yy87; + goto yy44; yy53: YYDEBUG(53, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy72; - goto yy41; + if (yych <= 'N') { + if (yych == 'F') goto yy86; + if (yych <= 'M') goto yy44; + goto yy80; + } else { + if (yych <= 'f') { + if (yych <= 'e') goto yy44; + goto yy86; + } else { + if (yych == 'n') goto yy80; + goto yy44; + } + } yy54: YYDEBUG(54, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'e') goto yy61; - goto yy41; + if (yych == 'R') goto yy84; + if (yych == 'r') goto yy84; + goto yy44; yy55: YYDEBUG(55, *YYCURSOR); - ++YYCURSOR; + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy79; + if (yych == 'e') goto yy79; + goto yy44; +yy56: YYDEBUG(56, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy76; + goto yy44; +yy57: + YYDEBUG(57, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'e') goto yy64; + goto yy44; +yy58: + YYDEBUG(58, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(59, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 91 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return T_POUND; } -#line 614 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy57: - YYDEBUG(57, *YYCURSOR); +#line 694 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy60: + YYDEBUG(60, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == ':') goto yy59; - YYDEBUG(58, *YYCURSOR); + if ((yych = *YYCURSOR) == ':') goto yy62; + YYDEBUG(61, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 97 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return T_COLON; } -#line 625 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy59: - YYDEBUG(59, *YYCURSOR); +#line 705 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy62: + YYDEBUG(62, *YYCURSOR); ++YYCURSOR; - YYDEBUG(60, *YYCURSOR); + YYDEBUG(63, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 94 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return T_DCOLON; } -#line 635 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy61: - YYDEBUG(61, *YYCURSOR); +#line 715 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy64: + YYDEBUG(64, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'n') goto yy66; - goto yy41; -yy62: - YYDEBUG(62, *YYCURSOR); - yych = *++YYCURSOR; - if (yych != '/') goto yy31; - YYDEBUG(63, *YYCURSOR); - yych = *++YYCURSOR; - if (yych != '/') goto yy31; - YYDEBUG(64, *YYCURSOR); - ++YYCURSOR; + if (yych == 'n') goto yy70; + goto yy44; +yy65: YYDEBUG(65, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '/') goto yy67; +yy66: + YYDEBUG(66, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 2) { + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy41; + } else { + goto yy47; + } + } else { + goto yy75; + } + } else { + if (yyaccept <= 3) { + goto yy108; + } else { + goto yy119; + } + } +yy67: + YYDEBUG(67, *YYCURSOR); + yych = *++YYCURSOR; + if (yych != '/') goto yy66; + YYDEBUG(68, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(69, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 85 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -656,52 +757,52 @@ yy62: yylval->len = yyleng; return T_PROTO; } -#line 660 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy66: - YYDEBUG(66, *YYCURSOR); +#line 761 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy70: + YYDEBUG(70, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'd') goto yy41; - YYDEBUG(67, *YYCURSOR); + if (yych != 'd') goto yy44; + YYDEBUG(71, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych != '_') goto yy41; -yy68: - YYDEBUG(68, *YYCURSOR); + if (yych != '_') goto yy44; +yy72: + YYDEBUG(72, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy69; + if (yybm[0+yych] & 32) { + goto yy73; } - goto yy41; -yy69: - YYDEBUG(69, *YYCURSOR); + goto yy44; +yy73: + YYDEBUG(73, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(70, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy69; + YYDEBUG(74, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy73; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy71; - if (yych <= 0x08) goto yy40; + if (yych <= 0x00) goto yy75; + if (yych <= 0x08) goto yy43; } else { - if (yych != '\r') goto yy40; + if (yych != '\r') goto yy43; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy71; - if (yych <= '"') goto yy40; + if (yych <= ' ') goto yy75; + if (yych <= '"') goto yy43; } else { - if (yych == ':') goto yy62; - goto yy40; + if (yych == ':') goto yy65; + goto yy43; } } -yy71: - YYDEBUG(71, *YYCURSOR); +yy75: + YYDEBUG(75, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 125 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -710,42 +811,45 @@ yy71: yylval->len = yyleng; return T_OPCODE; } -#line 714 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy72: - YYDEBUG(72, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'N') goto yy41; - YYDEBUG(73, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych != 'D') goto yy41; - YYDEBUG(74, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == '_') goto yy68; - goto yy41; -yy75: - YYDEBUG(75, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy76; - if (yych != 's') goto yy41; +#line 815 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy76: YYDEBUG(76, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == '\t') goto yy77; - if (yych != ' ') goto yy41; -yy77: + if (yych != 'N') goto yy44; YYDEBUG(77, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych != 'D') goto yy44; + YYDEBUG(78, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == '_') goto yy72; + goto yy44; +yy79: + YYDEBUG(79, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'S') goto yy80; + if (yych != 's') goto yy44; +yy80: + YYDEBUG(80, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy81; + } + goto yy44; +yy81: + YYDEBUG(81, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(78, *YYCURSOR); - if (yych == '\t') goto yy77; - if (yych == ' ') goto yy77; - YYDEBUG(79, *YYCURSOR); + YYDEBUG(82, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy81; + } + YYDEBUG(83, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 101 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -753,41 +857,52 @@ yy77: yylval->num = 1; return T_TRUTHY; } -#line 757 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy80: - YYDEBUG(80, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'U') goto yy81; - if (yych != 'u') goto yy41; -yy81: - YYDEBUG(81, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy76; - if (yych == 'e') goto yy76; - goto yy41; -yy82: - YYDEBUG(82, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'F') goto yy83; - if (yych != 'f') goto yy41; -yy83: - YYDEBUG(83, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == '\t') goto yy84; - if (yych != ' ') goto yy41; +#line 861 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy84: YYDEBUG(84, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'U') goto yy85; + if (yych != 'u') goto yy44; +yy85: + YYDEBUG(85, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy80; + if (yych == 'e') goto yy80; + goto yy44; +yy86: + YYDEBUG(86, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'F') goto yy87; + if (yych != 'f') goto yy44; +yy87: + YYDEBUG(87, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy44; + if (yych >= '\v') goto yy44; + } else { + if (yych <= '\r') goto yy88; + if (yych != ' ') goto yy44; + } +yy88: + YYDEBUG(88, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(85, *YYCURSOR); - if (yych == '\t') goto yy84; - if (yych == ' ') goto yy84; - YYDEBUG(86, *YYCURSOR); + YYDEBUG(89, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy90; + if (yych <= '\n') goto yy88; + } else { + if (yych <= '\r') goto yy88; + if (yych == ' ') goto yy88; + } +yy90: + YYDEBUG(90, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 107 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -795,130 +910,130 @@ yy84: yylval->num = 0; return T_FALSY; } -#line 799 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy87: - YYDEBUG(87, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy88; - if (yych != 'l') goto yy41; -yy88: - YYDEBUG(88, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy89; - if (yych != 's') goto yy41; -yy89: - YYDEBUG(89, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy83; - if (yych == 'e') goto yy83; - goto yy41; -yy90: - YYDEBUG(90, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy91; - if (yych != 'a') goto yy41; +#line 914 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" yy91: YYDEBUG(91, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'B') goto yy92; - if (yych != 'b') goto yy41; + if (yych == 'L') goto yy92; + if (yych != 'l') goto yy44; yy92: YYDEBUG(92, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy93; - if (yych != 'l') goto yy41; + if (yych == 'S') goto yy93; + if (yych != 's') goto yy44; yy93: YYDEBUG(93, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy94; - if (yych != 'e') goto yy41; + if (yych == 'E') goto yy87; + if (yych == 'e') goto yy87; + goto yy44; yy94: YYDEBUG(94, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'D') goto yy76; - if (yych == 'd') goto yy76; - goto yy41; + if (yych == 'A') goto yy95; + if (yych != 'a') goto yy44; yy95: YYDEBUG(95, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'S') goto yy96; - if (yych != 's') goto yy41; + if (yych == 'B') goto yy96; + if (yych != 'b') goto yy44; yy96: YYDEBUG(96, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'A') goto yy97; - if (yych != 'a') goto yy41; + if (yych == 'L') goto yy97; + if (yych != 'l') goto yy44; yy97: YYDEBUG(97, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'B') goto yy98; - if (yych != 'b') goto yy41; + if (yych == 'E') goto yy98; + if (yych != 'e') goto yy44; yy98: YYDEBUG(98, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'L') goto yy99; - if (yych != 'l') goto yy41; + if (yych == 'D') goto yy80; + if (yych == 'd') goto yy80; + goto yy44; yy99: YYDEBUG(99, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'E') goto yy100; - if (yych != 'e') goto yy41; + if (yych == 'S') goto yy100; + if (yych != 's') goto yy44; yy100: YYDEBUG(100, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'D') goto yy83; - if (yych == 'd') goto yy83; - goto yy41; + if (yych == 'A') goto yy101; + if (yych != 'a') goto yy44; yy101: YYDEBUG(101, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy102; - } - goto yy41; + if (yych == 'B') goto yy102; + if (yych != 'b') goto yy44; yy102: YYDEBUG(102, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'L') goto yy103; + if (yych != 'l') goto yy44; +yy103: + YYDEBUG(103, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy104; + if (yych != 'e') goto yy44; +yy104: + YYDEBUG(104, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'D') goto yy87; + if (yych == 'd') goto yy87; + goto yy44; +yy105: + YYDEBUG(105, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy106; + } + goto yy44; +yy106: + YYDEBUG(106, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(103, *YYCURSOR); + YYDEBUG(107, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy102; + goto yy106; } if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy104; - if (yych <= 0x08) goto yy40; + if (yych <= 0x00) goto yy108; + if (yych <= 0x08) goto yy43; } else { - if (yych != '\r') goto yy40; + if (yych != '\r') goto yy43; } } else { if (yych <= '#') { - if (yych <= ' ') goto yy104; - if (yych <= '"') goto yy40; + if (yych <= ' ') goto yy108; + if (yych <= '"') goto yy43; } else { - if (yych == ':') goto yy62; - goto yy40; + if (yych == ':') goto yy65; + goto yy43; } } -yy104: - YYDEBUG(104, *YYCURSOR); +yy108: + YYDEBUG(108, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 119 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -926,22 +1041,33 @@ yy104: yylval->addr = strtoul(yytext, 0, 16); return T_ADDR; } -#line 930 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy105: - YYDEBUG(105, *YYCURSOR); +#line 1045 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy109: + YYDEBUG(109, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == '\t') goto yy106; - if (yych != ' ') goto yy41; -yy106: - YYDEBUG(106, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy44; + if (yych >= '\v') goto yy44; + } else { + if (yych <= '\r') goto yy110; + if (yych != ' ') goto yy44; + } +yy110: + YYDEBUG(110, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(107, *YYCURSOR); - if (yych == '\t') goto yy106; - if (yych == ' ') goto yy106; - YYDEBUG(108, *YYCURSOR); + YYDEBUG(111, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy112; + if (yych <= '\n') goto yy110; + } else { + if (yych <= '\r') goto yy110; + if (yych == ' ') goto yy110; + } +yy112: + YYDEBUG(112, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 79 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -949,87 +1075,93 @@ yy106: phpdbg_init_param(yylval, EMPTY_PARAM); return T_IF; } -#line 953 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy109: - YYDEBUG(109, *YYCURSOR); +#line 1079 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy113: + YYDEBUG(113, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= ',') { - if (yych <= '\t') { - if (yych <= 0x08) goto yy41; + if (yych <= ' ') { + if (yych <= '\f') { + if (yych <= 0x08) goto yy44; + if (yych >= '\v') goto yy44; } else { - if (yych != ' ') goto yy41; - } - } else { - if (yych <= '.') { - if (yych <= '-') goto yy112; - goto yy113; - } else { - if (yych <= '/') goto yy41; - if (yych <= '9') goto yy113; - goto yy41; - } - } -yy110: - YYDEBUG(110, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; - YYDEBUG(111, *YYCURSOR); - if (yych <= ',') { - if (yych <= '\t') { - if (yych <= 0x08) goto yy31; - goto yy110; - } else { - if (yych == ' ') goto yy110; - goto yy31; + if (yych <= '\r') goto yy114; + if (yych <= 0x1F) goto yy44; } } else { if (yych <= '.') { + if (yych <= ',') goto yy44; if (yych <= '-') goto yy116; goto yy117; } else { - if (yych <= '/') goto yy31; + if (yych <= '/') goto yy44; if (yych <= '9') goto yy117; - goto yy31; + goto yy44; } } -yy112: - YYDEBUG(112, *YYCURSOR); +yy114: + YYDEBUG(114, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(115, *YYCURSOR); + if (yych <= ' ') { + if (yych <= '\f') { + if (yych <= 0x08) goto yy66; + if (yych <= '\n') goto yy114; + goto yy66; + } else { + if (yych <= '\r') goto yy114; + if (yych <= 0x1F) goto yy66; + goto yy114; + } + } else { + if (yych <= '.') { + if (yych <= ',') goto yy66; + if (yych <= '-') goto yy120; + goto yy121; + } else { + if (yych <= '/') goto yy66; + if (yych <= '9') goto yy121; + goto yy66; + } + } +yy116: + YYDEBUG(116, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == '.') goto yy113; - if (yych <= '/') goto yy41; - if (yych >= ':') goto yy41; -yy113: - YYDEBUG(113, *YYCURSOR); + if (yych == '.') goto yy117; + if (yych <= '/') goto yy44; + if (yych >= ':') goto yy44; +yy117: + YYDEBUG(117, *YYCURSOR); yyaccept = 4; YYMARKER = ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(114, *YYCURSOR); + YYDEBUG(118, *YYCURSOR); if (yych <= ' ') { if (yych <= '\n') { - if (yych <= 0x00) goto yy115; - if (yych <= 0x08) goto yy40; + if (yych <= 0x00) goto yy119; + if (yych <= 0x08) goto yy43; } else { - if (yych == '\r') goto yy115; - if (yych <= 0x1F) goto yy40; + if (yych == '\r') goto yy119; + if (yych <= 0x1F) goto yy43; } } else { if (yych <= '.') { - if (yych == '#') goto yy115; - if (yych <= '-') goto yy40; - goto yy113; + if (yych == '#') goto yy119; + if (yych <= '-') goto yy43; + goto yy117; } else { - if (yych <= '/') goto yy40; - if (yych <= '9') goto yy113; - if (yych <= ':') goto yy62; - goto yy40; + if (yych <= '/') goto yy43; + if (yych <= '9') goto yy117; + if (yych <= ':') goto yy65; + goto yy43; } } -yy115: - YYDEBUG(115, *YYCURSOR); +yy119: + YYDEBUG(119, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 72 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -1038,89 +1170,89 @@ yy115: yylval->num = atoi(text); return T_REQ_ID; } -#line 1042 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy116: - YYDEBUG(116, *YYCURSOR); +#line 1174 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy120: + YYDEBUG(120, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '.') goto yy117; - if (yych <= '/') goto yy31; - if (yych >= ':') goto yy31; -yy117: - YYDEBUG(117, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(118, *YYCURSOR); - if (yych == '.') goto yy117; - if (yych <= '/') goto yy115; - if (yych <= '9') goto yy117; - goto yy115; - } -/* *********************************** */ -yyc_RAW: - { - static const unsigned char yybm[] = { - 0, 64, 64, 64, 64, 64, 64, 64, - 64, 96, 0, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 96, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 192, 64, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }; - YYDEBUG(119, *YYCURSOR); - YYFILL(2); - yych = *YYCURSOR; - if (yybm[0+yych] & 32) { - goto yy121; - } - if (yych <= '\n') { - if (yych <= 0x00) goto yy124; - if (yych <= '\t') goto yy127; - goto yy124; - } else { - if (yych == '-') goto yy126; - goto yy127; - } + if (yych == '.') goto yy121; + if (yych <= '/') goto yy66; + if (yych >= ':') goto yy66; yy121: YYDEBUG(121, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; YYDEBUG(122, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy121; - } - if (yych <= 0x00) goto yy124; - if (yych == '\n') goto yy124; - goto yy127; -yy123: + if (yych == '.') goto yy121; + if (yych <= '/') goto yy119; + if (yych <= '9') goto yy121; + goto yy119; + } +/* *********************************** */ +yyc_RAW: + { + static const unsigned char yybm[] = { + 0, 32, 32, 32, 32, 32, 32, 32, + 32, 104, 80, 32, 32, 104, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 104, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 160, 32, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + }; YYDEBUG(123, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yybm[0+yych] & 8) { + goto yy125; + } + if (yych <= '\n') { + if (yych <= 0x00) goto yy131; + if (yych <= '\t') goto yy133; + goto yy128; + } else { + if (yych == '-') goto yy132; + goto yy133; + } +yy125: + YYDEBUG(125, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(126, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy125; + } + if (yych <= 0x00) goto yy131; + if (yych == '\n') goto yy128; + goto yy133; +yy127: + YYDEBUG(127, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 139 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -1129,74 +1261,120 @@ yy123: yylval->len = yyleng; return T_INPUT; } -#line 1133 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy124: - YYDEBUG(124, *YYCURSOR); +#line 1265 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy128: + YYDEBUG(128, *YYCURSOR); ++YYCURSOR; - YYDEBUG(125, *YYCURSOR); + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(129, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy128; + } + if (yych <= '\f') { + if (yych <= 0x00) goto yy131; + if (yych == '\t') goto yy147; + } else { + if (yych <= '\r') goto yy147; + if (yych == ' ') goto yy147; + } +yy130: + YYDEBUG(130, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 1143 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy126: - YYDEBUG(126, *YYCURSOR); +#line 1289 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy131: + YYDEBUG(131, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'r') goto yy129; - goto yy128; -yy127: - YYDEBUG(127, *YYCURSOR); + goto yy130; +yy132: + YYDEBUG(132, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'r') goto yy135; + goto yy134; +yy133: + YYDEBUG(133, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy128: - YYDEBUG(128, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy127; +yy134: + YYDEBUG(134, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy133; } - goto yy123; -yy129: - YYDEBUG(129, *YYCURSOR); + goto yy127; +yy135: + YYDEBUG(135, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(136, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy141; + } + if (yych <= '\f') { + if (yych <= 0x08) { + if (yych <= 0x00) goto yy127; + goto yy133; + } else { + if (yych <= '\t') goto yy135; + if (yych >= '\v') goto yy133; + } + } else { + if (yych <= ' ') { + if (yych <= '\r') goto yy135; + if (yych <= 0x1F) goto yy133; + goto yy135; + } else { + if (yych == '-') goto yy140; + goto yy133; + } + } +yy137: + YYDEBUG(137, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; - YYDEBUG(130, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy132; + YYDEBUG(138, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy137; } - if (yych <= '\n') { - if (yych <= 0x00) goto yy123; - if (yych <= 0x08) goto yy127; - if (yych <= '\t') goto yy129; - goto yy123; + if (yych <= '.') { + if (yych <= ',') goto yy139; + if (yych <= '-') goto yy144; + goto yy145; } else { - if (yych <= ' ') { - if (yych <= 0x1F) goto yy127; - goto yy129; - } else { - if (yych != '-') goto yy127; - } + if (yych <= '/') goto yy139; + if (yych <= '9') goto yy145; } - YYDEBUG(131, *YYCURSOR); +yy139: + YYDEBUG(139, *YYCURSOR); + YYCURSOR = YYMARKER; + goto yy127; +yy140: + YYDEBUG(140, *YYCURSOR); yych = *++YYCURSOR; if (yybm[0+yych] & 128) { - goto yy132; + goto yy141; } - goto yy128; -yy132: - YYDEBUG(132, *YYCURSOR); + goto yy134; +yy141: + YYDEBUG(141, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(133, *YYCURSOR); + YYDEBUG(142, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy132; + goto yy141; } - if (yych <= 0x00) goto yy134; - if (yych != '\n') goto yy127; -yy134: - YYDEBUG(134, *YYCURSOR); + if (yych <= 0x00) goto yy143; + if (yych != '\n') goto yy133; +yy143: + YYDEBUG(143, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; #line 72 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" { @@ -1205,7 +1383,48 @@ yy134: yylval->num = atoi(text); return T_REQ_ID; } -#line 1209 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 1387 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +yy144: + YYDEBUG(144, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '.') goto yy145; + if (yych <= '/') goto yy139; + if (yych >= ':') goto yy139; +yy145: + YYDEBUG(145, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(146, *YYCURSOR); + if (yych == '.') goto yy145; + if (yych <= '/') goto yy143; + if (yych <= '9') goto yy145; + goto yy143; +yy147: + YYDEBUG(147, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(148, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy128; + } + if (yych <= '\f') { + if (yych <= 0x00) goto yy131; + if (yych == '\t') goto yy147; + } else { + if (yych <= '\r') goto yy147; + if (yych == ' ') goto yy147; + } + YYDEBUG(149, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" + { + /* ignore whitespace */ + + goto restart; +} +#line 1428 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" } } #line 175 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 2f778ed254c..11fdc913c72 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -56,7 +56,7 @@ T_SHELL 'sh' T_IF 'if' T_RUN 'run' T_RUN_SHORT "r" -WS [ \t]+ +WS [ \r\n\t]+ DIGITS [-]?[0-9\.]+ ID [^ \r\n\t:#\000]+ ADDR [0][x][a-fA-F0-9]+ From fa89d8b3f90db1ea7068d6771d51d370d1ccaf6c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 8 Oct 2014 23:42:20 +0200 Subject: [PATCH 045/125] Fix escaping of < --- phpdbg_utils.c | 52 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 5ec3714230b..c2137020faa 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -718,19 +718,27 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca char *old_s = s, *s_ptr; free_s = s_ptr = s = emalloc(old_slen * 6 + 1); do { - if (old_s[i] == '&' || old_s[i] == '"') { + if (old_s[i] == '&' || old_s[i] == '"' || old_s[i] == '<') { *s_ptr++ = '&'; - if (old_s[i] == '"') { - s_len += 5; - *s_ptr++ = 'q'; - *s_ptr++ = 'u'; - *s_ptr++ = 'o'; - *s_ptr++ = 't'; - } else { - s_len += 4; - *s_ptr++ = 'a'; - *s_ptr++ = 'm'; - *s_ptr++ = 'p'; + switch (old_s[i]) { + case '"': + s_len += 5; + *s_ptr++ = 'q'; + *s_ptr++ = 'u'; + *s_ptr++ = 'o'; + *s_ptr++ = 't'; + break; + case '<': + s_len += 3; + *s_ptr++ = 'l'; + *s_ptr++ = 't'; + break; + case '&': + s_len += 4; + *s_ptr++ = 'a'; + *s_ptr++ = 'm'; + *s_ptr++ = 'p'; + break; } *s_ptr++ = ';'; } else { @@ -1052,15 +1060,18 @@ PHPAPI int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool escape } /* copy end */ -static int phpdbg_encode_xml(char **buf, char *msg, int msglen, char from, char *to) { +static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char *to) { int i; - char *tmp = *buf = emalloc(msglen * strlen(to)); - int tolen = strlen(to); + int tolen = to ? strlen(to) : 5; + char *tmp = *buf = emalloc(msglen * tolen); for (i = 0; i++ < msglen; msg++) { if (*msg == '&') { memcpy(tmp, ZEND_STRL("&")); tmp += sizeof("&") - 1; - } else if (*msg == from) { + } else if (*msg == '<') { + memcpy(tmp, ZEND_STRL("<")); + tmp += sizeof("<") - 1; + } else if (((int) *msg) == from) { memcpy(tmp, to, tolen); tmp += tolen; } else { @@ -1319,7 +1330,7 @@ PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) { int buflen; va_start(args, fmt); - buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); + buflen = phpdbg_xml_vasprintf(&buffer, fmt, 1, args TSRMLS_CC); va_end(args); if (PHPDBG_G(in_script_xml)) { @@ -1361,13 +1372,18 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { va_end(args); if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + char *msg; + int msglen; + + msglen = phpdbg_encode_xml(&msg, buffer, buflen, 256, NULL); + if (PHPDBG_G(in_script_xml)) { write(fd, ZEND_STRL("")); PHPDBG_G(in_script_xml) = 0; } write(fd, ZEND_STRL("")); - len = write(fd, buffer, buflen); + len = write(fd, msg, msglen); write(fd, ZEND_STRL("")); } else { len = write(fd, buffer, buflen); From 07bbe627426e06e0c665c6e6832268b5e70cb5ea Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 8 Oct 2014 23:44:22 +0200 Subject: [PATCH 046/125] Put stack_verify in error buffer too --- phpdbg_cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index abb41e4ae9f..69f8eeef8c4 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -777,9 +777,9 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, zend_bool allow_async return FAILURE; } - phpdbg_activate_err_buf(0 TSRMLS_CC); - phpdbg_free_err_buf(TSRMLS_C); if (phpdbg_stack_verify(handler, &top TSRMLS_CC) == SUCCESS) { + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); return handler->handler(top TSRMLS_CC); } } From 9db6a93b69edf154934c768dab0a70d3b8ef6b47 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 00:25:25 +0200 Subject: [PATCH 047/125] Add tag around tags --- phpdbg.c | 2 ++ xml.md | 1 + 2 files changed, 3 insertions(+) diff --git a/phpdbg.c b/phpdbg.c index 3f2a209df7f..6a9a60ad33d 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -733,9 +733,11 @@ static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */ { /* print blurb */ if (!cleaning) { + phpdbg_xml(""); phpdbg_notice("intro", "version=\"%s\"", "Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION); phpdbg_writeln("intro", "help=\"help\"", "To get help using phpdbg type \"help\" and press enter"); phpdbg_notice("intro", "report=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES); + phpdbg_xml(""); } else { if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { phpdbg_notice(NULL, NULL, "Clean Execution Environment"); diff --git a/xml.md b/xml.md index 83bd364626d..bd3adc7a5dc 100644 --- a/xml.md +++ b/xml.md @@ -69,6 +69,7 @@ intro - appears on startup if -q flag wasn't provided as command line arg - before any input possibility - attributes may be spread over multiple tags +- wrapped in tag ### attributes ### From 96de7c4b0ad30ad41983fa0786aeaf0418d82c7b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 11:47:52 +0200 Subject: [PATCH 048/125] Reduce variabledetails+variable to just one variable tag --- phpdbg_info.c | 14 +++++++------- xml.md | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/phpdbg_info.c b/phpdbg_info.c index 9c17e42c2eb..a85484238c3 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -184,29 +184,29 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { phpdbg_try_access { if (!(invalid_data = !*data)) { - phpdbg_writeln("variable", "address=\"%p\" refcount=\"%d\" type=\"%s\"", "%p\t%d\t(%s)", *data, Z_REFCOUNT_PP(data), zend_zval_type_name(*data)); +#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("variable", "address=\"%p\" refcount=\"%d\" type=\"%s\" refstatus=\"%s\" name=\"%s\" " attrs, "%p\t%d\t(%s)\n%s$%s", *data, Z_REFCOUNT_PP(data), zend_zval_type_name(*data), Z_ISREF_PP(data) ? "&": "", var, ##__VA_ARGS__) if (Z_TYPE_PP(data) == IS_RESOURCE) { phpdbg_try_access { int type; - phpdbg_writeln("variabledetails", "refstatus=\"%s\" name=\"%s\" type=\"%s\"", "%s$%s\n|-------(typeof)------> (%s)\n", Z_ISREF_PP(data) ? "&": "", var, zend_list_find(Z_RESVAL_PP(data), &type) ? zend_rsrc_list_get_rsrc_type(type TSRMLS_CC) : "unknown"); + VARIABLEINFO("type=\"%s\"", "\n|-------(typeof)------> (%s)\n", zend_list_find(Z_RESVAL_PP(data), &type) ? zend_rsrc_list_get_rsrc_type(type TSRMLS_CC) : "unknown"); } phpdbg_catch_access { - phpdbg_writeln("variabledetails", "refstatus=\"%s\" name=\"%s\" type=\"unknown\"", "%s$%s\n|-------(typeof)------> (unknown)\n", Z_ISREF_PP(data) ? "&": "", var); + VARIABLEINFO("type=\"unknown\"", "\n|-------(typeof)------> (unknown)\n"); } phpdbg_end_try_access(); } else if (Z_TYPE_PP(data) == IS_OBJECT) { phpdbg_try_access { - phpdbg_writeln("variabledetails", "refstatus=\"%s\" name=\"%s\" instanceof=\"%s\"", "%s$%s\n|-----(instanceof)----> (%s)\n", Z_ISREF_PP(data) ? "&": "", var, Z_OBJCE_PP(data)->name); + VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (%s)\n", Z_OBJCE_PP(data)->name); } phpdbg_catch_access { - phpdbg_writeln("variabledetails", "refstatus=\"%s\" name=\"%s\" instanceof=\"unknown\"", "%s$%s\n|-----(instanceof)----> (unknown)\n", Z_ISREF_PP(data) ? "&": "", var); + VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (unknown)\n"); } phpdbg_end_try_access(); } else { - phpdbg_writeln("variabledetails", "refstatus=\"%s\" name=\"%s\"", "%s$%s", Z_ISREF_PP(data) ? "&": "", var); + VARIABLEINFO("", ""); } } } phpdbg_end_try_access(); if (invalid_data) { - phpdbg_writeln("variabledetails", "name=\"%s\"", "n/a\tn/a\tn/a\t$%s", var); + phpdbg_writeln("variable", "name=\"%s\"", "n/a\tn/a\tn/a\t$%s", var); } } } diff --git a/xml.md b/xml.md index bd3adc7a5dc..5cf45535c7d 100644 --- a/xml.md +++ b/xml.md @@ -260,11 +260,11 @@ info (subcommands) - file - opline - for each variable there is a <variable> followed by a <variabledetails> element -- <variable address="" refcount="" type="" /> +- <variable address="" refcount="" type="" name="" /> - address: pointer to zval (hexadecimal) - refcount: refcount of zval - type: the variable type (long, string, ...). If the value is "unknown", the other attributes are meaningless -- <variabledetails name="" /> with name the name of the variable, optional args are: + - name: the name of the variable - refstatus: empty if the zval is not a reference - class: the class the object in the zval is an instance of - resource: the type of the resource in the zval From b426897c9c55b441f89fefab4a87acdbbe989241 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 11:52:57 +0200 Subject: [PATCH 049/125] Fix regression in list It showed the entire remaining file before... --- phpdbg_list.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpdbg_list.c b/phpdbg_list.c index 647a2901d8d..83c27bcfbca 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -153,12 +153,12 @@ void phpdbg_list_file(const char *filename, uint count, uint offset, uint highli char *buffer = (*data)->buf + linestart; if (!highlight) { - phpdbg_write("line", "line=\"%u\" code=\"%s\"", " %05u: %s", line, buffer); + phpdbg_write("line", "line=\"%u\" code=\"%.*s\"", " %05u: %.*s", line, linelen, buffer); } else { if (highlight != line) { - phpdbg_write("line", "line=\"%u\" code=\"%s\"", " %05u: %s", line, buffer); + phpdbg_write("line", "line=\"%u\" code=\"%.*s\"", " %05u: %.*s", line, linelen, buffer); } else { - phpdbg_write("line", "line=\"%u\" code=\"%s\" current=\"current\"", ">%05u: %s", line, buffer); + phpdbg_write("line", "line=\"%u\" code=\"%.*s\" current=\"current\"", ">%05u: %.*s", line, linelen, buffer); } } From ca7f2f5f43eda96c098553f6a9e99c2ea6c4d17b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 12:01:25 +0200 Subject: [PATCH 050/125] Ports are unsigned short, use unsigned to display --- phpdbg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 36e4bf80689..787ffe7db8e 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -791,18 +791,18 @@ static void phpdbg_remote_close(int socket, FILE *stream) { } /* don't inline this, want to debug it easily, will inline when done */ -static int phpdbg_remote_init(const char* address, short port, int *server, int *socket, FILE **stream) { +static int phpdbg_remote_init(const char* address, unsigned short port, int *server, int *socket, FILE **stream) { phpdbg_remote_close(*socket, *stream); *server = phpdbg_open_socket(address, port); if (*server < 0) { - phpdbg_rlog(fileno(stderr), "Initializing connection on %s:%d failed", address, port); + phpdbg_rlog(fileno(stderr), "Initializing connection on %s:%u failed", address, port); return FAILURE; } - phpdbg_rlog(fileno(stderr), "accepting connections on %s:%d", address, port); + phpdbg_rlog(fileno(stderr), "accepting connections on %s:%u", address, port); { struct sockaddr_in address; socklen_t size = sizeof(address); From a7918213e762b023075369a673ec651a0eb136de Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 12:24:52 +0200 Subject: [PATCH 051/125] Always output request id in containers --- phpdbg_bp.c | 2 +- phpdbg_info.c | 2 +- phpdbg_print.c | 2 +- phpdbg_prompt.c | 10 +++++----- phpdbg_watch.c | 8 ++++---- xml.md | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index f2ef4228ea1..fa9355cb243 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -1332,7 +1332,7 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ { - phpdbg_xml(""); + phpdbg_xml(""); switch (type) { case PHPDBG_BREAK_SYM: if ((PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP)) { diff --git a/phpdbg_info.c b/phpdbg_info.c index a85484238c3..0f1d191aa35 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -338,7 +338,7 @@ PHPDBG_INFO(classes) /* {{{ */ phpdbg_print_class_name(ce TSRMLS_CC); if ((*ce)->parent) { - phpdbg_xml(""); + phpdbg_xml(""); zend_class_entry *pce = (*ce)->parent; do { phpdbg_out("|-------- "); diff --git a/phpdbg_print.c b/phpdbg_print.c index 799734c9fa3..9a8edb3abaf 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -167,7 +167,7 @@ PHPDBG_PRINT(class) /* {{{ */ (*ce)->name, zend_hash_num_elements(&(*ce)->function_table)); - phpdbg_xml(""); + phpdbg_xml(""); if (zend_hash_num_elements(&(*ce)->function_table)) { HashPosition position; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index ad8c104475c..992d50f1107 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -671,7 +671,7 @@ out: int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv TSRMLS_DC) { phpdbg_notice("eval", "variable=\"%.*s\"", "Printing variable %.*s", (int) len, name); - phpdbg_xml(""); + phpdbg_xml(""); zend_print_zval_r(*zv, 0 TSRMLS_CC); phpdbg_xml(""); phpdbg_out("\n"); @@ -704,7 +704,7 @@ PHPDBG_COMMAND(ev) /* {{{ */ PHPDBG_G(flags) |= PHPDBG_IN_EVAL; zend_try { if (zend_eval_stringl(param->str, param->len,&retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { - phpdbg_xml(""); + phpdbg_xml(""); zend_print_zval_r(&retval, 0 TSRMLS_CC); phpdbg_xml(""); phpdbg_out("\n"); @@ -742,7 +742,7 @@ PHPDBG_COMMAND(back) /* {{{ */ PHPDBG_COMMAND(print) /* {{{ */ { phpdbg_out("Execution Context Information\n\n"); - phpdbg_xml(""); + phpdbg_xml(""); #ifdef HAVE_LIBREADLINE phpdbg_writeln("print", "readline=\"yes\"", "Readline yes"); #else @@ -1110,7 +1110,7 @@ PHPDBG_COMMAND(clean) /* {{{ */ } phpdbg_out("Cleaning Execution Environment\n"); - phpdbg_xml(""); + phpdbg_xml(""); phpdbg_writeln("clean", "classes=\"%d\"", "Classes %d", zend_hash_num_elements(EG(class_table))); phpdbg_writeln("clean", "functions=\"%d\"", "Functions %d", zend_hash_num_elements(EG(function_table))); @@ -1127,7 +1127,7 @@ PHPDBG_COMMAND(clean) /* {{{ */ PHPDBG_COMMAND(clear) /* {{{ */ { phpdbg_out("Clearing Breakpoints\n"); - phpdbg_xml(""); + phpdbg_xml(""); phpdbg_writeln("clear", "files=\"%d\"", "File %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE])); phpdbg_writeln("clear", "functions=\"%d\"", "Functions %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM])); diff --git a/phpdbg_watch.c b/phpdbg_watch.c index be37a96f165..af1bcc97155 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -550,7 +550,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { PHPDBG_G(watchpoint_hit) = 1; phpdbg_notice("watchhit", "variable=\"%s\"", "Breaking on watchpoint %.*s", (int) watch->str_len, watch->str); - phpdbg_xml(""); + phpdbg_xml(""); } switch (watch->type) { @@ -564,7 +564,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_writeln("watchvalue", "type=\"old\" inaccessible=\"inaccessible\"", "Old value inaccessible, array or object (HashTable) already destroyed"); } else { phpdbg_out("Old value: "); - phpdbg_xml(""); + phpdbg_xml(""); zend_print_flat_zval_r((zval *) oldPtr TSRMLS_CC); phpdbg_xml(""); phpdbg_out("\n"); @@ -590,7 +590,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { if (show_value) { phpdbg_out("New value: "); - phpdbg_xml(""); + phpdbg_xml(""); zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); phpdbg_xml(""); phpdbg_out("\n"); @@ -686,7 +686,7 @@ void phpdbg_list_watchpoints(TSRMLS_D) { HashPosition position; phpdbg_watchpoint_t **watch; - phpdbg_xml(""); + phpdbg_xml(""); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(watchpoints), &position); zend_hash_get_current_data_ex(&PHPDBG_G(watchpoints), (void**) &watch, &position) == SUCCESS; diff --git a/xml.md b/xml.md index 5cf45535c7d..bd5e6745032 100644 --- a/xml.md +++ b/xml.md @@ -69,7 +69,7 @@ intro - appears on startup if -q flag wasn't provided as command line arg - before any input possibility - attributes may be spread over multiple tags -- wrapped in tag +- wrapped in <intros> tag ### attributes ### From 31b6024c65a4480a26866fb60bec54e92038ba5a Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 12:35:54 +0200 Subject: [PATCH 052/125] Updated xml.md --- xml.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/xml.md b/xml.md index bd5e6745032..7871b313766 100644 --- a/xml.md +++ b/xml.md @@ -228,7 +228,7 @@ frame - maxnum: tried to access a frame with a number heigher than existing (or < 0) ### attributes on <arg> ### -v + - variadic: has a non-empty value if the argument is variadic - name: variable name of parameter @@ -283,13 +283,13 @@ info (subcommands) - Format: - <meminfo /> - <current /> - <used mem="" /> - <real mem="" /> - <peak /> - <used mem="" /> - <real mem="" /> + <meminfo /> + <current /> + <used mem="" /> + <real mem="" /> + <peak /> + <used mem="" /> + <real mem="" /> - mem is an attribute whose value is a float. The memory is given in kilobytes (1 kB == 1024 bytes) @@ -648,3 +648,4 @@ Other tags --------------- - generally emitted when data couldn't be fetched (e.g. by accessing inconsistent data); only used in hard interrupt mode +- it might mean that data couldn't be fetched at all, or that only incomplete data was fetched (e.g. when a fixed number of following attributes are fetched, this tag will mark a stop of fetching if none or not all tags were printed) From a54de936d028033304f385947fd67d69ae813fc5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 12:43:53 +0200 Subject: [PATCH 053/125] Fixed segfault when listing and last line is empty --- phpdbg_list.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/phpdbg_list.c b/phpdbg_list.c index 83c27bcfbca..365c7a62e8c 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -162,7 +162,7 @@ void phpdbg_list_file(const char *filename, uint count, uint offset, uint highli } } - if (*(buffer + linelen - 1) != '\n') { + if (*(buffer + linelen - 1) != '\n' || !linelen) { phpdbg_out("\n"); } } @@ -265,8 +265,9 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) { dataptr->line[++line] = (uint)(bufptr - data.buf) + 1; } } - dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line); dataptr->lines = ++line; + dataptr->line[line] = endptr - data.buf; + dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line); ret = PHPDBG_G(compile_file)(&fake, type TSRMLS_CC); From 0bcb32ae47fe308cad008f9ff65c7a998da75d2b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 12:43:53 +0200 Subject: [PATCH 054/125] Fixed segfault when listing and last line is empty Conflicts: phpdbg_list.c --- phpdbg_list.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/phpdbg_list.c b/phpdbg_list.c index 6a53b8d5e7d..5ea3a3efd8e 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -158,6 +158,10 @@ void phpdbg_list_file(const char *filename, uint count, uint offset, uint highli phpdbg_write(">%05u: %.*s", line, linelen, buffer); } } + + if (*(buffer + linelen - 1) != '\n' || !linelen) { + phpdbg_writeln(EMPTY); + } } } /* }}} */ @@ -256,8 +260,9 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) { dataptr->line[++line] = (uint)(bufptr - data.buf) + 1; } } - dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line); dataptr->lines = ++line; + dataptr->line[line] = endptr - data.buf; + dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line); ret = PHPDBG_G(compile_file)(&fake, type TSRMLS_CC); From f4f9e39faaef3227e13a57d7c4392e95d0e1caba Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 14:54:08 +0200 Subject: [PATCH 055/125] Fix ev/run/sh parsing --- phpdbg_parser.c | 12 ++++++------ phpdbg_parser.y | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/phpdbg_parser.c b/phpdbg_parser.c index b50ab12f246..c7668683699 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -1651,8 +1651,8 @@ yyreduce: #line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = EVAL_PARAM; - (yyval).str = (yyvsp[(2) - (3)]).str; - (yyval).len = (yyvsp[(2) - (3)]).len; + (yyval).str = (yyvsp[(3) - (3)]).str; + (yyval).len = (yyvsp[(3) - (3)]).len; } break; @@ -1662,8 +1662,8 @@ yyreduce: #line 151 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = SHELL_PARAM; - (yyval).str = (yyvsp[(2) - (3)]).str; - (yyval).len = (yyvsp[(2) - (3)]).len; + (yyval).str = (yyvsp[(3) - (3)]).str; + (yyval).len = (yyvsp[(3) - (3)]).len; } break; @@ -1683,8 +1683,8 @@ yyreduce: #line 160 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; - (yyval).str = (yyvsp[(2) - (3)]).str; - (yyval).len = (yyvsp[(2) - (3)]).len; + (yyval).str = (yyvsp[(3) - (3)]).str; + (yyval).len = (yyvsp[(3) - (3)]).len; } break; diff --git a/phpdbg_parser.y b/phpdbg_parser.y index 3af4552538d..e4353976f3e 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -145,13 +145,13 @@ req_id full_expression : T_EVAL req_id T_INPUT { $$.type = EVAL_PARAM; - $$.str = $2.str; - $$.len = $2.len; + $$.str = $3.str; + $$.len = $3.len; } | T_SHELL req_id T_INPUT { $$.type = SHELL_PARAM; - $$.str = $2.str; - $$.len = $2.len; + $$.str = $3.str; + $$.len = $3.len; } | T_RUN req_id { $$.type = RUN_PARAM; @@ -159,8 +159,8 @@ full_expression } | T_RUN req_id T_INPUT { $$.type = RUN_PARAM; - $$.str = $2.str; - $$.len = $2.len; + $$.str = $3.str; + $$.len = $3.len; } ; From e72b00b1ec57d7217731d05a881b8c244d1e5325 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 14:54:47 +0200 Subject: [PATCH 056/125] Only show req attribute if given --- phpdbg_utils.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index c2137020faa..6c65ebe10b4 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -780,8 +780,13 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca case 'r': - s_len = spprintf(&s, 0, "req=\"%lu\"", PHPDBG_G(req_id)); - free_s = s; + if (PHPDBG_G(req_id)) { + s_len = spprintf(&s, 0, "req=\"%lu\"", PHPDBG_G(req_id)); + free_s = s; + } else { + s = ""; + s_len = 0; + } break; From 9dfc5d551143c41b32d98aa68219ec075a9b4bd2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 9 Oct 2014 16:06:10 +0200 Subject: [PATCH 057/125] Escape control characters --- phpdbg_utils.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 6c65ebe10b4..11e3a52a237 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1086,11 +1086,38 @@ static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char * { int len = tmp - *buf; - *buf = erealloc(*buf, len); + *buf = erealloc(*buf, len + 1); return len; } } +static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) { + char *tmp, *tmpptr; + int len = *buflen; + int i; + + tmp = tmpptr = emalloc(*buflen * 5); + + for (i = 0; i < *buflen; i++) { + if ((*buf)[i] < 0x20) { + len += 4; + *tmpptr++ = '&'; + *tmpptr++ = '#'; + *tmpptr++ = ((*buf)[i] / 10) + '0'; + *tmpptr++ = ((*buf)[i] % 10) + '0'; + *tmpptr++ = ';'; + } else { + *tmpptr++ = (*buf)[i]; + } + } + + len = tmpptr - tmp; + + efree(*buf); + *buf = erealloc(tmp, len + 1); + *buflen = len; +} + static int phpdbg_process_print(int fd, int type, const char *tag, const char *msg, int msglen, const char *xml, int xmllen TSRMLS_DC) { char *msgout = NULL, *buf; int msgoutlen, xmloutlen, buflen; @@ -1174,6 +1201,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m PHPDBG_G(in_script_xml) = type; } buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); + phpdbg_encode_ctrl_chars(&buf, &buflen); write(fd, buf, buflen); efree(buf); } else { @@ -1216,6 +1244,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m xmloutlen = spprintf(&xmlout, 0, "<%s severity=\"%s\" %.*s msgout=\"\" />", tag, severity, xmllen, xml); } + phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen); write(fd, xmlout, xmloutlen); efree(xmlout); } else if (msgout) { From 3445e0e59ed8d3852664532f345e924f7100a54a Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 11 Oct 2014 00:20:30 +0200 Subject: [PATCH 058/125] Fix issue krakjoe/phpdbg#122 (segfault in helpaliases) --- phpdbg_help.c | 6 +++--- phpdbg_utils.c | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 3adc38b6aea..29087e005df 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -265,10 +265,10 @@ PHPDBG_HELP(aliases) /* {{{ */ /* Print out aliases for all commands except help as this one comes last */ phpdbg_writeln("help", "", "Below are the aliased, short versions of all supported commands"); - phpdbg_xml(""); + phpdbg_xml(""); for(c = phpdbg_prompt_commands; c->name; c++) { if (c->alias && c->alias != 'h') { - phpdbg_writeln("command", "name=\"%s\" alias=\"%c\" tip=\"%s\"", " %c %-20s %s", c->alias, c->name, c->tip); + phpdbg_writeln("command", "alias=\"%c\" name=\"%s\" tip=\"%s\"", " %c %-20s %s", c->alias, c->name, c->tip); if (c->subs) { len = 20 - 1 - c->name_len; for(c_sub = c->subs; c_sub->alias; c_sub++) { @@ -285,7 +285,7 @@ PHPDBG_HELP(aliases) /* {{{ */ /* Print out aliases for help as this one comes last, with the added text on how aliases are used */ get_command("h", 1, &c, phpdbg_prompt_commands TSRMLS_CC); - phpdbg_writeln("aliasinfo", "alias=\"%c\" name=\"%-*s\" tip=\"%s\"", " %c %-20s %s\n", c->alias, c->name, c->tip); + phpdbg_writeln("aliasinfo", "alias=\"%c\" name=\"%s\" tip=\"%s\"", " %c %-20s %s\n", c->alias, c->name, c->tip); phpdbg_xml(""); diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 11e3a52a237..c631d8f5256 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -772,8 +772,8 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca s_len = precision; } } else { - s = S_NULL; - s_len = S_NULL_LEN; + s = ""; + s_len = 0; } pad_char = ' '; break; @@ -1279,6 +1279,8 @@ PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, int fd, const char *tag, const va_copy(argcpy, args); xmllen = phpdbg_xml_vasprintf(&xml, xmlfmt, 1, argcpy TSRMLS_CC); va_end(argcpy); + } else { + xml = estrdup(""); } } From e19c7899799d8b5b1eacf6335f994fcbac10e2b3 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 11 Oct 2014 23:36:12 +0200 Subject: [PATCH 059/125] Maybe-fix for krakjoe/phpdbg#120, fixed remote on darwin --- phpdbg.c | 13 ++++++------- phpdbg_cmd.c | 6 +++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index c27bf60278b..1a7a1f83106 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -834,12 +834,10 @@ static void phpdbg_remote_close(int socket, FILE *stream) { } /* don't inline this, want to debug it easily, will inline when done */ -static int phpdbg_remote_init(const char* address, unsigned short port, int *server, int *socket, FILE **stream) { +static int phpdbg_remote_init(const char* address, unsigned short port, int server, int *socket, FILE **stream) { phpdbg_remote_close(*socket, *stream); - *server = phpdbg_open_socket(address, port); - - if (*server < 0) { + if (server < 0) { phpdbg_rlog(fileno(stderr), "Initializing connection on %s:%u failed", address, port); return FAILURE; @@ -852,7 +850,7 @@ static int phpdbg_remote_init(const char* address, unsigned short port, int *ser char buffer[20] = {0}; memset(&address, 0, size); - *socket = accept(*server, (struct sockaddr *) &address, &size); + *socket = accept(server, (struct sockaddr *) &address, &size); inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); phpdbg_rlog(fileno(stderr), "connection established from %s", buffer); @@ -1302,7 +1300,8 @@ phpdbg_main: #ifndef _WIN32 /* setup remote server if necessary */ if (!cleaning && listen > 0) { - if (phpdbg_remote_init(address, listen, &server, &socket, &stream) == FAILURE) { + server = phpdbg_open_socket(address, listen); + if (phpdbg_remote_init(address, listen, server, &socket, &stream) == FAILURE) { exit(0); } @@ -1493,7 +1492,7 @@ phpdbg_interact: if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { /* renegociate connections */ - phpdbg_remote_init(address, listen, &server, &socket, &stream); + phpdbg_remote_init(address, listen, server, &socket, &stream); /* set streams */ if (stream) { diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 69f8eeef8c4..3eb4f722341 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -834,8 +834,12 @@ readline: memcpy(buf, PHPDBG_G(input_buffer), len); } - while ((bytes = read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len)) > 0) { + while ((bytes = read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len)) > 0 || (errno == EINTR && bytes < 0)) { int i; + if (bytes <= 0) { + continue; + } + for (i = len; i < len + bytes; i++) { if (buf[i] == '\n') { PHPDBG_G(input_buflen) = len + bytes - 1 - i; From 1486a9ebf7c42120fb5dd3e12a8de44fe1527ed7 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 12 Oct 2014 00:30:09 +0200 Subject: [PATCH 060/125] Fix some compiler warnings --- phpdbg.h | 7 +++++++ phpdbg_cmd.c | 2 +- phpdbg_set.c | 2 +- phpdbg_watch.c | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/phpdbg.h b/phpdbg.h index e567e221fa6..a3835f3c064 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -90,6 +90,13 @@ #define PHPDBG_DEFAULT_PROMPT "prompt>" /* }}} */ +/* Hey, apple. One shouldn't define *functions* from the standard C library as marcos. */ +#ifdef memcpy +#define memcpy_tmp(...) memcpy(__VA_ARGS__) +#undef memcpy +#define memcpy(...) memcpy_tmp(__VA_ARGS__) +#endif + #if !defined(PHPDBG_WEBDATA_TRANSFER_H) && !defined(PHPDBG_WEBHELPER_H) #ifdef ZTS diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 3eb4f722341..f649bdecf6d 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -836,7 +836,7 @@ readline: while ((bytes = read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len)) > 0 || (errno == EINTR && bytes < 0)) { int i; - if (bytes <= 0) { + if (bytes <= 0) { continue; } diff --git a/phpdbg_set.c b/phpdbg_set.c index 7e164995fd9..fc7e788fa03 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -215,7 +215,7 @@ PHPDBG_SET(stepping) /* {{{ */ phpdbg_writeln("setstepping", "type=\"%s\"", "Stepping %s", PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line"); } else switch (param->type) { case STR_PARAM: { - if ((param->len == sizeof("opcode") - 1) && memcmp(param->str, "opcode", sizeof("opcode") == SUCCESS)) { + if ((param->len == sizeof("opcode") - 1) && memcmp(param->str, "opcode", sizeof("opcode")) == SUCCESS) { PHPDBG_G(flags) |= PHPDBG_STEP_OPCODE; } else if ((param->len == sizeof("line")-1) && memcmp(param->str, "line", sizeof("line")) == SUCCESS) { PHPDBG_G(flags) &= ~PHPDBG_STEP_OPCODE; diff --git a/phpdbg_watch.c b/phpdbg_watch.c index af1bcc97155..de6cddf5b3c 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -303,7 +303,7 @@ static int phpdbg_watchpoint_parse_wrapper(char *name, size_t len, char *keyname } PHPDBG_API int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC), zend_bool silent TSRMLS_DC) { - phpdbg_parse_variable_with_arg(input, len, parent, i, (phpdbg_parse_var_with_arg_func) phpdbg_watchpoint_parse_wrapper, 0, callback TSRMLS_CC); + return phpdbg_parse_variable_with_arg(input, len, parent, i, (phpdbg_parse_var_with_arg_func) phpdbg_watchpoint_parse_wrapper, 0, callback TSRMLS_CC); } static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { From a5607c4b5ac45d7bc525ffbd0dc567fc5e8c2404 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 12 Oct 2014 19:31:38 +0200 Subject: [PATCH 061/125] fix config.w32 --- config.w32 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config.w32 b/config.w32 index 17e15b6ced0..86f8949cd0d 100644 --- a/config.w32 +++ b/config.w32 @@ -1,7 +1,10 @@ ARG_ENABLE('phpdbg', 'Build phpdbg', 'no'); ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); -PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c phpdbg_parser.c phpdbg_lexer.c'; +PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c ' + + 'phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c ' + + 'phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c '+ + 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; From d5ce62c17c8246d43c43cd9177b76f8febc0b9e5 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 12 Oct 2014 19:53:05 +0200 Subject: [PATCH 062/125] basic rework for remote on win --- phpdbg.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 787ffe7db8e..9707b990989 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -740,7 +740,6 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */ } } /* }}} */ -#ifndef _WIN32 int phpdbg_open_socket(const char *interface, short port) /* {{{ */ { int reuse = 1; @@ -781,8 +780,12 @@ int phpdbg_open_socket(const char *interface, short port) /* {{{ */ static void phpdbg_remote_close(int socket, FILE *stream) { if (socket >= 0) { +#ifdef _WIN32 + closesocket(socket); +#else shutdown(socket, SHUT_RDWR); close(socket); +#endif } if (stream) { @@ -827,6 +830,7 @@ static int phpdbg_remote_init(const char* address, unsigned short port, int *ser return SUCCESS; } +#ifndef _WIN32 /* This function *strictly* assumes that SIGIO is *only* used on the remote connection stream */ void phpdbg_sigio_handler(int sig, siginfo_t *info, void *context) /* {{{ */ { @@ -964,13 +968,11 @@ int main(int argc, char **argv) /* {{{ */ char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX"; #endif -#ifndef _WIN32 char *address; int listen = -1; int server = -1; int socket = -1; FILE* stream = NULL; -#endif #ifdef ZTS void ***tsrm_ls; @@ -1149,7 +1151,6 @@ phpdbg_main: show_banner = 0; break; -#ifndef _WIN32 /* if you pass a listen port, we will read and write on listen port */ case 'l': /* set listen ports */ if (sscanf(php_optarg, "%d", &listen) != 1) { @@ -1163,7 +1164,6 @@ phpdbg_main: address = strdup("*"); } else address = strdup(php_optarg); } break; -#endif case 'V': { sapi_startup(phpdbg); @@ -1252,19 +1252,19 @@ phpdbg_main: #endif zend_mm_heap *mm_heap; -#ifndef _WIN32 /* setup remote server if necessary */ if (!cleaning && listen > 0) { if (phpdbg_remote_init(address, listen, &server, &socket, &stream) == FAILURE) { exit(0); } +#ifndef _WIN32 sigaction(SIGIO, &sigio_struct, NULL); +#endif /* set remote flag to stop service shutting down upon quit */ remote = 1; } -#endif mm_heap = phpdbg_mm_get_heap(); @@ -1338,14 +1338,13 @@ phpdbg_main: /* set flags from command line */ PHPDBG_G(flags) = flags; -#ifndef _WIN32 /* setup io here */ if (stream) { PHPDBG_G(flags) |= PHPDBG_IS_REMOTE; - +#ifndef _WIN32 signal(SIGPIPE, SIG_IGN); - } #endif + } PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin; PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin); @@ -1418,10 +1417,7 @@ phpdbg_main: } } -/* #ifndef for making compiler shutting up */ -#ifndef _WIN32 phpdbg_interact: -#endif /* phpdbg main() */ do { zend_try { @@ -1436,7 +1432,6 @@ phpdbg_interact: cleaning = 0; } -#ifndef _WIN32 if (!cleaning) { /* remote client disconnected */ if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) { @@ -1458,7 +1453,6 @@ phpdbg_interact: } } } -#endif } zend_end_try(); } while(!cleaning && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); @@ -1468,19 +1462,17 @@ phpdbg_interact: /* this is just helpful */ PG(report_memleaks) = 0; -#ifndef _WIN32 phpdbg_out: if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) { PHPDBG_G(flags) &= ~PHPDBG_IS_DISCONNECTED; goto phpdbg_interact; } -#endif #ifdef _WIN32 } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) { phpdbg_error("Access violation (Segementation fault) encountered\ntrying to abort cleanly..."); } -phpdbg_out: +/* phpdbg_out: */ #endif { From 449fd307e40e00e582b4b79ac18b13c1c530bc23 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 12 Oct 2014 20:05:26 +0200 Subject: [PATCH 063/125] enable console options for remote on win --- phpdbg.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 9707b990989..d30e4951644 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -663,10 +663,8 @@ const opt_struct OPTIONS[] = { /* {{{ */ {'r', 0, "run"}, {'E', 0, "step-through-eval"}, {'S', 1, "sapi-name"}, -#ifndef _WIN32 {'l', 1, "listen"}, {'a', 1, "address-or-any"}, -#endif {'V', 0, "version"}, {'-', 0, NULL} }; /* }}} */ @@ -985,10 +983,9 @@ int main(int argc, char **argv) /* {{{ */ signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER; sigio_struct.sa_sigaction = phpdbg_sigio_handler; sigio_struct.sa_flags = SA_SIGINFO; - +#endif address = strdup("127.0.0.1"); -#endif #ifdef PHP_WIN32 _fmode = _O_BINARY; /* sets default for file streams to binary */ From c812ee9c3556c0ea797627c86a0a650c65f9908b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 14 Oct 2014 09:16:30 +0200 Subject: [PATCH 064/125] Fix invalid efree() on null pointer and add help for -x --- phpdbg_help.c | 5 +++-- phpdbg_utils.c | 10 +++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 29087e005df..2990edd16d3 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -133,10 +133,10 @@ void pretty_print(char *text TSRMLS_DC) *q++ = '\0'; if ((q-new)>size) { - phpdbg_error("help", "overrun=\"%lu\"", "Output overrun of %lu bytes", ((q-new) - size)); + phpdbg_error("help", "overrun=\"%lu\"", "Output overrun of %lu bytes", ((q - new) - size)); } - phpdbg_out("%s", new); + phpdbg_out("%s\n", new); efree(new); } /* }}} */ @@ -387,6 +387,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **-S** **-S**cli Override SAPI name, careful!" CR " **-l** **-l**4000 Setup remote console ports" CR " **-a** **-a**192.168.0.3 Setup remote console bind address" CR +" **-x** Enable xml output (instead of normal text output)" CR " **-V** Print version number" CR " **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv " "argument after it" CR CR diff --git a/phpdbg_utils.c b/phpdbg_utils.c index c631d8f5256..27b75b24ae4 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1290,8 +1290,10 @@ PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, int fd, const char *tag, const PHPDBG_G(err_buf).tag = estrdup(tag); PHPDBG_G(err_buf).msg = msg; PHPDBG_G(err_buf).msglen = msglen; - PHPDBG_G(err_buf).xml = xml; - PHPDBG_G(err_buf).xmllen = xmllen; + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + PHPDBG_G(err_buf).xml = xml; + PHPDBG_G(err_buf).xmllen = xmllen; + } return msglen; } @@ -1318,7 +1320,9 @@ PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D) { efree(PHPDBG_G(err_buf).tag); efree(PHPDBG_G(err_buf).msg); - efree(PHPDBG_G(err_buf).xml); + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + efree(PHPDBG_G(err_buf).xml); + } } PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC) { From b28e3d01d77ee29fc5442d9d0b3d8f06b78b41a1 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 15 Oct 2014 20:30:16 +0200 Subject: [PATCH 065/125] Fix ctrl characters handling --- phpdbg_cmd.c | 8 ++++++++ phpdbg_utils.c | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index f649bdecf6d..ad49c62b259 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -841,6 +841,14 @@ readline: } for (i = len; i < len + bytes; i++) { + if (buf[i] == '\x03') { + if (i != len + bytes - 1) { + memmove(buf + i, buf + i + 1, len + bytes - i - 1); + } + len--; + i--; + continue; + } if (buf[i] == '\n') { PHPDBG_G(input_buflen) = len + bytes - 1 - i; if (PHPDBG_G(input_buflen)) { diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 27b75b24ae4..41178870f40 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1103,7 +1103,11 @@ static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) { len += 4; *tmpptr++ = '&'; *tmpptr++ = '#'; - *tmpptr++ = ((*buf)[i] / 10) + '0'; + if ((unsigned int) buf[i] > 10) { + *tmpptr++ = ((*buf)[i] / 10) + '0'; + } else { + --len; + } *tmpptr++ = ((*buf)[i] % 10) + '0'; *tmpptr++ = ';'; } else { @@ -1373,6 +1377,8 @@ PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) { buflen = phpdbg_xml_vasprintf(&buffer, fmt, 1, args TSRMLS_CC); va_end(args); + phpdbg_encode_ctrl_chars(&buffer, &buflen); + if (PHPDBG_G(in_script_xml)) { write(fd, ZEND_STRL("")); PHPDBG_G(in_script_xml) = 0; @@ -1416,6 +1422,7 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { int msglen; msglen = phpdbg_encode_xml(&msg, buffer, buflen, 256, NULL); + phpdbg_encode_ctrl_chars(&msg, &msglen); if (PHPDBG_G(in_script_xml)) { write(fd, ZEND_STRL("")); From 22f1c8a062d0a89989a005e021ab3f8b1104275e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 15 Oct 2014 22:00:33 +0200 Subject: [PATCH 066/125] Fix segfault in exceptions with xml --- phpdbg_prompt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 992d50f1107..64f43cb2043 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -551,7 +551,7 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ zend_call_function(&fci, NULL TSRMLS_CC); if (trace) { - phpdbg_writeln("exception", "name=\"%s\" trace=\"%s\"", "Uncaught %s!\n%.*s", Z_OBJCE(exception)->name, Z_STRLEN_P(trace), Z_STRVAL_P(trace)); + phpdbg_writeln("exception", "name=\"%s\" trace=\"%.*s\"", "Uncaught %s!\n%.*s", Z_OBJCE(exception)->name, Z_STRLEN_P(trace), Z_STRVAL_P(trace)); zval_ptr_dtor(&trace); } else { From 68694e31418501151b6d7996574b31ad60db2dcd Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 16 Oct 2014 11:04:45 +0200 Subject: [PATCH 067/125] Fix invalid dereference --- phpdbg_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 41178870f40..991a6c23634 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1103,7 +1103,7 @@ static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) { len += 4; *tmpptr++ = '&'; *tmpptr++ = '#'; - if ((unsigned int) buf[i] > 10) { + if ((unsigned int) ((*buf)[i]) > 10) { *tmpptr++ = ((*buf)[i] / 10) + '0'; } else { --len; From a80f0b982ae0d13fc3cc2ad05b5a2fea632ac331 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 16 Oct 2014 12:27:26 +0200 Subject: [PATCH 068/125] Fix lexing of -r \d+ in raw-string commands --- phpdbg_help.c | 2 +- phpdbg_lexer.c | 527 ++++++++++++++++++++++++++++--------------------- phpdbg_lexer.l | 20 +- 3 files changed, 322 insertions(+), 227 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 2990edd16d3..3fed04e7455 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -62,7 +62,7 @@ void pretty_print(char *text TSRMLS_DC) unsigned int line_count = 0; /* number printable chars on current line */ if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_xml("", text); + phpdbg_xml("", text); return; } diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 68895b4e3dd..90f3a449daa 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -1,5 +1,5 @@ /* Generated by re2c 0.13.5 */ -#line 1 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 1 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" /* * phpdbg_lexer.l */ @@ -23,8 +23,9 @@ #define YYFILL(n) #define NORMAL 0 -#define RAW 1 -#define INITIAL 2 +#define PRE_RAW 1 +#define RAW 2 +#define INITIAL 3 ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -44,14 +45,18 @@ restart: LEX(text) = YYCURSOR; -#line 48 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 49 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" { YYCTYPE yych; unsigned int yyaccept = 0; - if (YYGETCONDITION() < 1) { - goto yyc_NORMAL; + if (YYGETCONDITION() < 2) { + if (YYGETCONDITION() < 1) { + goto yyc_NORMAL; + } else { + goto yyc_PRE_RAW; + } } else { - if (YYGETCONDITION() < 2) { + if (YYGETCONDITION() < 3) { goto yyc_RAW; } else { goto yyc_INITIAL; @@ -145,14 +150,14 @@ yy2: yy3: YYDEBUG(3, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 168 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 176 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(NORMAL); YYCURSOR = LEX(text); goto restart; } -#line 156 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 161 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy4: YYDEBUG(4, *YYCURSOR); ++YYCURSOR; @@ -167,11 +172,11 @@ yy4: yy6: YYDEBUG(6, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 69 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 175 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 180 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy7: YYDEBUG(7, *YYCURSOR); yych = *++YYCURSOR; @@ -238,13 +243,13 @@ yy16: } YYDEBUG(18, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 162 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 163 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { - YYSETCONDITION(RAW); + YYSETCONDITION(PRE_RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_RUN; } -#line 248 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 253 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy19: YYDEBUG(19, *YYCURSOR); yych = *++YYCURSOR; @@ -271,13 +276,13 @@ yy20: yy22: YYDEBUG(22, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 157 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 158 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { - YYSETCONDITION(RAW); + YYSETCONDITION(PRE_RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } -#line 281 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 286 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy23: YYDEBUG(23, *YYCURSOR); yych = *++YYCURSOR; @@ -304,13 +309,13 @@ yy24: yy26: YYDEBUG(26, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 152 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 153 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { - YYSETCONDITION(RAW); + YYSETCONDITION(PRE_RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_EVAL; } -#line 314 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 319 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy27: YYDEBUG(27, *YYCURSOR); yych = *++YYCURSOR; @@ -329,13 +334,13 @@ yy29: if (yych == '\n') goto yy4; YYDEBUG(30, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 147 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ goto restart; } -#line 339 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 344 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" } /* *********************************** */ yyc_NORMAL: @@ -478,13 +483,13 @@ yy33: if (yych == '\n') goto yy36; YYDEBUG(35, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 147 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ goto restart; } -#line 488 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 493 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy36: YYDEBUG(36, *YYCURSOR); ++YYCURSOR; @@ -499,11 +504,11 @@ yy36: yy38: YYDEBUG(38, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 69 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 507 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 512 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy39: YYDEBUG(39, *YYCURSOR); yych = *++YYCURSOR; @@ -520,14 +525,14 @@ yy40: yy41: YYDEBUG(41, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 132 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 133 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_ID; } -#line 531 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 536 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy42: YYDEBUG(42, *YYCURSOR); yyaccept = 0; @@ -577,13 +582,13 @@ yy45: yy47: YYDEBUG(47, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 113 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 114 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } -#line 587 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 592 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy48: YYDEBUG(48, *YYCURSOR); yyaccept = 1; @@ -686,32 +691,32 @@ yy58: ++YYCURSOR; YYDEBUG(59, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 91 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 92 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { return T_POUND; } -#line 694 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 699 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy60: YYDEBUG(60, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == ':') goto yy62; YYDEBUG(61, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 97 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 98 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { return T_COLON; } -#line 705 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 710 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy62: YYDEBUG(62, *YYCURSOR); ++YYCURSOR; YYDEBUG(63, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 94 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 95 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { return T_DCOLON; } -#line 715 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 720 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy64: YYDEBUG(64, *YYCURSOR); yyaccept = 0; @@ -750,14 +755,14 @@ yy67: ++YYCURSOR; YYDEBUG(69, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 85 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 86 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_PROTO; } -#line 761 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 766 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy70: YYDEBUG(70, *YYCURSOR); yyaccept = 0; @@ -804,14 +809,14 @@ yy73: yy75: YYDEBUG(75, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 125 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 126 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = zend_strndup(yytext, yyleng); yylval->len = yyleng; return T_OPCODE; } -#line 815 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 820 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy76: YYDEBUG(76, *YYCURSOR); yyaccept = 0; @@ -851,13 +856,13 @@ yy81: } YYDEBUG(83, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 101 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 102 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return T_TRUTHY; } -#line 861 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 866 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy84: YYDEBUG(84, *YYCURSOR); yyaccept = 0; @@ -904,13 +909,13 @@ yy88: yy90: YYDEBUG(90, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 107 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 108 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return T_FALSY; } -#line 914 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 919 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy91: YYDEBUG(91, *YYCURSOR); yyaccept = 0; @@ -1035,13 +1040,13 @@ yy106: yy108: YYDEBUG(108, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 119 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 120 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, 0, 16); return T_ADDR; } -#line 1045 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 1050 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy109: YYDEBUG(109, *YYCURSOR); yyaccept = 0; @@ -1069,13 +1074,13 @@ yy110: yy112: YYDEBUG(112, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 79 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 80 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { YYSETCONDITION(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_IF; } -#line 1079 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 1084 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy113: YYDEBUG(113, *YYCURSOR); yyaccept = 0; @@ -1163,14 +1168,14 @@ yy117: yy119: YYDEBUG(119, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 72 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 73 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { char *text = yytext + 2; while (*++text < '0'); yylval->num = atoi(text); return T_REQ_ID; } -#line 1174 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 1179 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy120: YYDEBUG(120, *YYCURSOR); yych = *++YYCURSOR; @@ -1189,244 +1194,326 @@ yy121: goto yy119; } /* *********************************** */ -yyc_RAW: +yyc_PRE_RAW: { static const unsigned char yybm[] = { - 0, 32, 32, 32, 32, 32, 32, 32, - 32, 104, 80, 32, 32, 104, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 104, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 160, 32, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 160, 48, 0, 0, 160, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 160, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 64, 0, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }; YYDEBUG(123, *YYCURSOR); YYFILL(2); yych = *YYCURSOR; - if (yybm[0+yych] & 8) { - goto yy125; + if (yybm[0+yych] & 16) { + goto yy127; } - if (yych <= '\n') { - if (yych <= 0x00) goto yy131; - if (yych <= '\t') goto yy133; - goto yy128; + if (yych <= '\r') { + if (yych <= 0x08) { + if (yych <= 0x00) goto yy130; + goto yy132; + } else { + if (yych <= '\t') goto yy125; + if (yych <= '\f') goto yy132; + } } else { - if (yych == '-') goto yy132; - goto yy133; + if (yych <= ' ') { + if (yych <= 0x1F) goto yy132; + } else { + if (yych == '-') goto yy131; + goto yy132; + } } yy125: YYDEBUG(125, *YYCURSOR); ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(126, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy125; + if ((yych = *YYCURSOR) <= '\f') { + if (yych <= 0x00) goto yy142; + if (yych <= 0x08) goto yy126; + if (yych <= '\n') goto yy142; + } else { + if (yych <= '\r') goto yy142; + if (yych == ' ') goto yy142; } - if (yych <= 0x00) goto yy131; - if (yych == '\n') goto yy128; - goto yy133; +yy126: + YYDEBUG(126, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 169 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" + { + YYSETCONDITION(RAW); + + YYCURSOR = LEX(text); + goto restart; +} +#line 1277 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" yy127: YYDEBUG(127, *YYCURSOR); - yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 139 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" - { - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = zend_strndup(yytext, yyleng); - yylval->len = yyleng; - return T_INPUT; -} -#line 1265 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy128: - YYDEBUG(128, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; + YYDEBUG(128, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy141; + } + if (yych <= 0x00) goto yy140; + if (yych == '\n') goto yy127; +yy129: YYDEBUG(129, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy128; - } - if (yych <= '\f') { - if (yych <= 0x00) goto yy131; - if (yych == '\t') goto yy147; - } else { - if (yych <= '\r') goto yy147; - if (yych == ' ') goto yy147; - } -yy130: - YYDEBUG(130, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 69 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { return 0; } -#line 1289 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 1296 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" +yy130: + YYDEBUG(130, *YYCURSOR); + yych = *++YYCURSOR; + goto yy126; yy131: YYDEBUG(131, *YYCURSOR); - yych = *++YYCURSOR; - goto yy130; + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'r') goto yy133; + goto yy126; yy132: YYDEBUG(132, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'r') goto yy135; - goto yy134; + goto yy126; yy133: YYDEBUG(133, *YYCURSOR); ++YYCURSOR; - YYFILL(1); + YYFILL(2); yych = *YYCURSOR; -yy134: YYDEBUG(134, *YYCURSOR); if (yybm[0+yych] & 32) { goto yy133; } - goto yy127; + if (yych <= '.') { + if (yych <= ',') goto yy135; + if (yych <= '-') goto yy136; + goto yy137; + } else { + if (yych <= '/') goto yy135; + if (yych <= '9') goto yy137; + } yy135: YYDEBUG(135, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; + YYCURSOR = YYMARKER; + goto yy126; +yy136: YYDEBUG(136, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy141; - } - if (yych <= '\f') { - if (yych <= 0x08) { - if (yych <= 0x00) goto yy127; - goto yy133; - } else { - if (yych <= '\t') goto yy135; - if (yych >= '\v') goto yy133; - } - } else { - if (yych <= ' ') { - if (yych <= '\r') goto yy135; - if (yych <= 0x1F) goto yy133; - goto yy135; - } else { - if (yych == '-') goto yy140; - goto yy133; - } + yych = *++YYCURSOR; + if (yybm[0+yych] & 64) { + goto yy137; } + goto yy135; yy137: YYDEBUG(137, *YYCURSOR); ++YYCURSOR; - YYFILL(2); + YYFILL(1); yych = *YYCURSOR; YYDEBUG(138, *YYCURSOR); if (yybm[0+yych] & 64) { goto yy137; } - if (yych <= '.') { - if (yych <= ',') goto yy139; - if (yych <= '-') goto yy144; - goto yy145; - } else { - if (yych <= '/') goto yy139; - if (yych <= '9') goto yy145; - } -yy139: YYDEBUG(139, *YYCURSOR); - YYCURSOR = YYMARKER; - goto yy127; -yy140: - YYDEBUG(140, *YYCURSOR); - yych = *++YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy141; - } - goto yy134; -yy141: - YYDEBUG(141, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(142, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy141; - } - if (yych <= 0x00) goto yy143; - if (yych != '\n') goto yy133; -yy143: - YYDEBUG(143, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 72 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 73 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { char *text = yytext + 2; while (*++text < '0'); yylval->num = atoi(text); return T_REQ_ID; } -#line 1387 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" -yy144: - YYDEBUG(144, *YYCURSOR); +#line 1357 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" +yy140: + YYDEBUG(140, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '.') goto yy145; - if (yych <= '/') goto yy139; - if (yych >= ':') goto yy139; -yy145: - YYDEBUG(145, *YYCURSOR); + goto yy129; +yy141: + YYDEBUG(141, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(146, *YYCURSOR); - if (yych == '.') goto yy145; - if (yych <= '/') goto yy143; - if (yych <= '9') goto yy145; - goto yy143; -yy147: - YYDEBUG(147, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(148, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy128; +yy142: + YYDEBUG(142, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy141; } - if (yych <= '\f') { - if (yych <= 0x00) goto yy131; - if (yych == '\t') goto yy147; - } else { - if (yych <= '\r') goto yy147; - if (yych == ' ') goto yy147; - } - YYDEBUG(149, *YYCURSOR); + if (yych <= 0x00) goto yy140; + if (yych == '\n') goto yy127; + YYDEBUG(143, *YYCURSOR); yyleng = (size_t) YYCURSOR - (size_t) yytext; -#line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 147 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ goto restart; } -#line 1428 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.c" +#line 1382 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" + } +/* *********************************** */ +yyc_RAW: + { + static const unsigned char yybm[] = { + 0, 128, 128, 128, 128, 128, 128, 128, + 128, 160, 64, 128, 128, 160, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 160, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + }; + YYDEBUG(144, *YYCURSOR); + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 32) { + goto yy146; + } + if (yych <= 0x00) goto yy152; + if (yych == '\n') goto yy149; + goto yy153; +yy146: + YYDEBUG(146, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(147, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy146; + } + if (yych <= 0x00) goto yy152; + if (yych == '\n') goto yy149; + goto yy153; +yy148: + YYDEBUG(148, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 140 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" + { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = zend_strndup(yytext, yyleng); + yylval->len = yyleng; + return T_INPUT; +} +#line 1452 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" +yy149: + YYDEBUG(149, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(150, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy149; + } + if (yych <= '\f') { + if (yych <= 0x00) goto yy152; + if (yych == '\t') goto yy155; + } else { + if (yych <= '\r') goto yy155; + if (yych == ' ') goto yy155; + } +yy151: + YYDEBUG(151, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 69 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" + { + return 0; +} +#line 1476 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" +yy152: + YYDEBUG(152, *YYCURSOR); + yych = *++YYCURSOR; + goto yy151; +yy153: + YYDEBUG(153, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(154, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy153; + } + goto yy148; +yy155: + YYDEBUG(155, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(156, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy149; + } + if (yych <= '\f') { + if (yych <= 0x00) goto yy152; + if (yych == '\t') goto yy155; + } else { + if (yych <= '\r') goto yy155; + if (yych == ' ') goto yy155; + } + YYDEBUG(157, *YYCURSOR); + yyleng = (size_t) YYCURSOR - (size_t) yytext; +#line 147 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" + { + /* ignore whitespace */ + + goto restart; +} +#line 1515 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.c" } } -#line 175 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_lexer.l" +#line 183 "/Users/Bob/php-src-5.6/sapi/phpdbg/phpdbg_lexer.l" } diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 11fdc913c72..0c27fc22ace 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -21,8 +21,9 @@ #define YYFILL(n) #define NORMAL 0 -#define RAW 1 -#define INITIAL 2 +#define PRE_RAW 1 +#define RAW 2 +#define INITIAL 3 ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -69,7 +70,7 @@ INPUT [^\n\000]+ return 0; } -[-][r]{WS}?{DIGITS} { +[-][r]{WS}?{DIGITS} { char *text = yytext + 2; while (*++text < '0'); yylval->num = atoi(text); @@ -150,21 +151,28 @@ INPUT [^\n\000]+ } {T_EVAL}{WS} { - YYSETCONDITION(RAW); + YYSETCONDITION(PRE_RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_EVAL; } {T_SHELL}{WS} { - YYSETCONDITION(RAW); + YYSETCONDITION(PRE_RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } ({T_RUN}|{T_RUN_SHORT}){WS} { - YYSETCONDITION(RAW); + YYSETCONDITION(PRE_RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_RUN; } +. { + YYSETCONDITION(RAW); + + YYCURSOR = LEX(text); + goto restart; +} + . { YYSETCONDITION(NORMAL); From afe01e4956f37090a52a5bebf25bf4c8b57da8c5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 17 Oct 2014 19:32:02 +0200 Subject: [PATCH 069/125] Fix negative list offsets --- phpdbg_list.c | 2 +- phpdbg_list.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_list.c b/phpdbg_list.c index 365c7a62e8c..80b5d2b1892 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -124,7 +124,7 @@ PHPDBG_LIST(class) /* {{{ */ return SUCCESS; } /* }}} */ -void phpdbg_list_file(const char *filename, uint count, uint offset, uint highlight TSRMLS_DC) /* {{{ */ +void phpdbg_list_file(const char *filename, uint count, int offset, uint highlight TSRMLS_DC) /* {{{ */ { uint line, lastline; phpdbg_file_source **data; diff --git a/phpdbg_list.h b/phpdbg_list.h index 385ae205804..c88328bfeaf 100644 --- a/phpdbg_list.h +++ b/phpdbg_list.h @@ -34,7 +34,7 @@ PHPDBG_LIST(func); void phpdbg_list_function_byname(const char *, size_t TSRMLS_DC); void phpdbg_list_function(const zend_function* TSRMLS_DC); -void phpdbg_list_file(const char*, uint, uint, uint TSRMLS_DC); +void phpdbg_list_file(const char*, uint, int, uint TSRMLS_DC); extern const phpdbg_command_t phpdbg_list_commands[]; From f0e67720d4585f18130767b39501bd39de71acae Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 17 Oct 2014 19:39:09 +0200 Subject: [PATCH 070/125] Remove accidentally added null-byte in attributes --- phpdbg_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 991a6c23634..5f94d216482 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1069,7 +1069,7 @@ static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char * int i; int tolen = to ? strlen(to) : 5; char *tmp = *buf = emalloc(msglen * tolen); - for (i = 0; i++ < msglen; msg++) { + for (i = 0; ++i < msglen; msg++) { if (*msg == '&') { memcpy(tmp, ZEND_STRL("&")); tmp += sizeof("&") - 1; From 24972fa986f316bc64141f46ff37f1a33ae03624 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 17 Oct 2014 22:20:54 +0200 Subject: [PATCH 071/125] Fixed potential segfault in backtrace of internal funcs --- phpdbg_frame.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 429061edf40..8baaf771906 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -231,7 +231,7 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ phpdbg_out(" at %s:%ld\n", Z_STRVAL_PP(file), Z_LVAL_PP(line)); } else { phpdbg_out(" => "); - phpdbg_xml(" Date: Sat, 18 Oct 2014 20:42:54 +0200 Subject: [PATCH 072/125] Fix execution of immediately following commands --- phpdbg_cmd.c | 8 ++++---- phpdbg_utils.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index ad49c62b259..d42ad36495f 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -829,12 +829,12 @@ readline: #endif { char buf[PHPDBG_MAX_CMD]; - int bytes = 0, len = PHPDBG_G(input_buflen); + int bytes = PHPDBG_G(input_buflen), len = 0; if (PHPDBG_G(input_buflen)) { - memcpy(buf, PHPDBG_G(input_buffer), len); + memcpy(buf, PHPDBG_G(input_buffer), bytes); } - while ((bytes = read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len)) > 0 || (errno == EINTR && bytes < 0)) { + do { int i; if (bytes <= 0) { continue; @@ -862,7 +862,7 @@ readline: } } len += bytes; - } + } while ((bytes = read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len)) > 0 || (errno == EINTR && bytes < 0)); if (bytes <= 0) { goto disconnect; diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 5f94d216482..ca36f108747 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1103,7 +1103,7 @@ static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) { len += 4; *tmpptr++ = '&'; *tmpptr++ = '#'; - if ((unsigned int) ((*buf)[i]) > 10) { + if ((unsigned int) ((*buf)[i]) > 9) { *tmpptr++ = ((*buf)[i] / 10) + '0'; } else { --len; From 8525c40eac994a3485b7d9b7dd42c4839ea22b98 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 18 Oct 2014 21:54:44 +0200 Subject: [PATCH 073/125] Fix for 5.4/5.5 --- phpdbg.h | 2 +- phpdbg_bp.c | 12 ++++++------ phpdbg_cmd.c | 2 +- phpdbg_opcode.c | 4 ++-- phpdbg_print.c | 2 +- phpdbg_prompt.c | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/phpdbg.h b/phpdbg.h index a3835f3c064..3220243f290 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -217,7 +217,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable registered; /* registered */ HashTable seek; /* seek oplines */ phpdbg_frame_t frame; /* frame */ - uint32_t last_line; /* last executed line */ + zend_uint last_line; /* last executed line */ phpdbg_lexer_data lexer; /* lexer data */ phpdbg_param_t *parser_stack; /* param stack during lexer / parser phase */ diff --git a/phpdbg_bp.c b/phpdbg_bp.c index fa9355cb243..26e6ee29713 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -696,7 +696,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRML static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, const phpdbg_param_t *param, const char *expr, size_t expr_len, zend_ulong hash TSRMLS_DC) /* {{{ */ { phpdbg_breakcond_t new_break; - uint32_t cops = CG(compiler_options); + zend_uint cops = CG(compiler_options); zval pv; PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_COND); @@ -1075,7 +1075,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ if ((brake = phpdbg_find_breakbase_ex(num, &table, &position TSRMLS_CC))) { char *key; - uint32_t klen; + zend_uint klen; zend_ulong idx; int type = brake->type; char *name = NULL; @@ -1354,7 +1354,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *class_table; char *class_name = NULL; - uint32_t class_len = 0; + zend_uint class_len = 0; zend_ulong class_idx = 0L; phpdbg_out(SEPARATE "\n"); @@ -1433,7 +1433,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[3]; HashTable *class_table, *method_table; char *class_name = NULL, *method_name = NULL; - uint32_t class_len = 0, method_len = 0; + zend_uint class_len = 0, method_len = 0; zend_ulong class_idx = 0L, method_idx = 0L; phpdbg_out(SEPARATE "\n"); @@ -1472,7 +1472,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *function_table; char *function_name = NULL; - uint32_t function_len = 0; + zend_uint function_len = 0; zend_ulong function_idx = 0L; phpdbg_out(SEPARATE "\n"); @@ -1502,7 +1502,7 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *file_table; char *file_name = NULL; - uint32_t file_len = 0; + zend_uint file_len = 0; zend_ulong file_idx = 0L; phpdbg_out(SEPARATE "\n"); diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index d42ad36495f..a32114e916c 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -691,7 +691,7 @@ PHPDBG_API const phpdbg_command_t *phpdbg_stack_resolve(const phpdbg_command_t * default: { char *list = NULL; - uint32_t it = 0; + zend_uint it = 0; size_t pos = 0; while (it < matches) { diff --git a/phpdbg_opcode.c b/phpdbg_opcode.c index 41365216462..331718accc2 100644 --- a/phpdbg_opcode.c +++ b/phpdbg_opcode.c @@ -26,7 +26,7 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -static inline uint32_t phpdbg_decode_literal(zend_op_array *ops, zend_literal *literal TSRMLS_DC) /* {{{ */ +static inline zend_uint phpdbg_decode_literal(zend_op_array *ops, zend_literal *literal TSRMLS_DC) /* {{{ */ { int iter = 0; @@ -40,7 +40,7 @@ static inline uint32_t phpdbg_decode_literal(zend_op_array *ops, zend_literal *l return 0; } /* }}} */ -static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t type, HashTable *vars TSRMLS_DC) /* {{{ */ +static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, zend_uint type, HashTable *vars TSRMLS_DC) /* {{{ */ { char *decode = NULL; diff --git a/phpdbg_print.c b/phpdbg_print.c index 9a8edb3abaf..80eeddb39d1 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -59,7 +59,7 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) if (op_array) { zend_op *opline = &(op_array->opcodes[0]); - uint32_t opcode = 0, + zend_uint opcode = 0, end = op_array->last-1; if (method->common.scope) { diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 64f43cb2043..194c890ebe6 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -441,7 +441,7 @@ PHPDBG_COMMAND(until) /* {{{ */ PHPDBG_G(flags) |= PHPDBG_IN_UNTIL; { - uint32_t next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + zend_uint next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); zend_op *opline = &EG(active_op_array)->opcodes[self]; for (next = self; next < EG(active_op_array)->last; next++) { @@ -464,7 +464,7 @@ PHPDBG_COMMAND(finish) /* {{{ */ PHPDBG_G(flags) |= PHPDBG_IN_FINISH; { - uint32_t next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + zend_uint next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); for (next = self; next < EG(active_op_array)->last; next++) { switch (EG(active_op_array)->opcodes[next].opcode) { @@ -492,7 +492,7 @@ PHPDBG_COMMAND(leave) /* {{{ */ PHPDBG_G(flags) |= PHPDBG_IN_LEAVE; { - uint32_t next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + zend_uint next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); for (next = self; next < EG(active_op_array)->last; next++) { switch (EG(active_op_array)->opcodes[next].opcode) { @@ -530,7 +530,7 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ /* get filename and linenumber before unsetting exception */ const char *filename = zend_get_executed_filename(TSRMLS_C); - uint32_t lineno = zend_get_executed_lineno(TSRMLS_C); + zend_uint lineno = zend_get_executed_lineno(TSRMLS_C); /* copy exception */ exception = *EG(exception); From f67bd30131a4bb2f2d6a6b09bfdfc80d67a06d02 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 18 Oct 2014 22:43:56 +0200 Subject: [PATCH 074/125] C89 compat --- phpdbg_info.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpdbg_info.c b/phpdbg_info.c index 0f1d191aa35..fee8368ab6f 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -338,8 +338,10 @@ PHPDBG_INFO(classes) /* {{{ */ phpdbg_print_class_name(ce TSRMLS_CC); if ((*ce)->parent) { + zend_class_entry *pce; + phpdbg_xml(""); - zend_class_entry *pce = (*ce)->parent; + pce = (*ce)->parent; do { phpdbg_out("|-------- "); phpdbg_print_class_name(&pce TSRMLS_CC); From 3ca381ee8b928122d2b266a93978fe3d90c6deb3 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 18 Oct 2014 22:45:17 +0200 Subject: [PATCH 075/125] fix dll export --- phpdbg_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index ca36f108747..44771805940 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1042,7 +1042,7 @@ static int phpdbg_xml_vsnprintf(char *buf, size_t len, const char *format, zend_ return (cc); } -PHPAPI int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { +PHPDBG_API int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { va_list ap2; int cc; From 0cfd77185b0702a5cf0995153238d609c4acd639 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 18 Oct 2014 22:59:49 +0200 Subject: [PATCH 076/125] enable php_stdiop_write for windows yet it's unclear whether it'll be usable, but otherwise it breaks compilation as some places depend on it --- phpdbg.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/phpdbg.h b/phpdbg.h index 3220243f290..fc9944111eb 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -247,9 +247,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) FILE *ptr; int fd; } io[PHPDBG_IO_FDS]; /* io */ -#ifndef _WIN32 size_t (*php_stdiop_write)(php_stream *, const char *, size_t TSRMLS_DC); -#endif int in_script_xml; /* in output mode */ struct { zend_bool active; From dd551706a9d9acee3c36012384d1117d9237fe47 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 00:12:23 +0200 Subject: [PATCH 077/125] add basic stuff to generalize IO --- config.m4 | 2 +- config.w32 | 2 +- phpdbg_io.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_io.h | 57 +++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 phpdbg_io.c create mode 100644 phpdbg_io.h diff --git a/config.m4 b/config.m4 index aea509eb00a..3bedc3cad99 100644 --- a/config.m4 +++ b/config.m4 @@ -33,7 +33,7 @@ if test "$BUILD_PHPDBG" == "" && test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_sigsafe.c phpdbg_wait.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c" if test "$PHP_READLINE" != "no" -o "$PHP_LIBEDIT" != "no"; then PHPDBG_EXTRA_LIBS="$PHP_READLINE_LIBS" diff --git a/config.w32 b/config.w32 index 86f8949cd0d..df75510be42 100644 --- a/config.w32 +++ b/config.w32 @@ -4,7 +4,7 @@ ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c ' + 'phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c ' + 'phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c '+ - 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c'; + 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; diff --git a/phpdbg_io.c b/phpdbg_io.c new file mode 100644 index 00000000000..e561174f8c5 --- /dev/null +++ b/phpdbg_io.c @@ -0,0 +1,85 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Anatol Belski | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "phpdbg_io.h" + +PHPDBG_API int +phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) +{/*{{{*/ + int got_now, i = len, j; + char *p = ptr; +#ifndef PHP_WIN32 + struct pollfd pfd; + + pfd.fd = sock; + pfd.events = POLLIN; + + j = poll(&pfd, 1, tmo); + + if (j == 0) { +#else + struct fd_set readfds; + struct timeval ttmo; + + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + + ttmo.tv_sec = 0; + ttmo.tv_usec = tmo*1000; + + j = select(0, &readfds, NULL, NULL, &ttmo); + + if (j <= 0) { +#endif + return -1; + } + + while(i > 0) { + got_now = recv(sock, p, i, 0); + if (got_now == -1) { + return -1; + } + i -= got_now; + p += got_now; + } + + return len; +}/*}}}*/ + +PHPDBG_API int +phpdbg_send_bytes(int sock, char *ptr, int len) +{/*{{{*/ + int sent, i = len; + char *p = ptr; + + while(i > 0) { + sent = send(sock, p, i, 0); + if (sent == -1) { + return -1; + } + i -= sent; + p += sent; + } + + return len; +}/*}}}*/ + diff --git a/phpdbg_io.h b/phpdbg_io.h new file mode 100644 index 00000000000..e2935167779 --- /dev/null +++ b/phpdbg_io.h @@ -0,0 +1,57 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Anatol Belski | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_IO_H +#define PHPDBG_IO_H + +#include "phpdbg.h" + +#ifdef PHP_WIN32 +#undef UNICODE +#include "win32/inet.h" +#include +#include +#include +#include "win32/sockets.h" + +#else + +#if HAVE_SYS_TYPES_H +#include +#endif +#include +#include +#if HAVE_ARPA_INET_H +#include +#endif +#include + +#include + +#include +#endif + + +PHPDBG_API int +phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo); + +PHPDBG_API int +phpdbg_send_bytes(int sock, char *ptr, int len); + +#endif /* PHPDBG_IO_H */ + From 47388e636285d9500e7fd446ecd70bdd426e424f Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 01:30:00 +0200 Subject: [PATCH 078/125] move these to use the mixed read/write routines --- phpdbg_cmd.c | 2 +- phpdbg_utils.c | 39 ++++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index a32114e916c..42a1bef2031 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -862,7 +862,7 @@ readline: } } len += bytes; - } while ((bytes = read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len)) > 0 || (errno == EINTR && bytes < 0)); + } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, 10000)) > 0 || (errno == EINTR && bytes < 0)); if (bytes <= 0) { goto disconnect; diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 44771805940..2fdb00b0686 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -26,6 +26,7 @@ #include "spprintf.h" #include "phpdbg.h" #include "phpdbg_opcode.h" +#include "phpdbg_io.h" #include "phpdbg_utils.h" #include "ext/standard/html.h" @@ -1128,7 +1129,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m const char *severity; if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML) && PHPDBG_G(in_script_xml) && PHPDBG_G(in_script_xml) != type) { - write(fd, ZEND_STRL("")); + phpdbg_mixed_write(fd, ZEND_STRL("")); PHPDBG_G(in_script_xml) = 0; } @@ -1139,9 +1140,9 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m severity = "error"; if (!PHPDBG_G(last_was_newline)) { if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL("\n")); } else { - write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL("\n")); } PHPDBG_G(last_was_newline) = 1; } @@ -1156,9 +1157,9 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m severity = "notice"; if (!PHPDBG_G(last_was_newline)) { if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL("\n")); } else { - write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL("\n")); } PHPDBG_G(last_was_newline) = 1; } @@ -1200,16 +1201,16 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m if (PHPDBG_G(in_script_xml) != type) { char *stream_buf; int stream_buflen = spprintf(&stream_buf, 0, "", type == P_STDERR ? "stderr" : "stdout"); - write(fd, stream_buf, stream_buflen); + phpdbg_mixed_write(fd, stream_buf, stream_buflen); efree(stream_buf); PHPDBG_G(in_script_xml) = type; } buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); phpdbg_encode_ctrl_chars(&buf, &buflen); - write(fd, buf, buflen); + phpdbg_mixed_write(fd, buf, buflen); efree(buf); } else { - write(fd, msg, msglen); + phpdbg_mixed_write(fd, msg, msglen); } return msglen; } @@ -1249,10 +1250,10 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m } phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen); - write(fd, xmlout, xmloutlen); + phpdbg_mixed_write(fd, xmlout, xmloutlen); efree(xmlout); } else if (msgout) { - write(fd, msgout, msgoutlen); + phpdbg_mixed_write(fd, msgout, msgoutlen); } if (PHPDBG_G(req_id) && (PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { @@ -1380,11 +1381,11 @@ PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) { phpdbg_encode_ctrl_chars(&buffer, &buflen); if (PHPDBG_G(in_script_xml)) { - write(fd, ZEND_STRL("")); + phpdbg_mixed_write(fd, ZEND_STRL("")); PHPDBG_G(in_script_xml) = 0; } - len = write(fd, buffer, buflen); + len = phpdbg_mixed_write(fd, buffer, buflen); efree(buffer); } @@ -1401,7 +1402,7 @@ PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...) { buflen = vspprintf(&buffer, 0, fmt, args); va_end(args); - len = write(fd, buffer, buflen); + len = phpdbg_mixed_write(fd, buffer, buflen); efree(buffer); return len; @@ -1425,15 +1426,15 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { phpdbg_encode_ctrl_chars(&msg, &msglen); if (PHPDBG_G(in_script_xml)) { - write(fd, ZEND_STRL("")); + phpdbg_mixed_write(fd, ZEND_STRL("")); PHPDBG_G(in_script_xml) = 0; } - write(fd, ZEND_STRL("")); - len = write(fd, msg, msglen); - write(fd, ZEND_STRL("")); + phpdbg_mixed_write(fd, ZEND_STRL("")); + len = phpdbg_mixed_write(fd, msg, msglen); + phpdbg_mixed_write(fd, ZEND_STRL("")); } else { - len = write(fd, buffer, buflen); + len = phpdbg_mixed_write(fd, buffer, buflen); } return len; @@ -1458,7 +1459,7 @@ PHPDBG_API int phpdbg_rlog(int fd, const char *fmt, ...) { /* {{{ */ rc = vspprintf(&outbuf, 0, format, args); if (outbuf) { - rc = write(fd, outbuf, rc); + rc = phpdbg_mixed_write(fd, outbuf, rc); efree(outbuf); } From 52d2ead59d8770da166f8a6cfe0e2f4eab1bbaaa Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 01:31:00 +0200 Subject: [PATCH 079/125] override stdin and stdout to be remote, stderr is untouched however is this ok? some functions want to write a log there ... --- phpdbg.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index a8fb37ab835..e7a8f47a151 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -849,7 +849,7 @@ static int phpdbg_remote_init(const char* address, unsigned short port, int serv struct sockaddr_in address; socklen_t size = sizeof(address); char buffer[20] = {0}; - + /* XXX error checks */ memset(&address, 0, size); *socket = accept(server, (struct sockaddr *) &address, &size); inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); @@ -857,6 +857,7 @@ static int phpdbg_remote_init(const char* address, unsigned short port, int serv phpdbg_rlog(fileno(stderr), "connection established from %s", buffer); } +#ifndef _WIN32 dup2(*socket, fileno(stdout)); dup2(*socket, fileno(stdin)); @@ -865,7 +866,7 @@ static int phpdbg_remote_init(const char* address, unsigned short port, int serv *stream = fdopen(*socket, "r+"); phpdbg_set_async_io(*socket); - +#endif return SUCCESS; } @@ -1381,17 +1382,36 @@ phpdbg_main: PHPDBG_G(flags) = flags; /* setup io here */ - if (stream) { + if (remote) { PHPDBG_G(flags) |= PHPDBG_IS_REMOTE; #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); #endif } +#ifndef _WIN32 PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin; PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin); PHPDBG_G(io)[PHPDBG_STDOUT].ptr = stdout; PHPDBG_G(io)[PHPDBG_STDOUT].fd = fileno(stdout); +#else + /* XXX this is a complete mess here with FILE/fd/SOCKET, + we should let only one to survive probably. Need + a clean separation whether it's a remote or local + prompt. And what is supposed to go as user interaction, + error log, etc. */ + if (remote) { + PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin; + PHPDBG_G(io)[PHPDBG_STDIN].fd = socket; + PHPDBG_G(io)[PHPDBG_STDOUT].ptr = stdout; + PHPDBG_G(io)[PHPDBG_STDOUT].fd = socket; + } else { + PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin; + PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin); + PHPDBG_G(io)[PHPDBG_STDOUT].ptr = stdout; + PHPDBG_G(io)[PHPDBG_STDOUT].fd = fileno(stdout); + } +#endif PHPDBG_G(io)[PHPDBG_STDERR].ptr = stderr; PHPDBG_G(io)[PHPDBG_STDERR].fd = fileno(stderr); From 1137d9cb2bb269d73708b76349a07c36bcac13dc Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 01:32:46 +0200 Subject: [PATCH 080/125] several fixes to the new io stuff --- phpdbg_io.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++- phpdbg_io.h | 32 ++++++------------------------ 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/phpdbg_io.c b/phpdbg_io.c index e561174f8c5..f358fbfcd8e 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -22,6 +22,35 @@ #include "phpdbg_io.h" +#ifdef PHP_WIN32 +#undef UNICODE +#include "win32/inet.h" +#include +#include +#include +#include "win32/sockets.h" + +#else + +#if HAVE_SYS_TYPES_H +#include +#endif +#include +#include +#if HAVE_ARPA_INET_H +#include +#endif +#include + +#include + +#include +#endif + + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + + PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) {/*{{{*/ @@ -54,6 +83,11 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) } while(i > 0) { +#ifdef PHP_WIN32 + int can_read = recv(sock, p, i, MSG_PEEK); + + i = can_read; +#endif got_now = recv(sock, p, i, 0); if (got_now == -1) { return -1; @@ -62,7 +96,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) p += got_now; } - return len; + return p - ptr; }/*}}}*/ PHPDBG_API int @@ -83,3 +117,24 @@ phpdbg_send_bytes(int sock, char *ptr, int len) return len; }/*}}}*/ + +PHPDBG_API int +phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_CC) +{/*{{{*/ + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { + return phpdbg_consume_bytes(sock, ptr, len, tmo); + } + + return read(sock, ptr, len); +}/*}}}*/ + + +PHPDBG_API int +phpdbg_mixed_write(int sock, char *ptr, int len TSRMLS_CC) +{/*{{{*/ + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { + return phpdbg_send_bytes(sock, ptr, len); + } + + return write(sock, ptr, len); +}/*}}}*/ diff --git a/phpdbg_io.h b/phpdbg_io.h index e2935167779..3c4684698ae 100644 --- a/phpdbg_io.h +++ b/phpdbg_io.h @@ -21,37 +21,17 @@ #include "phpdbg.h" -#ifdef PHP_WIN32 -#undef UNICODE -#include "win32/inet.h" -#include -#include -#include -#include "win32/sockets.h" - -#else - -#if HAVE_SYS_TYPES_H -#include -#endif -#include -#include -#if HAVE_ARPA_INET_H -#include -#endif -#include - -#include - -#include -#endif - - PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo); PHPDBG_API int phpdbg_send_bytes(int sock, char *ptr, int len); +PHPDBG_API int +phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_CC); + +PHPDBG_API int +phpdbg_mixed_write(int sock, char *ptr, int len TSRMLS_CC); + #endif /* PHPDBG_IO_H */ From d5fb8e583097123e8a3cbacbe0191bac75ea5df2 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 02:14:31 +0200 Subject: [PATCH 081/125] increase stack to avoid overflow crash on SIGINT but should actually check, maybe something is causing a recursive stack exhaustion --- config.w32 | 1 + 1 file changed, 1 insertion(+) diff --git a/config.w32 b/config.w32 index df75510be42..6fb46652e1d 100644 --- a/config.w32 +++ b/config.w32 @@ -12,6 +12,7 @@ if (PHP_PHPDBG == "yes") { SAPI('phpdbg', PHPDBG_SOURCES, PHPDBG_EXE); ADD_FLAG("LIBS_PHPDBG", "ws2_32.lib user32.lib"); ADD_FLAG("CFLAGS_PHPDBG", "/D YY_NO_UNISTD_H"); + ADD_FLAG("LDFLAGS_PHPDBG", "/stack:8388608"); } if (PHP_PHPDBGS == "yes") { From e853fec3fd63b3c511faba3a841911715cd340c8 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 10:39:44 +0200 Subject: [PATCH 082/125] fixed EOL transferred to the client side, fixed strftime fmt string the windows telnet gets broken output when receiving no '\r' --- phpdbg_cmd.c | 20 ++++++++++---------- phpdbg_help.c | 2 +- phpdbg_utils.c | 28 ++++++++++++++++------------ 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 42a1bef2031..77a0cacc198 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -417,43 +417,43 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) if (param && param->type) { switch (param->type) { case STR_PARAM: - fprintf(stderr, "%s STR_PARAM(%s=%lu)\n", msg, param->str, param->len); + fprintf(stderr, "%s STR_PARAM(%s=%lu)" PHP_EOL, msg, param->str, param->len); break; case ADDR_PARAM: - fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); + fprintf(stderr, "%s ADDR_PARAM(%lu)" PHP_EOL, msg, param->addr); break; case NUMERIC_FILE_PARAM: - fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#%lu)\n", msg, param->file.name, param->file.line); + fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#%lu)" PHP_EOL, msg, param->file.name, param->file.line); break; case FILE_PARAM: - fprintf(stderr, "%s FILE_PARAM(%s:%lu)\n", msg, param->file.name, param->file.line); + fprintf(stderr, "%s FILE_PARAM(%s:%lu)" PHP_EOL, msg, param->file.name, param->file.line); break; case METHOD_PARAM: - fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + fprintf(stderr, "%s METHOD_PARAM(%s::%s)" PHP_EOL, msg, param->method.class, param->method.name); break; case NUMERIC_METHOD_PARAM: - fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)" PHP_EOL, msg, param->method.class, param->method.name); break; case NUMERIC_FUNCTION_PARAM: - fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%ld)\n", msg, param->str, param->num); + fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%ld)" PHP_EOL, msg, param->str, param->num); break; case NUMERIC_PARAM: - fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); + fprintf(stderr, "%s NUMERIC_PARAM(%ld)" PHP_EOL, msg, param->num); break; case COND_PARAM: - fprintf(stderr, "%s COND_PARAM(%s=%lu)\n", msg, param->str, param->len); + fprintf(stderr, "%s COND_PARAM(%s=%lu)" PHP_EOL, msg, param->str, param->len); break; case OP_PARAM: - fprintf(stderr, "%s OP_PARAM(%s=%lu)\n", msg, param->str, param->len); + fprintf(stderr, "%s OP_PARAM(%s=%lu)" PHP_EOL, msg, param->str, param->len); break; default: { diff --git a/phpdbg_help.c b/phpdbg_help.c index 3fed04e7455..2e8f527b531 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -319,7 +319,7 @@ PHPDBG_HELP(aliases) /* {{{ */ * Also note the convention that help text not directly referenceable as a help param * has a key ending in ! */ -#define CR "\n" +#define CR PHP_EOL phpdbg_help_text_t phpdbg_help_text[] = { /******************************** General Help Topics ********************************/ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 2fdb00b0686..a3c19659285 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1140,16 +1140,16 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m severity = "error"; if (!PHPDBG_G(last_was_newline)) { if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_mixed_write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL("" PHP_EOL "")); } else { - phpdbg_mixed_write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL(PHP_EOL)); } PHPDBG_G(last_was_newline) = 1; } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); + msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m" PHP_EOL, PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); } else { - msgoutlen = spprintf(&msgout, 0, "[%.*s]\n", msglen, msg); + msgoutlen = spprintf(&msgout, 0, "[%.*s]" PHP_EOL, msglen, msg); } break; @@ -1157,26 +1157,26 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m severity = "notice"; if (!PHPDBG_G(last_was_newline)) { if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_mixed_write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL("" PHP_EOL "")); } else { - phpdbg_mixed_write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL(PHP_EOL)); } PHPDBG_G(last_was_newline) = 1; } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); + msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m" PHP_EOL, PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); } else { - msgoutlen = spprintf(&msgout, 0, "[%.*s]\n", msglen, msg); + msgoutlen = spprintf(&msgout, 0, "[%.*s]" PHP_EOL, msglen, msg); } break; case P_WRITELN: severity = "normal"; if (msg) { - msgoutlen = spprintf(&msgout, 0, "%.*s\n", msglen, msg); + msgoutlen = spprintf(&msgout, 0, "%.*s" PHP_EOL, msglen, msg); } else { msgoutlen = 1; - msgout = estrdup("\n"); + msgout = estrdup(PHP_EOL); } PHPDBG_G(last_was_newline) = 1; break; @@ -1222,7 +1222,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m if (msg) { struct timeval tp; if (gettimeofday(&tp, NULL) == SUCCESS) { - msgoutlen = spprintf(&msgout, 0, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); + msgoutlen = spprintf(&msgout, 0, "[%ld %.8F]: %.*s" PHP_EOL, tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); } else { msgoutlen = FAILURE; } @@ -1453,9 +1453,13 @@ PHPDBG_API int phpdbg_rlog(int fd, const char *fmt, ...) { /* {{{ */ char *format = NULL, *buffer = NULL, *outbuf = NULL; const time_t tt = tp.tv_sec; +#ifdef PHP_WIN32 + strftime(friendly, 100, "%a %b %d %H.%%04d %Y", localtime(&tt)); +#else strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt)); +#endif spprintf(&buffer, 0, friendly, tp.tv_usec/1000); - spprintf(&format, 0, "[%s]: %s\n", buffer, fmt); + spprintf(&format, 0, "[%s]: %s" PHP_EOL, buffer, fmt); rc = vspprintf(&outbuf, 0, format, args); if (outbuf) { From 52686b322682e470c9664cfb01d69406b44b7b20 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 11:03:17 +0200 Subject: [PATCH 083/125] use MSG_PEEK flag for recv() everywhere --- phpdbg_io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpdbg_io.c b/phpdbg_io.c index f358fbfcd8e..6de1397ec9b 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -83,11 +83,11 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) } while(i > 0) { -#ifdef PHP_WIN32 + /* There's something to read. Read what's available and proceed + disregarding whether len could be exhausted or not.*/ int can_read = recv(sock, p, i, MSG_PEEK); - i = can_read; -#endif + got_now = recv(sock, p, i, 0); if (got_now == -1) { return -1; From 2be895e4fe97f42ae75ea266517e21576892d3c5 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 11:10:13 +0200 Subject: [PATCH 084/125] more EOL fixes --- phpdbg.c | 10 +++++----- phpdbg_bp.c | 36 ++++++++++++++++++------------------ phpdbg_frame.c | 6 +++--- phpdbg_help.c | 6 +++--- phpdbg_prompt.c | 22 +++++++++++----------- phpdbg_watch.c | 4 ++-- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index e7a8f47a151..13666227590 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -742,10 +742,10 @@ static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */ } phpdbg_write("cleaninfo", "classes=\"%d\" functions=\"%d\" constants=\"%d\" includes=\"%d\"", - "Classes %d\n" - "Functions %d\n" - "Constants %d\n" - "Includes %d\n", + "Classes %d" PHP_EOL + "Functions %d" PHP_EOL + "Constants %d" PHP_EOL + "Includes %d" PHP_EOL, zend_hash_num_elements(EG(class_table)), zend_hash_num_elements(EG(function_table)), zend_hash_num_elements(EG(zend_constants)), @@ -1212,7 +1212,7 @@ phpdbg_main: sapi_startup(phpdbg); phpdbg->startup(phpdbg); printf( - "phpdbg %s (built: %s %s)\nPHP %s, Copyright (c) 1997-2014 The PHP Group\n%s", + "phpdbg %s (built: %s %s)" PHP_EOL "PHP %s, Copyright (c) 1997-2014 The PHP Group" PHP_EOL "%s", PHPDBG_VERSION, __DATE__, __TIME__, diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 26e6ee29713..e7f313d6b87 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -1339,8 +1339,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breaksymbol_t *brake; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("Function Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("Function Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position)) { @@ -1357,8 +1357,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ zend_uint class_len = 0; zend_ulong class_idx = 0L; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("Method Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("Method Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**) &class_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) { @@ -1383,8 +1383,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *points; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("File Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("File Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**) &points, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) { @@ -1405,8 +1405,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakline_t *brake; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("Opline Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("Opline Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) { @@ -1436,8 +1436,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ zend_uint class_len = 0, method_len = 0; zend_ulong class_idx = 0L, method_idx = 0L; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("Method opline Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("Method opline Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) { @@ -1475,8 +1475,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ zend_uint function_len = 0; zend_ulong function_idx = 0L; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("Function opline Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("Function opline Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) { @@ -1505,8 +1505,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ zend_uint file_len = 0; zend_ulong file_idx = 0L; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("File opline Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("File opline Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) { @@ -1531,8 +1531,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakcond_t *brake; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("Conditional Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("Conditional Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { @@ -1607,8 +1607,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakop_t *brake; - phpdbg_out(SEPARATE "\n"); - phpdbg_out("Opcode Breakpoints:\n"); + phpdbg_out(SEPARATE PHP_EOL); + phpdbg_out("Opcode Breakpoints:" PHP_EOL); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) { diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 8baaf771906..f4ab92392f1 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -228,16 +228,16 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ phpdbg_out("frame #%d: ", i++); phpdbg_xml(" "); phpdbg_xml(""); zval_dtor(&zbacktrace); diff --git a/phpdbg_help.c b/phpdbg_help.c index 2e8f527b531..f2c6486ae5e 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -136,7 +136,7 @@ void pretty_print(char *text TSRMLS_DC) phpdbg_error("help", "overrun=\"%lu\"", "Output overrun of %lu bytes", ((q - new) - size)); } - phpdbg_out("%s\n", new); + phpdbg_out("%s" PHP_EOL, new); efree(new); } /* }}} */ @@ -144,7 +144,7 @@ void pretty_print(char *text TSRMLS_DC) void summary_print(phpdbg_command_t const * const cmd TSRMLS_DC) { char *summary; - spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**\n", cmd->name, cmd->alias, cmd->tip); + spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**" PHP_EOL, cmd->name, cmd->alias, cmd->tip); pretty_print(summary TSRMLS_CC); efree(summary); } @@ -285,7 +285,7 @@ PHPDBG_HELP(aliases) /* {{{ */ /* Print out aliases for help as this one comes last, with the added text on how aliases are used */ get_command("h", 1, &c, phpdbg_prompt_commands TSRMLS_CC); - phpdbg_writeln("aliasinfo", "alias=\"%c\" name=\"%s\" tip=\"%s\"", " %c %-20s %s\n", c->alias, c->name, c->tip); + phpdbg_writeln("aliasinfo", "alias=\"%c\" name=\"%s\" tip=\"%s\"", " %c %-20s %s" PHP_EOL, c->alias, c->name, c->tip); phpdbg_xml(""); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 194c890ebe6..cc2062b2b7e 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -190,7 +190,7 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * if (fretval) { zend_print_zval_r(fretval, 0 TSRMLS_CC); - phpdbg_out("\n"); + phpdbg_out(PHP_EOL); } zval_dtor(&fname); @@ -551,7 +551,7 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ zend_call_function(&fci, NULL TSRMLS_CC); if (trace) { - phpdbg_writeln("exception", "name=\"%s\" trace=\"%.*s\"", "Uncaught %s!\n%.*s", Z_OBJCE(exception)->name, Z_STRLEN_P(trace), Z_STRVAL_P(trace)); + phpdbg_writeln("exception", "name=\"%s\" trace=\"%.*s\"", "Uncaught %s!" PHP_EOL "%.*s", Z_OBJCE(exception)->name, Z_STRLEN_P(trace), Z_STRVAL_P(trace)); zval_ptr_dtor(&trace); } else { @@ -674,7 +674,7 @@ int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keyl phpdbg_xml(""); zend_print_zval_r(*zv, 0 TSRMLS_CC); phpdbg_xml(""); - phpdbg_out("\n"); + phpdbg_out(PHP_EOL); efree(name); efree(keyname); @@ -707,7 +707,7 @@ PHPDBG_COMMAND(ev) /* {{{ */ phpdbg_xml(""); zend_print_zval_r(&retval, 0 TSRMLS_CC); phpdbg_xml(""); - phpdbg_out("\n"); + phpdbg_out(PHP_EOL); zval_dtor(&retval); } } zend_end_try(); @@ -741,7 +741,7 @@ PHPDBG_COMMAND(back) /* {{{ */ PHPDBG_COMMAND(print) /* {{{ */ { - phpdbg_out("Execution Context Information\n\n"); + phpdbg_out("Execution Context Information" PHP_EOL PHP_EOL); phpdbg_xml(""); #ifdef HAVE_LIBREADLINE phpdbg_writeln("print", "readline=\"yes\"", "Readline yes"); @@ -855,12 +855,12 @@ PHPDBG_COMMAND(sh) /* {{{ */ } /* }}} */ static int add_module_info(zend_module_entry *module TSRMLS_DC) { - phpdbg_write("module", "name=\"%s\"", "%s\n", module->name); + phpdbg_write("module", "name=\"%s\"", "%s" PHP_EOL, module->name); return 0; } static int add_zendext_info(zend_extension *ext TSRMLS_DC) { - phpdbg_write("extension", "name=\"%s\"", "%s\n", ext->name); + phpdbg_write("extension", "name=\"%s\"", "%s" PHP_EOL, ext->name); return 0; } @@ -1012,7 +1012,7 @@ PHPDBG_COMMAND(dl) /* {{{ */ if (!param || param->type == EMPTY_PARAM) { phpdbg_notice("dl", "extensiontype=\"Zend extension\"", "Zend extensions"); zend_llist_apply(&zend_extensions, (llist_apply_func_t) add_zendext_info TSRMLS_CC); - phpdbg_out("\n"); + phpdbg_out(PHP_EOL); phpdbg_notice("dl", "extensiontype=\"module\"", "Modules"); zend_hash_apply(&module_registry, (apply_func_t) add_module_info TSRMLS_CC); } else switch (param->type) { @@ -1109,7 +1109,7 @@ PHPDBG_COMMAND(clean) /* {{{ */ return SUCCESS; } - phpdbg_out("Cleaning Execution Environment\n"); + phpdbg_out("Cleaning Execution Environment" PHP_EOL); phpdbg_xml(""); phpdbg_writeln("clean", "classes=\"%d\"", "Classes %d", zend_hash_num_elements(EG(class_table))); @@ -1126,7 +1126,7 @@ PHPDBG_COMMAND(clean) /* {{{ */ PHPDBG_COMMAND(clear) /* {{{ */ { - phpdbg_out("Clearing Breakpoints\n"); + phpdbg_out("Clearing Breakpoints" PHP_EOL); phpdbg_xml(""); phpdbg_writeln("clear", "files=\"%d\"", "File %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE])); @@ -1479,7 +1479,7 @@ zend_vm_enter: if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED; - phpdbg_out("\n"); + phpdbg_out(PHP_EOL); phpdbg_notice("signal", "type=\"SIGINT\"", "Program received signal SIGINT"); DO_INTERACTIVE(1); } diff --git a/phpdbg_watch.c b/phpdbg_watch.c index de6cddf5b3c..3f07b70dcd5 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -567,7 +567,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_xml(""); zend_print_flat_zval_r((zval *) oldPtr TSRMLS_CC); phpdbg_xml(""); - phpdbg_out("\n"); + phpdbg_out(PHP_EOL); } } if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && (removed || show_ref)) { @@ -593,7 +593,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_xml(""); zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); phpdbg_xml(""); - phpdbg_out("\n"); + phpdbg_out(PHP_EOL); } if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && show_ref) { phpdbg_writeln("watchrefcount", "type=\"new\" refcount=\"%d\" isref=\"%d\"", "New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); From 0929b7a4e432b8764c8bc7c7dad1e5eaeb921fce Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 11:16:01 +0200 Subject: [PATCH 085/125] increase default recv timeout to 30 seconds --- phpdbg_cmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 77a0cacc198..f4c2e172f9e 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -862,7 +862,8 @@ readline: } } len += bytes; - } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, 10000)) > 0 || (errno == EINTR && bytes < 0)); + /* XXX export the timeout through INI??*/ + } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, 30000)) > 0 || (errno == EINTR && bytes < 0)); if (bytes <= 0) { goto disconnect; From 75bc2076535c933ae9d41f5d3448772e35251b9f Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 11:16:56 +0200 Subject: [PATCH 086/125] add comment --- phpdbg_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_io.c b/phpdbg_io.c index 6de1397ec9b..ec0ac681258 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -104,7 +104,7 @@ phpdbg_send_bytes(int sock, char *ptr, int len) {/*{{{*/ int sent, i = len; char *p = ptr; - +/* XXX poll/select needed here? */ while(i > 0) { sent = send(sock, p, i, 0); if (sent == -1) { From 0acafba89d93ec58de44515e1a5041494d29ae89 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 13:40:45 +0200 Subject: [PATCH 087/125] improve server sock creation and support ipv6 --- phpdbg.c | 50 ++----------------- phpdbg_io.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_io.h | 9 ++++ 3 files changed, 148 insertions(+), 46 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 13666227590..2893aa300e4 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -781,52 +781,10 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */ } } /* }}} */ -int phpdbg_open_socket(const char *interface, short port) /* {{{ */ -{ - int reuse = 1; - struct sockaddr_in address; - int fd = socket(AF_INET, SOCK_STREAM, 0); - - if (fd == -1) { - return -1; - } - - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) == -1) { - close(fd); - return -2; - } - - - memset(&address, 0, sizeof(address)); - - address.sin_port = htons(port); - address.sin_family = AF_INET; - - if ((*interface == '*')) { - address.sin_addr.s_addr = htonl(INADDR_ANY); - } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) { - close(fd); - return -3; - } - - if (bind(fd, (struct sockaddr *)&address, sizeof(address)) == -1) { - close(fd); - return -4; - } - - listen(fd, 5); - - return fd; -} /* }}} */ static void phpdbg_remote_close(int socket, FILE *stream) { if (socket >= 0) { -#ifdef _WIN32 - closesocket(socket); -#else - shutdown(socket, SHUT_RDWR); - close(socket); -#endif + phpdbg_close_socket(socket); } if (stream) { @@ -846,13 +804,13 @@ static int phpdbg_remote_init(const char* address, unsigned short port, int serv phpdbg_rlog(fileno(stderr), "accepting connections on %s:%u", address, port); { - struct sockaddr_in address; + struct sockaddr_storage address; socklen_t size = sizeof(address); char buffer[20] = {0}; /* XXX error checks */ memset(&address, 0, size); *socket = accept(server, (struct sockaddr *) &address, &size); - inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); + inet_ntop(AF_INET, &(((struct sockaddr_in *)&address)->sin_addr), buffer, sizeof(buffer)); phpdbg_rlog(fileno(stderr), "connection established from %s", buffer); } @@ -1298,7 +1256,7 @@ phpdbg_main: /* setup remote server if necessary */ if (!cleaning && listen > 0) { server = phpdbg_open_socket(address, listen); - if (phpdbg_remote_init(address, listen, server, &socket, &stream) == FAILURE) { + if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream) == FAILURE) { exit(0); } diff --git a/phpdbg_io.c b/phpdbg_io.c index ec0ac681258..2dc6884f4e4 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -58,6 +58,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) char *p = ptr; #ifndef PHP_WIN32 struct pollfd pfd; + TSRMLS_FETCH(); pfd.fd = sock; pfd.events = POLLIN; @@ -68,6 +69,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) #else struct fd_set readfds; struct timeval ttmo; + TSRMLS_FETCH(); FD_ZERO(&readfds); FD_SET(sock, &readfds); @@ -90,6 +92,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) got_now = recv(sock, p, i, 0); if (got_now == -1) { + write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Read operation timed out!\n")); return -1; } i -= got_now; @@ -138,3 +141,135 @@ phpdbg_mixed_write(int sock, char *ptr, int len TSRMLS_CC) return write(sock, ptr, len); }/*}}}*/ + + +PHPDBG_API int +phpdbg_open_socket(const char *interface, short port) /* {{{ */ +{ + struct addrinfo res; + int fd = phpdbg_create_listenable_socket(interface, port, &res); + + if (fd == -1) { + return -1; + } + + if (bind(fd, res.ai_addr, res.ai_addrlen) == -1) { + phpdbg_close_socket(fd); + return -4; + } + + listen(fd, 5); + + return fd; +} /* }}} */ + + +PHPDBG_API int +phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *addr_res) +{/*{{{*/ + int sock = -1, rc; + int reuse = 1; + struct in6_addr serveraddr; + struct addrinfo hints, *res = NULL; + char port_buf[8]; + int8_t any_addr = *addr == '*'; + TSRMLS_FETCH(); + + do { + memset(&hints, 0, sizeof hints); + if (any_addr) { + hints.ai_flags = AI_PASSIVE; + } else { + hints.ai_flags = AI_NUMERICSERV; + } + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + rc = inet_pton(AF_INET, addr, &serveraddr); + if (1 == rc) { + hints.ai_family = AF_INET; + if (!any_addr) { + hints.ai_flags |= AI_NUMERICHOST; + } + } else { + rc = inet_pton(AF_INET6, addr, &serveraddr); + if (1 == rc) { + hints.ai_family = AF_INET6; + if (!any_addr) { + hints.ai_flags |= AI_NUMERICHOST; + } + } else { + /* XXX get host by name ??? */ + } + } + + snprintf(port_buf, 7, "%d", port); + if (!any_addr) { + rc = getaddrinfo(addr, port_buf, &hints, &res); + } else { + rc = getaddrinfo(NULL, port_buf, &hints, &res); + } + if (0 != rc) { +#ifndef PHP_WIN32 + if (rc == EAI_SYSTEM) { + char buf[128]; + int wrote; + + wrote = snprintf(buf, 128, "Could not translate address '%s'", addr); + buf[wrote] = '\0'; + write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); + + return sock; + } else { +#endif + char buf[256]; + int wrote; + + wrote = snprintf(buf, 256, "Host '%s' not found. %s", addr, estrdup(gai_strerror(rc))); + buf[wrote] = '\0'; + write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); + + return sock; +#ifndef PHP_WIN32 + } +#endif + return sock; + } + + if((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { + char buf[128]; + int wrote; + + wrote = sprintf(buf, "Unable to create socket"); + buf[wrote] = '\0'; + write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf)); + + return sock; + } + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) == -1) { + phpdbg_close_socket(sock); + return sock; + } + + + } while (0); + + *addr_res = *res; + + return sock; +}/*}}}*/ + +PHPDBG_API void +phpdbg_close_socket(int sock) +{ + if (socket >= 0) { +#ifdef _WIN32 + closesocket(sock); +#else + shutdown(sock, SHUT_RDWR); + close(sock); +#endif + } +} + diff --git a/phpdbg_io.h b/phpdbg_io.h index 3c4684698ae..1edfe73662b 100644 --- a/phpdbg_io.h +++ b/phpdbg_io.h @@ -33,5 +33,14 @@ phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_CC); PHPDBG_API int phpdbg_mixed_write(int sock, char *ptr, int len TSRMLS_CC); +PHPDBG_API int +phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *res); + +PHPDBG_API int +phpdbg_open_socket(const char *interface, short port); + +PHPDBG_API void +phpdbg_close_socket(int sock); + #endif /* PHPDBG_IO_H */ From 362c87f4b0aea6aa6b812259190f34259b592d80 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 18:30:07 +0200 Subject: [PATCH 088/125] don't use timeout for the remote prompt, recv() will block until input arrives --- phpdbg_cmd.c | 2 +- phpdbg_io.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index f4c2e172f9e..94e8e4c7976 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -863,7 +863,7 @@ readline: } len += bytes; /* XXX export the timeout through INI??*/ - } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, 30000)) > 0 || (errno == EINTR && bytes < 0)); + } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1)) > 0 || (errno == EINTR && bytes < 0)); if (bytes <= 0) { goto disconnect; diff --git a/phpdbg_io.c b/phpdbg_io.c index 2dc6884f4e4..437e3ec3af3 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -60,6 +60,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) struct pollfd pfd; TSRMLS_FETCH(); + if (tmo < 0) goto recv_once; pfd.fd = sock; pfd.events = POLLIN; @@ -71,6 +72,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) struct timeval ttmo; TSRMLS_FETCH(); + if (tmo < 0) goto recv_once; FD_ZERO(&readfds); FD_SET(sock, &readfds); @@ -84,11 +86,14 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) return -1; } +recv_once: while(i > 0) { - /* There's something to read. Read what's available and proceed - disregarding whether len could be exhausted or not.*/ - int can_read = recv(sock, p, i, MSG_PEEK); - i = can_read; + if (tmo < 0) { + /* There's something to read. Read what's available and proceed + disregarding whether len could be exhausted or not.*/ + int can_read = recv(sock, p, i, MSG_PEEK); + i = can_read; + } got_now = recv(sock, p, i, 0); if (got_now == -1) { From 795cb98ac6a85e86ff0f1a955408cffba7eb5e2e Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 19 Oct 2014 20:09:39 +0200 Subject: [PATCH 089/125] revert PHP_EOL changes --- phpdbg.c | 10 +++++----- phpdbg_bp.c | 36 ++++++++++++++++++------------------ phpdbg_cmd.c | 20 ++++++++++---------- phpdbg_frame.c | 6 +++--- phpdbg_help.c | 8 ++++---- phpdbg_prompt.c | 22 +++++++++++----------- phpdbg_utils.c | 24 ++++++++++++------------ phpdbg_watch.c | 4 ++-- 8 files changed, 65 insertions(+), 65 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 2893aa300e4..72582ceeac7 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -742,10 +742,10 @@ static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */ } phpdbg_write("cleaninfo", "classes=\"%d\" functions=\"%d\" constants=\"%d\" includes=\"%d\"", - "Classes %d" PHP_EOL - "Functions %d" PHP_EOL - "Constants %d" PHP_EOL - "Includes %d" PHP_EOL, + "Classes %d\n" + "Functions %d\n" + "Constants %d\n" + "Includes %d\n", zend_hash_num_elements(EG(class_table)), zend_hash_num_elements(EG(function_table)), zend_hash_num_elements(EG(zend_constants)), @@ -1170,7 +1170,7 @@ phpdbg_main: sapi_startup(phpdbg); phpdbg->startup(phpdbg); printf( - "phpdbg %s (built: %s %s)" PHP_EOL "PHP %s, Copyright (c) 1997-2014 The PHP Group" PHP_EOL "%s", + "phpdbg %s (built: %s %s)\nPHP %s, Copyright (c) 1997-2014 The PHP Group\n%s", PHPDBG_VERSION, __DATE__, __TIME__, diff --git a/phpdbg_bp.c b/phpdbg_bp.c index e7f313d6b87..26e6ee29713 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -1339,8 +1339,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breaksymbol_t *brake; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("Function Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Function Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position)) { @@ -1357,8 +1357,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ zend_uint class_len = 0; zend_ulong class_idx = 0L; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("Method Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Method Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**) &class_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) { @@ -1383,8 +1383,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position[2]; HashTable *points; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("File Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("File Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**) &points, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) { @@ -1405,8 +1405,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakline_t *brake; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("Opline Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Opline Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) { @@ -1436,8 +1436,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ zend_uint class_len = 0, method_len = 0; zend_ulong class_idx = 0L, method_idx = 0L; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("Method opline Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Method opline Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) { @@ -1475,8 +1475,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ zend_uint function_len = 0; zend_ulong function_idx = 0L; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("Function opline Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Function opline Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) { @@ -1505,8 +1505,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ zend_uint file_len = 0; zend_ulong file_idx = 0L; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("File opline Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("File opline Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) { @@ -1531,8 +1531,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakcond_t *brake; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("Conditional Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Conditional Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { @@ -1607,8 +1607,8 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ HashPosition position; phpdbg_breakop_t *brake; - phpdbg_out(SEPARATE PHP_EOL); - phpdbg_out("Opcode Breakpoints:" PHP_EOL); + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Opcode Breakpoints:\n"); for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**) &brake, &position) == SUCCESS; zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) { diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 94e8e4c7976..ae4925c5a2b 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -417,43 +417,43 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) if (param && param->type) { switch (param->type) { case STR_PARAM: - fprintf(stderr, "%s STR_PARAM(%s=%lu)" PHP_EOL, msg, param->str, param->len); + fprintf(stderr, "%s STR_PARAM(%s=%lu)\n", msg, param->str, param->len); break; case ADDR_PARAM: - fprintf(stderr, "%s ADDR_PARAM(%lu)" PHP_EOL, msg, param->addr); + fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); break; case NUMERIC_FILE_PARAM: - fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#%lu)" PHP_EOL, msg, param->file.name, param->file.line); + fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#%lu)\n", msg, param->file.name, param->file.line); break; case FILE_PARAM: - fprintf(stderr, "%s FILE_PARAM(%s:%lu)" PHP_EOL, msg, param->file.name, param->file.line); + fprintf(stderr, "%s FILE_PARAM(%s:%lu)\n", msg, param->file.name, param->file.line); break; case METHOD_PARAM: - fprintf(stderr, "%s METHOD_PARAM(%s::%s)" PHP_EOL, msg, param->method.class, param->method.name); + fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); break; case NUMERIC_METHOD_PARAM: - fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)" PHP_EOL, msg, param->method.class, param->method.name); + fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); break; case NUMERIC_FUNCTION_PARAM: - fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%ld)" PHP_EOL, msg, param->str, param->num); + fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%ld)\n", msg, param->str, param->num); break; case NUMERIC_PARAM: - fprintf(stderr, "%s NUMERIC_PARAM(%ld)" PHP_EOL, msg, param->num); + fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); break; case COND_PARAM: - fprintf(stderr, "%s COND_PARAM(%s=%lu)" PHP_EOL, msg, param->str, param->len); + fprintf(stderr, "%s COND_PARAM(%s=%lu)\n", msg, param->str, param->len); break; case OP_PARAM: - fprintf(stderr, "%s OP_PARAM(%s=%lu)" PHP_EOL, msg, param->str, param->len); + fprintf(stderr, "%s OP_PARAM(%s=%lu)\n", msg, param->str, param->len); break; default: { diff --git a/phpdbg_frame.c b/phpdbg_frame.c index f4ab92392f1..8baaf771906 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -228,16 +228,16 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ phpdbg_out("frame #%d: ", i++); phpdbg_xml(" "); phpdbg_xml(""); zval_dtor(&zbacktrace); diff --git a/phpdbg_help.c b/phpdbg_help.c index f2c6486ae5e..edb617f1f26 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -136,7 +136,7 @@ void pretty_print(char *text TSRMLS_DC) phpdbg_error("help", "overrun=\"%lu\"", "Output overrun of %lu bytes", ((q - new) - size)); } - phpdbg_out("%s" PHP_EOL, new); + phpdbg_out("%s\n", new); efree(new); } /* }}} */ @@ -144,7 +144,7 @@ void pretty_print(char *text TSRMLS_DC) void summary_print(phpdbg_command_t const * const cmd TSRMLS_DC) { char *summary; - spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**" PHP_EOL, cmd->name, cmd->alias, cmd->tip); + spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**\n", cmd->name, cmd->alias, cmd->tip); pretty_print(summary TSRMLS_CC); efree(summary); } @@ -285,7 +285,7 @@ PHPDBG_HELP(aliases) /* {{{ */ /* Print out aliases for help as this one comes last, with the added text on how aliases are used */ get_command("h", 1, &c, phpdbg_prompt_commands TSRMLS_CC); - phpdbg_writeln("aliasinfo", "alias=\"%c\" name=\"%s\" tip=\"%s\"", " %c %-20s %s" PHP_EOL, c->alias, c->name, c->tip); + phpdbg_writeln("aliasinfo", "alias=\"%c\" name=\"%s\" tip=\"%s\"", " %c %-20s %s\n", c->alias, c->name, c->tip); phpdbg_xml(""); @@ -319,7 +319,7 @@ PHPDBG_HELP(aliases) /* {{{ */ * Also note the convention that help text not directly referenceable as a help param * has a key ending in ! */ -#define CR PHP_EOL +#define CR "\n" phpdbg_help_text_t phpdbg_help_text[] = { /******************************** General Help Topics ********************************/ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index cc2062b2b7e..194c890ebe6 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -190,7 +190,7 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * if (fretval) { zend_print_zval_r(fretval, 0 TSRMLS_CC); - phpdbg_out(PHP_EOL); + phpdbg_out("\n"); } zval_dtor(&fname); @@ -551,7 +551,7 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ zend_call_function(&fci, NULL TSRMLS_CC); if (trace) { - phpdbg_writeln("exception", "name=\"%s\" trace=\"%.*s\"", "Uncaught %s!" PHP_EOL "%.*s", Z_OBJCE(exception)->name, Z_STRLEN_P(trace), Z_STRVAL_P(trace)); + phpdbg_writeln("exception", "name=\"%s\" trace=\"%.*s\"", "Uncaught %s!\n%.*s", Z_OBJCE(exception)->name, Z_STRLEN_P(trace), Z_STRVAL_P(trace)); zval_ptr_dtor(&trace); } else { @@ -674,7 +674,7 @@ int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keyl phpdbg_xml(""); zend_print_zval_r(*zv, 0 TSRMLS_CC); phpdbg_xml(""); - phpdbg_out(PHP_EOL); + phpdbg_out("\n"); efree(name); efree(keyname); @@ -707,7 +707,7 @@ PHPDBG_COMMAND(ev) /* {{{ */ phpdbg_xml(""); zend_print_zval_r(&retval, 0 TSRMLS_CC); phpdbg_xml(""); - phpdbg_out(PHP_EOL); + phpdbg_out("\n"); zval_dtor(&retval); } } zend_end_try(); @@ -741,7 +741,7 @@ PHPDBG_COMMAND(back) /* {{{ */ PHPDBG_COMMAND(print) /* {{{ */ { - phpdbg_out("Execution Context Information" PHP_EOL PHP_EOL); + phpdbg_out("Execution Context Information\n\n"); phpdbg_xml(""); #ifdef HAVE_LIBREADLINE phpdbg_writeln("print", "readline=\"yes\"", "Readline yes"); @@ -855,12 +855,12 @@ PHPDBG_COMMAND(sh) /* {{{ */ } /* }}} */ static int add_module_info(zend_module_entry *module TSRMLS_DC) { - phpdbg_write("module", "name=\"%s\"", "%s" PHP_EOL, module->name); + phpdbg_write("module", "name=\"%s\"", "%s\n", module->name); return 0; } static int add_zendext_info(zend_extension *ext TSRMLS_DC) { - phpdbg_write("extension", "name=\"%s\"", "%s" PHP_EOL, ext->name); + phpdbg_write("extension", "name=\"%s\"", "%s\n", ext->name); return 0; } @@ -1012,7 +1012,7 @@ PHPDBG_COMMAND(dl) /* {{{ */ if (!param || param->type == EMPTY_PARAM) { phpdbg_notice("dl", "extensiontype=\"Zend extension\"", "Zend extensions"); zend_llist_apply(&zend_extensions, (llist_apply_func_t) add_zendext_info TSRMLS_CC); - phpdbg_out(PHP_EOL); + phpdbg_out("\n"); phpdbg_notice("dl", "extensiontype=\"module\"", "Modules"); zend_hash_apply(&module_registry, (apply_func_t) add_module_info TSRMLS_CC); } else switch (param->type) { @@ -1109,7 +1109,7 @@ PHPDBG_COMMAND(clean) /* {{{ */ return SUCCESS; } - phpdbg_out("Cleaning Execution Environment" PHP_EOL); + phpdbg_out("Cleaning Execution Environment\n"); phpdbg_xml(""); phpdbg_writeln("clean", "classes=\"%d\"", "Classes %d", zend_hash_num_elements(EG(class_table))); @@ -1126,7 +1126,7 @@ PHPDBG_COMMAND(clean) /* {{{ */ PHPDBG_COMMAND(clear) /* {{{ */ { - phpdbg_out("Clearing Breakpoints" PHP_EOL); + phpdbg_out("Clearing Breakpoints\n"); phpdbg_xml(""); phpdbg_writeln("clear", "files=\"%d\"", "File %d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE])); @@ -1479,7 +1479,7 @@ zend_vm_enter: if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED; - phpdbg_out(PHP_EOL); + phpdbg_out("\n"); phpdbg_notice("signal", "type=\"SIGINT\"", "Program received signal SIGINT"); DO_INTERACTIVE(1); } diff --git a/phpdbg_utils.c b/phpdbg_utils.c index a3c19659285..4a45642a4d7 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1140,16 +1140,16 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m severity = "error"; if (!PHPDBG_G(last_was_newline)) { if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_mixed_write(fd, ZEND_STRL("" PHP_EOL "")); + phpdbg_mixed_write(fd, ZEND_STRL("\n" "")); } else { - phpdbg_mixed_write(fd, ZEND_STRL(PHP_EOL)); + phpdbg_mixed_write(fd, ZEND_STRL("\n")); } PHPDBG_G(last_was_newline) = 1; } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m" PHP_EOL, PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); + msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); } else { - msgoutlen = spprintf(&msgout, 0, "[%.*s]" PHP_EOL, msglen, msg); + msgoutlen = spprintf(&msgout, 0, "[%.*s]\n", msglen, msg); } break; @@ -1157,26 +1157,26 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m severity = "notice"; if (!PHPDBG_G(last_was_newline)) { if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_mixed_write(fd, ZEND_STRL("" PHP_EOL "")); + phpdbg_mixed_write(fd, ZEND_STRL("\n" "")); } else { - phpdbg_mixed_write(fd, ZEND_STRL(PHP_EOL)); + phpdbg_mixed_write(fd, ZEND_STRL("\n")); } PHPDBG_G(last_was_newline) = 1; } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m" PHP_EOL, PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); + msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); } else { - msgoutlen = spprintf(&msgout, 0, "[%.*s]" PHP_EOL, msglen, msg); + msgoutlen = spprintf(&msgout, 0, "[%.*s]\n", msglen, msg); } break; case P_WRITELN: severity = "normal"; if (msg) { - msgoutlen = spprintf(&msgout, 0, "%.*s" PHP_EOL, msglen, msg); + msgoutlen = spprintf(&msgout, 0, "%.*s\n", msglen, msg); } else { msgoutlen = 1; - msgout = estrdup(PHP_EOL); + msgout = estrdup("\n"); } PHPDBG_G(last_was_newline) = 1; break; @@ -1222,7 +1222,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m if (msg) { struct timeval tp; if (gettimeofday(&tp, NULL) == SUCCESS) { - msgoutlen = spprintf(&msgout, 0, "[%ld %.8F]: %.*s" PHP_EOL, tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); + msgoutlen = spprintf(&msgout, 0, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); } else { msgoutlen = FAILURE; } @@ -1459,7 +1459,7 @@ PHPDBG_API int phpdbg_rlog(int fd, const char *fmt, ...) { /* {{{ */ strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt)); #endif spprintf(&buffer, 0, friendly, tp.tv_usec/1000); - spprintf(&format, 0, "[%s]: %s" PHP_EOL, buffer, fmt); + spprintf(&format, 0, "[%s]: %s\n", buffer, fmt); rc = vspprintf(&outbuf, 0, format, args); if (outbuf) { diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 3f07b70dcd5..de6cddf5b3c 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -567,7 +567,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_xml(""); zend_print_flat_zval_r((zval *) oldPtr TSRMLS_CC); phpdbg_xml(""); - phpdbg_out(PHP_EOL); + phpdbg_out("\n"); } } if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && (removed || show_ref)) { @@ -593,7 +593,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_xml(""); zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); phpdbg_xml(""); - phpdbg_out(PHP_EOL); + phpdbg_out("\n"); } if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && show_ref) { phpdbg_writeln("watchrefcount", "type=\"new\" refcount=\"%d\" isref=\"%d\"", "New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); From 07670ff8712dd39240b2050fd8014bf7aa8769c5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 19 Oct 2014 21:20:43 +0200 Subject: [PATCH 090/125] Fix TSRMLS_* and a few warnings --- phpdbg.c | 9 +++++---- phpdbg.h | 23 ++++++++++++----------- phpdbg_io.c | 47 +++++++++++++++-------------------------------- phpdbg_io.h | 26 +++++++------------------- phpdbg_utils.c | 42 ++++++++++++++++++++---------------------- phpdbg_utils.h | 3 ++- 6 files changed, 61 insertions(+), 89 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 72582ceeac7..71def1dd52e 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -28,6 +28,7 @@ #include "phpdbg_list.h" #include "phpdbg_utils.h" #include "phpdbg_set.h" +#include "phpdbg_io.h" #include "zend_alloc.h" /* {{{ remote console headers */ @@ -793,7 +794,7 @@ static void phpdbg_remote_close(int socket, FILE *stream) { } /* don't inline this, want to debug it easily, will inline when done */ -static int phpdbg_remote_init(const char* address, unsigned short port, int server, int *socket, FILE **stream) { +static int phpdbg_remote_init(const char* address, unsigned short port, int server, int *socket, FILE **stream TSRMLS_DC) { phpdbg_remote_close(*socket, *stream); if (server < 0) { @@ -1255,8 +1256,8 @@ phpdbg_main: /* setup remote server if necessary */ if (!cleaning && listen > 0) { - server = phpdbg_open_socket(address, listen); - if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream) == FAILURE) { + server = phpdbg_open_socket(address, listen TSRMLS_CC); + if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream TSRMLS_CC) == FAILURE) { exit(0); } @@ -1462,7 +1463,7 @@ phpdbg_interact: if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { /* renegociate connections */ - phpdbg_remote_init(address, listen, server, &socket, &stream); + phpdbg_remote_init(address, listen, server, &socket, &stream TSRMLS_CC); /* set streams */ if (stream) { diff --git a/phpdbg.h b/phpdbg.h index fc9944111eb..2cb73ff43fa 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -40,20 +40,20 @@ #include "zend_ini_scanner.h" #include "zend_stream.h" #ifndef _WIN32 -# include "zend_signal.h" +# include "zend_signal.h" #endif #include "SAPI.h" #include #include #if defined(_WIN32) && !defined(__MINGW32__) -# include -# include "config.w32.h" -# undef strcasecmp -# undef strncasecmp -# define strcasecmp _stricmp -# define strncasecmp _strnicmp +# include +# include "config.w32.h" +# undef strcasecmp +# undef strncasecmp +# define strcasecmp _stricmp +# define strncasecmp _strnicmp #else -# include "php_config.h" +# include "php_config.h" #endif #ifndef O_BINARY # define O_BINARY 0 @@ -65,11 +65,11 @@ #endif #ifdef HAVE_LIBREADLINE -# include -# include +# include +# include #endif #ifdef HAVE_LIBEDIT -# include +# include #endif /* {{{ remote console headers */ @@ -78,6 +78,7 @@ # include # include # include +# include #endif /* }}} */ /* {{{ strings */ diff --git a/phpdbg_io.c b/phpdbg_io.c index 437e3ec3af3..79fd55957df 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -51,14 +51,11 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -PHPDBG_API int -phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) -{/*{{{*/ +PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC) { int got_now, i = len, j; char *p = ptr; #ifndef PHP_WIN32 struct pollfd pfd; - TSRMLS_FETCH(); if (tmo < 0) goto recv_once; pfd.fd = sock; @@ -70,7 +67,6 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo) #else struct fd_set readfds; struct timeval ttmo; - TSRMLS_FETCH(); if (tmo < 0) goto recv_once; FD_ZERO(&readfds); @@ -105,11 +101,9 @@ recv_once: } return p - ptr; -}/*}}}*/ +} -PHPDBG_API int -phpdbg_send_bytes(int sock, char *ptr, int len) -{/*{{{*/ +PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len) { int sent, i = len; char *p = ptr; /* XXX poll/select needed here? */ @@ -123,36 +117,30 @@ phpdbg_send_bytes(int sock, char *ptr, int len) } return len; -}/*}}}*/ +} -PHPDBG_API int -phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_CC) -{/*{{{*/ +PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC) { if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { - return phpdbg_consume_bytes(sock, ptr, len, tmo); + return phpdbg_consume_bytes(sock, ptr, len, tmo TSRMLS_CC); } return read(sock, ptr, len); -}/*}}}*/ +} -PHPDBG_API int -phpdbg_mixed_write(int sock, char *ptr, int len TSRMLS_CC) -{/*{{{*/ +PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC) { if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { return phpdbg_send_bytes(sock, ptr, len); } return write(sock, ptr, len); -}/*}}}*/ +} -PHPDBG_API int -phpdbg_open_socket(const char *interface, short port) /* {{{ */ -{ +PHPDBG_API int phpdbg_open_socket(const char *interface, short port TSRMLS_DC) { struct addrinfo res; - int fd = phpdbg_create_listenable_socket(interface, port, &res); + int fd = phpdbg_create_listenable_socket(interface, port, &res TSRMLS_CC); if (fd == -1) { return -1; @@ -166,19 +154,16 @@ phpdbg_open_socket(const char *interface, short port) /* {{{ */ listen(fd, 5); return fd; -} /* }}} */ +} -PHPDBG_API int -phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *addr_res) -{/*{{{*/ +PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *addr_res TSRMLS_DC) { int sock = -1, rc; int reuse = 1; struct in6_addr serveraddr; struct addrinfo hints, *res = NULL; char port_buf[8]; int8_t any_addr = *addr == '*'; - TSRMLS_FETCH(); do { memset(&hints, 0, sizeof hints); @@ -263,11 +248,9 @@ phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *add *addr_res = *res; return sock; -}/*}}}*/ +} -PHPDBG_API void -phpdbg_close_socket(int sock) -{ +PHPDBG_API void phpdbg_close_socket(int sock) { if (socket >= 0) { #ifdef _WIN32 closesocket(sock); diff --git a/phpdbg_io.h b/phpdbg_io.h index 1edfe73662b..4d1b74044b9 100644 --- a/phpdbg_io.h +++ b/phpdbg_io.h @@ -21,26 +21,14 @@ #include "phpdbg.h" -PHPDBG_API int -phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo); +PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC); +PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len); +PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC); +PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC); -PHPDBG_API int -phpdbg_send_bytes(int sock, char *ptr, int len); - -PHPDBG_API int -phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_CC); - -PHPDBG_API int -phpdbg_mixed_write(int sock, char *ptr, int len TSRMLS_CC); - -PHPDBG_API int -phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *res); - -PHPDBG_API int -phpdbg_open_socket(const char *interface, short port); - -PHPDBG_API void -phpdbg_close_socket(int sock); +PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *res TSRMLS_DC); +PHPDBG_API int phpdbg_open_socket(const char *interface, short port TSRMLS_DC); +PHPDBG_API void phpdbg_close_socket(int sock); #endif /* PHPDBG_IO_H */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 4a45642a4d7..0768726e6e1 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1129,7 +1129,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m const char *severity; if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML) && PHPDBG_G(in_script_xml) && PHPDBG_G(in_script_xml) != type) { - phpdbg_mixed_write(fd, ZEND_STRL("")); + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); PHPDBG_G(in_script_xml) = 0; } @@ -1140,9 +1140,9 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m severity = "error"; if (!PHPDBG_G(last_was_newline)) { if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_mixed_write(fd, ZEND_STRL("\n" "")); + phpdbg_mixed_write(fd, ZEND_STRL("\n" "") TSRMLS_CC); } else { - phpdbg_mixed_write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL("\n") TSRMLS_CC); } PHPDBG_G(last_was_newline) = 1; } @@ -1157,9 +1157,9 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m severity = "notice"; if (!PHPDBG_G(last_was_newline)) { if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_mixed_write(fd, ZEND_STRL("\n" "")); + phpdbg_mixed_write(fd, ZEND_STRL("\n" "") TSRMLS_CC); } else { - phpdbg_mixed_write(fd, ZEND_STRL("\n")); + phpdbg_mixed_write(fd, ZEND_STRL("\n") TSRMLS_CC); } PHPDBG_G(last_was_newline) = 1; } @@ -1201,16 +1201,16 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m if (PHPDBG_G(in_script_xml) != type) { char *stream_buf; int stream_buflen = spprintf(&stream_buf, 0, "", type == P_STDERR ? "stderr" : "stdout"); - phpdbg_mixed_write(fd, stream_buf, stream_buflen); + phpdbg_mixed_write(fd, stream_buf, stream_buflen TSRMLS_CC); efree(stream_buf); PHPDBG_G(in_script_xml) = type; } buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); phpdbg_encode_ctrl_chars(&buf, &buflen); - phpdbg_mixed_write(fd, buf, buflen); + phpdbg_mixed_write(fd, buf, buflen TSRMLS_CC); efree(buf); } else { - phpdbg_mixed_write(fd, msg, msglen); + phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC); } return msglen; } @@ -1239,8 +1239,6 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m xml = xmlbuf; } if (msgout) { -// unsigned char *tmp = msgout; -// buf = php_escape_html_entities(tmp, msgoutlen, (size_t *) &buflen, 0, ENT_COMPAT, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); buflen = phpdbg_encode_xml(&buf, msgout, msgoutlen, '"', """); xmloutlen = spprintf(&xmlout, 0, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf); @@ -1250,10 +1248,10 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m } phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen); - phpdbg_mixed_write(fd, xmlout, xmloutlen); + phpdbg_mixed_write(fd, xmlout, xmloutlen TSRMLS_CC); efree(xmlout); } else if (msgout) { - phpdbg_mixed_write(fd, msgout, msgoutlen); + phpdbg_mixed_write(fd, msgout, msgoutlen TSRMLS_CC); } if (PHPDBG_G(req_id) && (PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { @@ -1381,11 +1379,11 @@ PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) { phpdbg_encode_ctrl_chars(&buffer, &buflen); if (PHPDBG_G(in_script_xml)) { - phpdbg_mixed_write(fd, ZEND_STRL("")); + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); PHPDBG_G(in_script_xml) = 0; } - len = phpdbg_mixed_write(fd, buffer, buflen); + len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); efree(buffer); } @@ -1402,7 +1400,7 @@ PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...) { buflen = vspprintf(&buffer, 0, fmt, args); va_end(args); - len = phpdbg_mixed_write(fd, buffer, buflen); + len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); efree(buffer); return len; @@ -1426,22 +1424,22 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { phpdbg_encode_ctrl_chars(&msg, &msglen); if (PHPDBG_G(in_script_xml)) { - phpdbg_mixed_write(fd, ZEND_STRL("")); + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); PHPDBG_G(in_script_xml) = 0; } - phpdbg_mixed_write(fd, ZEND_STRL("")); - len = phpdbg_mixed_write(fd, msg, msglen); - phpdbg_mixed_write(fd, ZEND_STRL("")); + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); + len = phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC); + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); } else { - len = phpdbg_mixed_write(fd, buffer, buflen); + len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); } return len; } -PHPDBG_API int phpdbg_rlog(int fd, const char *fmt, ...) { /* {{{ */ +PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...) { /* {{{ */ int rc = 0; va_list args; @@ -1463,7 +1461,7 @@ PHPDBG_API int phpdbg_rlog(int fd, const char *fmt, ...) { /* {{{ */ rc = vspprintf(&outbuf, 0, format, args); if (outbuf) { - rc = phpdbg_mixed_write(fd, outbuf, rc); + rc = phpdbg_mixed_write(fd, outbuf, rc TSRMLS_CC); efree(outbuf); } diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 0a677b40c69..cee39c4879f 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -56,7 +56,8 @@ PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...); PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...); PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...); -PHPDBG_API int phpdbg_rlog(int fd, const char *fmt, ...); +PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...); +#define phpdbg_rlog(fd, fmt, ...) phpdbg_rlog_internal(fd TSRMLS_CC, fmt, ##__VA_ARGS__) #define phpdbg_error(tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) #define phpdbg_notice(tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) From 2916a14018c19fb6d38984e12eed930666dcb200 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Oct 2014 08:46:22 +0200 Subject: [PATCH 091/125] Fix reading from remote on some *nixes --- phpdbg_cmd.c | 3 ++- phpdbg_io.c | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index ae4925c5a2b..c09df70a414 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -23,6 +23,7 @@ #include "phpdbg_utils.h" #include "phpdbg_set.h" #include "phpdbg_prompt.h" +#include "phpdbg_io.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -863,7 +864,7 @@ readline: } len += bytes; /* XXX export the timeout through INI??*/ - } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1)) > 0 || (errno == EINTR && bytes < 0)); + } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1 TSRMLS_CC)) > 0 || (errno == EINTR && bytes < 0)); if (bytes <= 0) { goto disconnect; diff --git a/phpdbg_io.c b/phpdbg_io.c index 79fd55957df..753779a5df7 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -88,10 +88,22 @@ recv_once: /* There's something to read. Read what's available and proceed disregarding whether len could be exhausted or not.*/ int can_read = recv(sock, p, i, MSG_PEEK); +#ifndef _WIN32 + if (can_read == -1 && errno == EINTR) { + continue; + } +#endif i = can_read; } +#ifdef _WIN32 got_now = recv(sock, p, i, 0); +#else + do { + got_now = recv(sock, p, i, 0); + } while (got_now == -1 && errno == EINTR); +#endif + if (got_now == -1) { write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Read operation timed out!\n")); return -1; From fa1c26f0227a50ebb44d0dee65e87b3291f91d23 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Oct 2014 09:47:35 +0200 Subject: [PATCH 092/125] Fix for ports >= 1<<15 --- phpdbg_io.c | 7 ++++--- phpdbg_io.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/phpdbg_io.c b/phpdbg_io.c index 753779a5df7..019e1e8e1b8 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -150,7 +150,7 @@ PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC) } -PHPDBG_API int phpdbg_open_socket(const char *interface, short port TSRMLS_DC) { +PHPDBG_API int phpdbg_open_socket(const char *interface, unsigned short port TSRMLS_DC) { struct addrinfo res; int fd = phpdbg_create_listenable_socket(interface, port, &res TSRMLS_CC); @@ -169,7 +169,7 @@ PHPDBG_API int phpdbg_open_socket(const char *interface, short port TSRMLS_DC) { } -PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *addr_res TSRMLS_DC) { +PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, unsigned short port, struct addrinfo *addr_res TSRMLS_DC) { int sock = -1, rc; int reuse = 1; struct in6_addr serveraddr; @@ -205,12 +205,13 @@ PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, int port, struc } } - snprintf(port_buf, 7, "%d", port); + snprintf(port_buf, 7, "%u", port); if (!any_addr) { rc = getaddrinfo(addr, port_buf, &hints, &res); } else { rc = getaddrinfo(NULL, port_buf, &hints, &res); } + if (0 != rc) { #ifndef PHP_WIN32 if (rc == EAI_SYSTEM) { diff --git a/phpdbg_io.h b/phpdbg_io.h index 4d1b74044b9..3ac8f4112d0 100644 --- a/phpdbg_io.h +++ b/phpdbg_io.h @@ -26,8 +26,8 @@ PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len); PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC); PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC); -PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *res TSRMLS_DC); -PHPDBG_API int phpdbg_open_socket(const char *interface, short port TSRMLS_DC); +PHPDBG_API int phpdbg_create_listenable_socket(const char *addr, unsigned short port, struct addrinfo *res TSRMLS_DC); +PHPDBG_API int phpdbg_open_socket(const char *interface, unsigned short port TSRMLS_DC); PHPDBG_API void phpdbg_close_socket(int sock); #endif /* PHPDBG_IO_H */ From 6c6b356f637c1677a4f1b6f946fb899c2769aea5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Oct 2014 16:05:37 +0200 Subject: [PATCH 093/125] Add values of scalars to info vars/globals --- phpdbg_info.c | 53 ++++++++++++++++++++++++++++++++++----------------- xml.md | 2 ++ 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/phpdbg_info.c b/phpdbg_info.c index fee8368ab6f..e7857e1ff52 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -173,7 +173,7 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { } if (zend_hash_num_elements(&vars)) { - phpdbg_out("Address\t\tRefs\tType\t\tVariable"); + phpdbg_out("Address Refs Type Variable\n"); for (zend_hash_internal_pointer_reset_ex(&vars, &pos); zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS; zend_hash_move_forward_ex(&vars, &pos)) { @@ -184,23 +184,42 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { phpdbg_try_access { if (!(invalid_data = !*data)) { -#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("variable", "address=\"%p\" refcount=\"%d\" type=\"%s\" refstatus=\"%s\" name=\"%s\" " attrs, "%p\t%d\t(%s)\n%s$%s", *data, Z_REFCOUNT_PP(data), zend_zval_type_name(*data), Z_ISREF_PP(data) ? "&": "", var, ##__VA_ARGS__) +#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("variable", "address=\"%p\" refcount=\"%d\" type=\"%s\" refstatus=\"%s\" name=\"%s\" " attrs, "%-18p %-7d %-9s %s$%s" msg, *data, Z_REFCOUNT_PP(data), zend_zval_type_name(*data), Z_ISREF_PP(data) ? "&": "", var, ##__VA_ARGS__) - if (Z_TYPE_PP(data) == IS_RESOURCE) { - phpdbg_try_access { - int type; - VARIABLEINFO("type=\"%s\"", "\n|-------(typeof)------> (%s)\n", zend_list_find(Z_RESVAL_PP(data), &type) ? zend_rsrc_list_get_rsrc_type(type TSRMLS_CC) : "unknown"); - } phpdbg_catch_access { - VARIABLEINFO("type=\"unknown\"", "\n|-------(typeof)------> (unknown)\n"); - } phpdbg_end_try_access(); - } else if (Z_TYPE_PP(data) == IS_OBJECT) { - phpdbg_try_access { - VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (%s)\n", Z_OBJCE_PP(data)->name); - } phpdbg_catch_access { - VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (unknown)\n"); - } phpdbg_end_try_access(); - } else { - VARIABLEINFO("", ""); + switch (Z_TYPE_PP(data)) { + case IS_RESOURCE: + phpdbg_try_access { + int type; + VARIABLEINFO("type=\"%s\"", "\n|-------(typeof)------> (%s)\n", zend_list_find(Z_RESVAL_PP(data), &type) ? zend_rsrc_list_get_rsrc_type(type TSRMLS_CC) : "unknown"); + } phpdbg_catch_access { + VARIABLEINFO("type=\"unknown\"", "\n|-------(typeof)------> (unknown)\n"); + } phpdbg_end_try_access(); + break; + case IS_OBJECT: + phpdbg_try_access { + VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (%s)\n", Z_OBJCE_PP(data)->name); + } phpdbg_catch_access { + VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (unknown)\n"); + } phpdbg_end_try_access(); + break; + case IS_STRING: + phpdbg_try_access { + VARIABLEINFO("length=\"%d\" value=\"%.*s%s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN_PP(data), Z_STRLEN_PP(data) < 255 ? Z_STRLEN_PP(data) : 255, Z_STRVAL_PP(data), Z_STRLEN_PP(data) > 255 ? "..." : ""); + } phpdbg_catch_access { + VARIABLEINFO("", ""); + } phpdbg_end_try_access(); + break; + case IS_BOOL: + VARIABLEINFO("value=\"%s\"", "\nbool (%s)", Z_LVAL_PP(data) ? "true" : "false"); + break; + case IS_LONG: + VARIABLEINFO("value=\"%ld\"", "\nint (%ld)", Z_LVAL_PP(data)); + break; + case IS_DOUBLE: + VARIABLEINFO("value=\"%lf\"", "\ndouble (%lf)", Z_DVAL_PP(data)); + break; + default: + VARIABLEINFO("", ""); } } } phpdbg_end_try_access(); diff --git a/xml.md b/xml.md index 7871b313766..06756342579 100644 --- a/xml.md +++ b/xml.md @@ -268,6 +268,8 @@ info (subcommands) - refstatus: empty if the zval is not a reference - class: the class the object in the zval is an instance of - resource: the type of the resource in the zval + - value: the value of primitive types (scalars) => string/int/bool/double + - length: if string, then the length of that string ### literal ### From 3e5a4c6f305a48e53f8da5f1245ae91f2b8c672b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Oct 2014 21:14:13 +0200 Subject: [PATCH 094/125] Add info constants (alias: i d) command --- phpdbg_help.c | 19 ++++++------ phpdbg_info.c | 86 ++++++++++++++++++++++++++++++++++++++++++++------- phpdbg_info.h | 1 + 3 files changed, 86 insertions(+), 20 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index edb617f1f26..8a7084bb5ae 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -653,15 +653,16 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Specific info commands are show below:" CR CR " **Target** **Alias** **Purpose**" CR -" **break** **b** show current breakpoints" CR -" **files** **F** show included files" CR -" **classes** **c** show loaded classes" CR -" **funcs** **f** show loaded functions" CR -" **error** **e** show last error" CR -" **vars** **v** show active variables" CR -" **globals** **g** show superglobal variables" CR -" **literal** **l** show active literal constants" CR -" **memory** **m** show memory manager stats" +" **break** **b** show current breakpoints" CR +" **files** **F** show included files" CR +" **classes** **c** show loaded classes" CR +" **funcs** **f** show loaded functions" CR +" **error** **e** show last error" CR +" **constants** **d** show user-defined constants" CR +" **vars** **v** show active variables" CR +" **globals** **g** show superglobal variables" CR +" **literal** **l** show active literal constants" CR +" **memory** **m** show memory manager stats" }, // ******** same issue about breakpoints in called frames diff --git a/phpdbg_info.c b/phpdbg_info.c index e7857e1ff52..74352878a02 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -31,15 +31,16 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[14], flags) const phpdbg_command_t phpdbg_info_commands[] = { - PHPDBG_INFO_COMMAND_D(break, "show breakpoints", 'b', info_break, NULL, 0, PHPDBG_ASYNC_SAFE), - PHPDBG_INFO_COMMAND_D(files, "show included files", 'F', info_files, NULL, 0, PHPDBG_ASYNC_SAFE), - PHPDBG_INFO_COMMAND_D(classes, "show loaded classes", 'c', info_classes, NULL, 0, PHPDBG_ASYNC_SAFE), - PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0, PHPDBG_ASYNC_SAFE), - PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0, PHPDBG_ASYNC_SAFE), - PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0, PHPDBG_ASYNC_SAFE), - PHPDBG_INFO_COMMAND_D(globals, "show superglobals", 'g', info_globals, NULL, 0, PHPDBG_ASYNC_SAFE), - PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0, PHPDBG_ASYNC_SAFE), - PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(break, "show breakpoints", 'b', info_break, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(files, "show included files", 'F', info_files, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(classes, "show loaded classes", 'c', info_classes, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(constants, "show user defined constants", 'd', info_constants, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(globals, "show superglobals", 'g', info_globals, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0, PHPDBG_ASYNC_SAFE), + PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0, PHPDBG_ASYNC_SAFE), PHPDBG_END_COMMAND }; @@ -96,6 +97,67 @@ PHPDBG_INFO(error) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_INFO(constants) /* {{{ */ +{ + HashPosition pos; + HashTable consts; + zend_constant *data; + + zend_hash_init(&consts, 8, NULL, NULL, 0); + + if (EG(zend_constants)) { + phpdbg_try_access { + zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos); + while (zend_hash_get_current_data_ex(EG(zend_constants), (void **) &data, &pos) == SUCCESS) { + if (data->module_number == PHP_USER_CONSTANT) { + zend_hash_update(&consts, data->name, data->name_len, (void **) &data, sizeof(zend_constant *), NULL); + } + zend_hash_move_forward_ex(EG(zend_constants), &pos); + } + } phpdbg_catch_access { + phpdbg_error("signalsegv", "", "Cannot fetch all the constants, invalid data source"); + } phpdbg_end_try_access(); + } + + phpdbg_notice("constantinfo", "num=\"%d\"", "User-defined constants (%d)", zend_hash_num_elements(&consts)); + + if (zend_hash_num_elements(&consts)) { + phpdbg_out("Address Refs Type Constant\n"); + for (zend_hash_internal_pointer_reset_ex(&consts, &pos); + zend_hash_get_current_data_ex(&consts, (void **) &data, &pos) == SUCCESS; + zend_hash_move_forward_ex(&consts, &pos)) { + data = *(zend_constant **) data; + +#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("constant", "address=\"%p\" refcount=\"%d\" type=\"%s\" name=\"%.*s\" " attrs, "%-18p %-7d %-9s %.*s" msg, &data->value, Z_REFCOUNT(data->value), zend_zval_type_name(&data->value), data->name_len - 1, data->name, ##__VA_ARGS__) + + switch (Z_TYPE(data->value)) { + case IS_STRING: + phpdbg_try_access { + VARIABLEINFO("length=\"%d\" value=\"%.*s%s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN(data->value), Z_STRLEN(data->value) < 255 ? Z_STRLEN(data->value) : 255, Z_STRVAL(data->value), Z_STRLEN(data->value) > 255 ? "..." : ""); + } phpdbg_catch_access { + VARIABLEINFO("", ""); + } phpdbg_end_try_access(); + break; + case IS_BOOL: + VARIABLEINFO("value=\"%s\"", "\nbool (%s)", Z_LVAL(data->value) ? "true" : "false"); + break; + case IS_LONG: + VARIABLEINFO("value=\"%ld\"", "\nint (%ld)", Z_LVAL(data->value)); + break; + case IS_DOUBLE: + VARIABLEINFO("value=\"%lf\"", "\ndouble (%lf)", Z_DVAL(data->value)); + break; + default: + VARIABLEINFO("", ""); + +#undef VARIABLEINFO + } + } + } + + return SUCCESS; +} /* }}} */ + static int phpdbg_arm_auto_global(zend_auto_global *auto_global TSRMLS_DC) { if (auto_global->armed) { if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { @@ -175,8 +237,8 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { if (zend_hash_num_elements(&vars)) { phpdbg_out("Address Refs Type Variable\n"); for (zend_hash_internal_pointer_reset_ex(&vars, &pos); - zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS; - zend_hash_move_forward_ex(&vars, &pos)) { + zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS; + zend_hash_move_forward_ex(&vars, &pos)) { char *var; zend_bool invalid_data = 1; @@ -222,6 +284,8 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { VARIABLEINFO("", ""); } } + +#undef VARIABLEINFO } phpdbg_end_try_access(); if (invalid_data) { diff --git a/phpdbg_info.h b/phpdbg_info.h index 6930cdd8244..aac9fa3ab3b 100644 --- a/phpdbg_info.h +++ b/phpdbg_info.h @@ -30,6 +30,7 @@ PHPDBG_INFO(break); PHPDBG_INFO(classes); PHPDBG_INFO(funcs); PHPDBG_INFO(error); +PHPDBG_INFO(constants); PHPDBG_INFO(vars); PHPDBG_INFO(globals); PHPDBG_INFO(literal); From d410b23f90505a6f68d4956e8c114860b9040ed2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Oct 2014 21:17:45 +0200 Subject: [PATCH 095/125] Ensure that %.*s uses the full string (INCLUDING \0) --- phpdbg_utils.c | 54 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 0768726e6e1..e9fbdef9630 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1066,6 +1066,30 @@ PHPDBG_API int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool es } /* copy end */ +#define phpdbg_xml_asprintf(buf, ...) _phpdbg_xml_asprintf(buf TSRMLS_CC, ##__VA_ARGS__) +PHPDBG_API int _phpdbg_xml_asprintf(char **buf TSRMLS_DC, const char *format, zend_bool escape_xml, ...) { + int ret; + va_list va; + + va_start(va, escape_xml); + ret = phpdbg_xml_vasprintf(buf, format, escape_xml, va TSRMLS_CC); + va_end(va); + + return ret; +} + +#define phpdbg_asprintf(buf, ...) _phpdbg_asprintf(buf TSRMLS_CC, ##__VA_ARGS__) +PHPDBG_API int _phpdbg_asprintf(char **buf TSRMLS_DC, const char *format, ...) { + int ret; + va_list va; + + va_start(va, format); + ret = phpdbg_xml_vasprintf(buf, format, 0, va TSRMLS_CC); + va_end(va); + + return ret; +} + static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char *to) { int i; int tolen = to ? strlen(to) : 5; @@ -1147,9 +1171,9 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m PHPDBG_G(last_was_newline) = 1; } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); + msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); } else { - msgoutlen = spprintf(&msgout, 0, "[%.*s]\n", msglen, msg); + msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg); } break; @@ -1164,16 +1188,16 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m PHPDBG_G(last_was_newline) = 1; } if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - msgoutlen = spprintf(&msgout, 0, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); + msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); } else { - msgoutlen = spprintf(&msgout, 0, "[%.*s]\n", msglen, msg); + msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg); } break; case P_WRITELN: severity = "normal"; if (msg) { - msgoutlen = spprintf(&msgout, 0, "%.*s\n", msglen, msg); + msgoutlen = phpdbg_asprintf(&msgout, "%.*s\n", msglen, msg); } else { msgoutlen = 1; msgout = estrdup("\n"); @@ -1200,7 +1224,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { if (PHPDBG_G(in_script_xml) != type) { char *stream_buf; - int stream_buflen = spprintf(&stream_buf, 0, "", type == P_STDERR ? "stderr" : "stdout"); + int stream_buflen = phpdbg_asprintf(&stream_buf, "", type == P_STDERR ? "stderr" : "stdout"); phpdbg_mixed_write(fd, stream_buf, stream_buflen TSRMLS_CC); efree(stream_buf); PHPDBG_G(in_script_xml) = type; @@ -1222,7 +1246,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m if (msg) { struct timeval tp; if (gettimeofday(&tp, NULL) == SUCCESS) { - msgoutlen = spprintf(&msgout, 0, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); + msgoutlen = phpdbg_asprintf(&msgout, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); } else { msgoutlen = FAILURE; } @@ -1235,16 +1259,16 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m if (PHPDBG_G(req_id)) { char *xmlbuf = NULL; - xmllen = spprintf(&xmlbuf, 0, "req=\"%lu\" %.*s", PHPDBG_G(req_id), xmllen, xml); + xmllen = phpdbg_asprintf(&xmlbuf, "req=\"%lu\" %.*s", PHPDBG_G(req_id), xmllen, xml); xml = xmlbuf; } if (msgout) { buflen = phpdbg_encode_xml(&buf, msgout, msgoutlen, '"', """); - xmloutlen = spprintf(&xmlout, 0, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf); + xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf); efree(buf); } else { - xmloutlen = spprintf(&xmlout, 0, "<%s severity=\"%s\" %.*s msgout=\"\" />", tag, severity, xmllen, xml); + xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"\" />", tag, severity, xmllen, xml); } phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen); @@ -1397,7 +1421,7 @@ PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...) { int len = 0; va_start(args, fmt); - buflen = vspprintf(&buffer, 0, fmt, args); + buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); va_end(args); len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); @@ -1413,7 +1437,7 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { int len = 0; va_start(args, fmt); - buflen = vspprintf(&buffer, 0, fmt, args); + buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); va_end(args); if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { @@ -1456,9 +1480,9 @@ PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...) { /* #else strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt)); #endif - spprintf(&buffer, 0, friendly, tp.tv_usec/1000); - spprintf(&format, 0, "[%s]: %s\n", buffer, fmt); - rc = vspprintf(&outbuf, 0, format, args); + phpdbg_asprintf(&buffer, friendly, tp.tv_usec/1000); + phpdbg_asprintf(&format, "[%s]: %s\n", buffer, fmt); + rc = phpdbg_xml_vasprintf(&outbuf, format, 0, args TSRMLS_CC); if (outbuf) { rc = phpdbg_mixed_write(fd, outbuf, rc TSRMLS_CC); From 27629577b07efb18b7fbcdf4faeffef67d6cec64 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Oct 2014 21:22:16 +0200 Subject: [PATCH 096/125] Add xml.md info for info constants --- xml.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/xml.md b/xml.md index 06756342579..1cb164629a7 100644 --- a/xml.md +++ b/xml.md @@ -251,6 +251,23 @@ info (subcommands) - <lasterror error="" (file="" line="") /> - error attribute contains the last error as a string, is empty if there's no last error +### constants ### + +- <constantinfo num="" /> with num having an integer value, indicating the number of (local or superglobal) variables +- if info vars was used it'll have also one of these attributes: + - method + - function + - file + - opline +- for each variable there is a <constant> element +- <constant address="" refcount="" type="" name="" /> + - address: pointer to zval (hexadecimal) + - refcount: refcount of zval + - type: the variable type (long, string, ...). If the value is "unknown", the other attributes are meaningless + - name: the name of the variable + - value: the value of primitive types (scalars) => string/int/bool/double + - length: if string, then the length of that string + ### vars / globals ### - <variableinfo num="" /> with num having an integer value, indicating the number of (local or superglobal) variables @@ -259,7 +276,7 @@ info (subcommands) - function - file - opline -- for each variable there is a <variable> followed by a <variabledetails> element +- for each variable there is a <variable> element - <variable address="" refcount="" type="" name="" /> - address: pointer to zval (hexadecimal) - refcount: refcount of zval From dfdc19fb2a3a4e3ed7627e47678e63b02cb01278 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Oct 2014 21:52:47 +0200 Subject: [PATCH 097/125] Fix off-by-one bug in text messages (msg/) --- phpdbg_utils.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index e9fbdef9630..ecdb5fbfea3 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1094,7 +1094,7 @@ static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char * int i; int tolen = to ? strlen(to) : 5; char *tmp = *buf = emalloc(msglen * tolen); - for (i = 0; ++i < msglen; msg++) { + for (i = 0; i++ < msglen; msg++) { if (*msg == '&') { memcpy(tmp, ZEND_STRL("&")); tmp += sizeof("&") - 1; @@ -1118,20 +1118,17 @@ static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char * static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) { char *tmp, *tmpptr; - int len = *buflen; + int len; int i; tmp = tmpptr = emalloc(*buflen * 5); for (i = 0; i < *buflen; i++) { if ((*buf)[i] < 0x20) { - len += 4; *tmpptr++ = '&'; *tmpptr++ = '#'; if ((unsigned int) ((*buf)[i]) > 9) { *tmpptr++ = ((*buf)[i] / 10) + '0'; - } else { - --len; } *tmpptr++ = ((*buf)[i] % 10) + '0'; *tmpptr++ = ';'; From bafe6a9f7a89fdbea2fca0b2e1f3e1ab85db25db Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Oct 2014 22:05:05 +0200 Subject: [PATCH 098/125] Always show the prompt (now also: tag) --- phpdbg_cmd.c | 13 ++++--------- xml.md | 5 +++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index c09df70a414..30ea48cfbe4 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -813,14 +813,6 @@ disconnect: } #define USE_LIB_STAR (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)) -#if !USE_LIB_STAR - if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { - if (!phpdbg_out("%s", phpdbg_get_prompt(TSRMLS_C))) { - goto disconnect; - } - PHPDBG_G(last_was_newline) = 1; - } -#endif /* note: EOF makes readline write prompt again in local console mode - and ignored if compiled without readline */ /* strongly assuming to be in blocking mode... */ @@ -835,6 +827,9 @@ readline: memcpy(buf, PHPDBG_G(input_buffer), bytes); } + phpdbg_write("prompt", "", "%s", phpdbg_get_prompt(TSRMLS_C)); + PHPDBG_G(last_was_newline) = 1; + do { int i; if (bytes <= 0) { @@ -864,7 +859,7 @@ readline: } len += bytes; /* XXX export the timeout through INI??*/ - } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1 TSRMLS_CC)) > 0 || (errno == EINTR && bytes < 0)); + } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1 TSRMLS_CC)) > 0); if (bytes <= 0) { goto disconnect; diff --git a/xml.md b/xml.md index 1cb164629a7..05734d6be89 100644 --- a/xml.md +++ b/xml.md @@ -77,6 +77,11 @@ intro - help: command name for help - report: URL for bug reporting +prompt +------ + +- msg tag contains the text prompt +- indicates that a new command may be accepted phpdbg ------ From 3dec59f00d4c0345c23bcecafb40386c993e7fd0 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 20 Oct 2014 22:12:58 +0200 Subject: [PATCH 099/125] basic sigio surrogate for windows --- config.w32 | 3 +- phpdbg.c | 5 +++ phpdbg.h | 10 +++++ phpdbg_prompt.c | 5 +++ phpdbg_sigio_win32.c | 91 ++++++++++++++++++++++++++++++++++++++++++++ phpdbg_sigio_win32.h | 36 ++++++++++++++++++ 6 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 phpdbg_sigio_win32.c create mode 100644 phpdbg_sigio_win32.h diff --git a/config.w32 b/config.w32 index 6fb46652e1d..40a593331dd 100644 --- a/config.w32 +++ b/config.w32 @@ -4,7 +4,8 @@ ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c ' + 'phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c ' + 'phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c '+ - 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c'; + 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c ' + + 'phpdbg_sigio_win32.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; diff --git a/phpdbg.c b/phpdbg.c index 71def1dd52e..cd84aff6b10 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -88,6 +88,11 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->input_buflen = 0; pg->sigsafe_mem.mem = NULL; pg->sigsegv_bailout = NULL; + +#ifdef PHP_WIN32 + pg->sigio_watcher_thread = INVALID_HANDLE_VALUE; + memset(&pg->swd, 0, sizeof(struct win32_sigio_watcher_data)); +#endif } /* }}} */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ diff --git a/phpdbg.h b/phpdbg.h index 2cb73ff43fa..09dc079ad88 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -112,6 +112,12 @@ #include "phpdbg_utils.h" #include "phpdbg_btree.h" #include "phpdbg_watch.h" +#ifdef PHP_WIN32 +# include "phpdbg_sigio_win32.h" +#else +# define sigio_watcher_start() +# define sigio_watcher_stop() +#endif int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); @@ -279,6 +285,10 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) char *sapi_name_ptr; /* store sapi name to free it if necessary to not leak memory */ int socket_fd; /* file descriptor to socket (wait command) (-1 if unused) */ int socket_server_fd; /* file descriptor to master socket (wait command) (-1 if unused) */ +#ifdef PHP_WIN32 + HANDLE sigio_watcher_thread; /* sigio watcher thread handle */ + struct win32_sigio_watcher_data swd; +#endif ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ #endif diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 194c890ebe6..45f7b14d084 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -579,6 +579,8 @@ PHPDBG_COMMAND(run) /* {{{ */ zend_bool restore = 1; zend_execute_data *ex = EG(current_execute_data); + sigio_watcher_start(); + if (!PHPDBG_G(ops)) { if (phpdbg_compile(TSRMLS_C) == FAILURE) { phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec)); @@ -635,6 +637,7 @@ PHPDBG_COMMAND(run) /* {{{ */ zend_execute(EG(active_op_array) TSRMLS_CC); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; phpdbg_notice("stop", "type=\"normal\"", "Script ended normally"); + sigio_watcher_stop(); } zend_catch { EG(active_op_array) = orig_op_array; EG(opline_ptr) = orig_opline; @@ -644,6 +647,7 @@ PHPDBG_COMMAND(run) /* {{{ */ phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM"); restore = 0; } + sigio_watcher_stop(); } zend_end_try(); if (PHPDBG_G(socket_fd) != -1) { @@ -665,6 +669,7 @@ PHPDBG_COMMAND(run) /* {{{ */ } out: + sigio_watcher_stop(); PHPDBG_FRAME(num) = 0; return SUCCESS; } /* }}} */ diff --git a/phpdbg_sigio_win32.c b/phpdbg_sigio_win32.c new file mode 100644 index 00000000000..616c250617e --- /dev/null +++ b/phpdbg_sigio_win32.c @@ -0,0 +1,91 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 7-4 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Anatol Belski | + +----------------------------------------------------------------------+ +*/ + + +#include + +#include "phpdbg.h" + + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + + +VOID +SigIoWatcherThread(VOID *p) +{ + zend_uchar sig; + + (void)recv(PHPDBG_G(swd).fd, &sig, 1, 0); + + if (3 == sig) { + printf("signaled, got %d", sig); + /* XXX completely not sure where to go from here */ + if (raise(sig)) { + /* just out*/ + exit(0); + } + ExitThread(sig); + } +} + + +/* Start this only for the time of the run or eval command, +for so long that the main thread is busy serving some debug +session. */ +void +sigio_watcher_start(void) +{ + PHPDBG_G(swd).fd = PHPDBG_G(io)[PHPDBG_STDIN].fd; + PHPDBG_G(swd).signaled = 0; + + PHPDBG_G(sigio_watcher_thread) = CreateThread( + NULL, + 0, + (LPTHREAD_START_ROUTINE)SigIoWatcherThread, + NULL, + 0, + NULL); +} + +void +sigio_watcher_stop(void) +{ + DWORD waited; + + if (INVALID_HANDLE_VALUE == PHPDBG_G(sigio_watcher_thread)) { + /* it probably did bail out already */ + return; + } + + waited = WaitForSingleObject(PHPDBG_G(sigio_watcher_thread), 300); + + if (WAIT_OBJECT_0 != waited) { + if (!CancelSynchronousIo(PHPDBG_G(sigio_watcher_thread))) { + /* error out */ + } + + if (!TerminateThread(PHPDBG_G(sigio_watcher_thread), 0)) { + /* error out */ + } + } + + PHPDBG_G(swd).fd = -1; + PHPDBG_G(swd).signaled = 0; + PHPDBG_G(sigio_watcher_thread) = INVALID_HANDLE_VALUE; +} + diff --git a/phpdbg_sigio_win32.h b/phpdbg_sigio_win32.h new file mode 100644 index 00000000000..b724eaeeb5e --- /dev/null +++ b/phpdbg_sigio_win32.h @@ -0,0 +1,36 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 7-4 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Anatol Belski | + +----------------------------------------------------------------------+ +*/ + + +#ifndef PHPDBG_SIGIO_WIN32_H +#define PHPDBG_SIGIO_WIN32_H + +#include "phpdbg.h" + +struct win32_sigio_watcher_data { + int fd; + zend_uchar signaled; +}; + +void +sigio_watcher_start(void); + +void +sigio_watcher_stop(void); + +#endif /* PHPDBG_SIGIO_WIN32_H */ From da40b116a6fde9a8386e1902228e1e9353870c81 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 20 Oct 2014 22:55:00 +0200 Subject: [PATCH 100/125] further improvements to windows/sigio --- phpdbg_sigio_win32.c | 41 +++++++++++++++++++++++++++++++++-------- phpdbg_sigio_win32.h | 8 +++++++- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/phpdbg_sigio_win32.c b/phpdbg_sigio_win32.c index 616c250617e..b10f2a352cc 100644 --- a/phpdbg_sigio_win32.c +++ b/phpdbg_sigio_win32.c @@ -20,6 +20,7 @@ #include #include "phpdbg.h" +#include "phpdbg_sigio_win32.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -29,16 +30,32 @@ VOID SigIoWatcherThread(VOID *p) { zend_uchar sig; + struct win32_sigio_watcher_data *swd = (struct win32_sigio_watcher_data *)p; +#ifdef ZTS + void ***tsrm_ls = swd->tsrm_ls; + (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1, tsrm_ls); +#else + (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1); +#endif - (void)recv(PHPDBG_G(swd).fd, &sig, 1, 0); if (3 == sig) { printf("signaled, got %d", sig); - /* XXX completely not sure where to go from here */ - if (raise(sig)) { - /* just out*/ - exit(0); + /* XXX completely not sure it is done right here */ + if (swd->flags & PHPDBG_IS_INTERACTIVE) { + if (raise(sig)) { + /* just out*/ + exit(0); + } } + if (swd->flags & PHPDBG_IS_SIGNALED) { + phpdbg_set_sigsafe_mem(&sig TSRMLS_CC); + zend_try { + phpdbg_force_interruption(TSRMLS_C); + } zend_end_try(); + phpdbg_clear_sigsafe_mem(TSRMLS_C); + } + /* XXX set signaled flag to the caller thread, question is - whether it's needed */ ExitThread(sig); } } @@ -50,14 +67,20 @@ session. */ void sigio_watcher_start(void) { + TSRMLS_FETCH(); + PHPDBG_G(swd).fd = PHPDBG_G(io)[PHPDBG_STDIN].fd; - PHPDBG_G(swd).signaled = 0; + PHPDBG_G(swd).running = 1; + PHPDBG_G(swd).flags = PHPDBG_G(flags); +#ifdef ZTS + PHPDBG_G(swd).tsrm_ls = tsrm_ls; +#endif PHPDBG_G(sigio_watcher_thread) = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)SigIoWatcherThread, - NULL, + &PHPDBG_G(swd), 0, NULL); } @@ -66,6 +89,7 @@ void sigio_watcher_stop(void) { DWORD waited; + TSRMLS_FETCH(); if (INVALID_HANDLE_VALUE == PHPDBG_G(sigio_watcher_thread)) { /* it probably did bail out already */ @@ -85,7 +109,8 @@ sigio_watcher_stop(void) } PHPDBG_G(swd).fd = -1; - PHPDBG_G(swd).signaled = 0; + PHPDBG_G(swd).running = 0; + PHPDBG_G(swd).flags = 0; PHPDBG_G(sigio_watcher_thread) = INVALID_HANDLE_VALUE; } diff --git a/phpdbg_sigio_win32.h b/phpdbg_sigio_win32.h index b724eaeeb5e..796b477f936 100644 --- a/phpdbg_sigio_win32.h +++ b/phpdbg_sigio_win32.h @@ -21,10 +21,16 @@ #define PHPDBG_SIGIO_WIN32_H #include "phpdbg.h" +#include "phpdbg_prompt.h" +#include "phpdbg_io.h" struct win32_sigio_watcher_data { + zend_ulong flags; +#ifdef ZTS + void ***tsrm_ls; +#endif int fd; - zend_uchar signaled; + zend_uchar running; }; void From 55936dc23d7adabb90c5cec06ac1eaf8e294f82b Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 09:55:22 +0200 Subject: [PATCH 101/125] correct place to start the sigio watcher plus started with the eol command --- phpdbg.c | 2 ++ phpdbg.h | 4 +--- phpdbg_prompt.c | 16 +++++++++++----- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index cd84aff6b10..0eb07bce0ca 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -93,6 +93,8 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->sigio_watcher_thread = INVALID_HANDLE_VALUE; memset(&pg->swd, 0, sizeof(struct win32_sigio_watcher_data)); #endif + + pg->eol = "\n"; } /* }}} */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ diff --git a/phpdbg.h b/phpdbg.h index 09dc079ad88..41124eada36 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -114,9 +114,6 @@ #include "phpdbg_watch.h" #ifdef PHP_WIN32 # include "phpdbg_sigio_win32.h" -#else -# define sigio_watcher_start() -# define sigio_watcher_stop() #endif int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); @@ -289,6 +286,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HANDLE sigio_watcher_thread; /* sigio watcher thread handle */ struct win32_sigio_watcher_data swd; #endif + char *eol; ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ #endif diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 45f7b14d084..39d474cd7b9 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -83,6 +83,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0, PHPDBG_ASYNC_SAFE), PHPDBG_COMMAND_D(wait, "wait for other process", 'W', NULL, 0, 0), PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss", 0), + //PHPDBG_COMMAND_D(eol, "set eol", 'E', NULL, "|s", 0), PHPDBG_END_COMMAND }; /* }}} */ @@ -579,8 +580,6 @@ PHPDBG_COMMAND(run) /* {{{ */ zend_bool restore = 1; zend_execute_data *ex = EG(current_execute_data); - sigio_watcher_start(); - if (!PHPDBG_G(ops)) { if (phpdbg_compile(TSRMLS_C) == FAILURE) { phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec)); @@ -637,7 +636,6 @@ PHPDBG_COMMAND(run) /* {{{ */ zend_execute(EG(active_op_array) TSRMLS_CC); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; phpdbg_notice("stop", "type=\"normal\"", "Script ended normally"); - sigio_watcher_stop(); } zend_catch { EG(active_op_array) = orig_op_array; EG(opline_ptr) = orig_opline; @@ -647,7 +645,6 @@ PHPDBG_COMMAND(run) /* {{{ */ phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM"); restore = 0; } - sigio_watcher_stop(); } zend_end_try(); if (PHPDBG_G(socket_fd) != -1) { @@ -669,7 +666,6 @@ PHPDBG_COMMAND(run) /* {{{ */ } out: - sigio_watcher_stop(); PHPDBG_FRAME(num) = 0; return SUCCESS; } /* }}} */ @@ -1208,6 +1204,11 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */ if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { phpdbg_activate_err_buf(1 TSRMLS_CC); +#ifdef PHP_WIN32 + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { + sigio_watcher_start(); + } +#endif switch (ret = phpdbg_stack_execute(&stack, allow_async_unsafe TSRMLS_CC)) { case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { @@ -1232,6 +1233,11 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */ phpdbg_activate_err_buf(0 TSRMLS_CC); phpdbg_free_err_buf(TSRMLS_C); +#ifdef PHP_WIN32 + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { + sigio_watcher_stop(); + } +#endif } phpdbg_stack_free(&stack); From e011f0ca60a7d4d062b559dbbf7cfabef8f7a75b Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 10:35:20 +0200 Subject: [PATCH 102/125] prepare setting EOL with command or INI --- phpdbg.c | 22 ++++++++++++++++++++++ phpdbg_prompt.c | 25 ++++++++++++++++++++++++- phpdbg_prompt.h | 1 + 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/phpdbg.c b/phpdbg.c index 0eb07bce0ca..1133cd9f425 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -45,8 +45,30 @@ ZEND_DECLARE_MODULE_GLOBALS(phpdbg); +static PHP_INI_MH(OnUpdateEol) +{ + if (!new_value) { + return FAILURE; + } + + if (0 == strcmp(new_value, "CRLF", 4) || 0 == strcmp(new_value, "crlf", 4)) { + PHPDBG_G(eol) = "\r\n"; + } else if (0 == strcmp(new_value, "LF", 2) || 0 == strcmp(new_value, "lf", 4)) { + PHPDBG_G(eol) = "\n"; + } else if (0 == strcmp(new_value, "CR", 2) || 0 == strcmp(new_value, "cr", 4)) { + PHPDBG_G(eol) = "\r"; + } else if (0 == strcmp(new_value, "LFCR", 4) || 0 == strcmp(new_value, "lfcr", 4)) { + PHPDBG_G(eol) = "\n\r"; + } else { + return FAILURE; + } + + return SUCCESS; +} + PHP_INI_BEGIN() STD_PHP_INI_ENTRY("phpdbg.path", "", PHP_INI_SYSTEM | PHP_INI_PERDIR, OnUpdateString, socket_path, zend_phpdbg_globals, phpdbg_globals) + STD_PHP_INI_ENTRY("phpdbg.eol", "lf", PHP_INI_ALL, OnUpdateEol, socket_path, zend_phpdbg_globals, phpdbg_globals) PHP_INI_END() static zend_bool phpdbg_booted = 0; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 39d474cd7b9..387054f0d07 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -83,7 +83,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0, PHPDBG_ASYNC_SAFE), PHPDBG_COMMAND_D(wait, "wait for other process", 'W', NULL, 0, 0), PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss", 0), - //PHPDBG_COMMAND_D(eol, "set eol", 'E', NULL, "|s", 0), + PHPDBG_COMMAND_D(eol, "set eol", 'E', NULL, "|s", 0), PHPDBG_END_COMMAND }; /* }}} */ @@ -1563,3 +1563,26 @@ next: zend_bailout(); } } + +PHPDBG_COMMAND(eol) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + //phpdbg_notice("eol", "variable=\"%.*s\"", "Set watchpoint on %.*s", (int) param->len, param->str); + phpdbg_notice("eol", "argument required, supported crlf, lfcr, lf, cr", "argument required, supported crlf, lfcr, lf, cr"); + } else switch (param->type) { + case STR_PARAM: + if (0 == strcmp(param->str, "CRLF", 4) || 0 == strcmp(param->str, "crlf", 4)) { + PHPDBG_G(eol) = "\r\n"; + } else if (0 == strcmp(param->str, "LF", 2) || 0 == strcmp(param->str, "lf", 4)) { + PHPDBG_G(eol) = "\n"; + } else if (0 == strcmp(param->str, "CR", 2) || 0 == strcmp(param->str, "cr", 4)) { + PHPDBG_G(eol) = "\r"; + } else if (0 == strcmp(param->str, "LFCR", 4) || 0 == strcmp(param->str, "lfcr", 4)) { + PHPDBG_G(eol) = "\n\r"; + } + break; + + phpdbg_default_switch_case(); + } +} /* }}} */ + diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 314f7110784..94e24df8334 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -56,6 +56,7 @@ PHPDBG_COMMAND(export); PHPDBG_COMMAND(register); PHPDBG_COMMAND(quit); PHPDBG_COMMAND(watch); +PHPDBG_COMMAND(eol); PHPDBG_COMMAND(wait); /* }}} */ /* {{{ prompt commands */ From 63a450281ae5d2e22cf5c28357f230f704905cb3 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 11:29:18 +0200 Subject: [PATCH 103/125] reworked the current EOL stuff --- config.m4 | 2 +- config.w32 | 2 +- phpdbg.c | 19 ++++--------------- phpdbg.h | 2 +- phpdbg_prompt.c | 13 +++---------- 5 files changed, 10 insertions(+), 28 deletions(-) diff --git a/config.m4 b/config.m4 index 3bedc3cad99..3f24e303dec 100644 --- a/config.m4 +++ b/config.m4 @@ -33,7 +33,7 @@ if test "$BUILD_PHPDBG" == "" && test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c phpdbg_eol.c" if test "$PHP_READLINE" != "no" -o "$PHP_LIBEDIT" != "no"; then PHPDBG_EXTRA_LIBS="$PHP_READLINE_LIBS" diff --git a/config.w32 b/config.w32 index 40a593331dd..3f4639399be 100644 --- a/config.w32 +++ b/config.w32 @@ -5,7 +5,7 @@ PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help. 'phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c ' + 'phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c '+ 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c ' + - 'phpdbg_sigio_win32.c'; + 'phpdbg_sigio_win32.c phpdbg_eol.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; diff --git a/phpdbg.c b/phpdbg.c index 1133cd9f425..8686dcd1c36 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -30,6 +30,7 @@ #include "phpdbg_set.h" #include "phpdbg_io.h" #include "zend_alloc.h" +#include "phpdbg_eol.h" /* {{{ remote console headers */ #ifndef _WIN32 @@ -51,24 +52,12 @@ static PHP_INI_MH(OnUpdateEol) return FAILURE; } - if (0 == strcmp(new_value, "CRLF", 4) || 0 == strcmp(new_value, "crlf", 4)) { - PHPDBG_G(eol) = "\r\n"; - } else if (0 == strcmp(new_value, "LF", 2) || 0 == strcmp(new_value, "lf", 4)) { - PHPDBG_G(eol) = "\n"; - } else if (0 == strcmp(new_value, "CR", 2) || 0 == strcmp(new_value, "cr", 4)) { - PHPDBG_G(eol) = "\r"; - } else if (0 == strcmp(new_value, "LFCR", 4) || 0 == strcmp(new_value, "lfcr", 4)) { - PHPDBG_G(eol) = "\n\r"; - } else { - return FAILURE; - } - - return SUCCESS; + return phpdbg_update_eol_global(new_value TSRMLS_CC); } PHP_INI_BEGIN() STD_PHP_INI_ENTRY("phpdbg.path", "", PHP_INI_SYSTEM | PHP_INI_PERDIR, OnUpdateString, socket_path, zend_phpdbg_globals, phpdbg_globals) - STD_PHP_INI_ENTRY("phpdbg.eol", "lf", PHP_INI_ALL, OnUpdateEol, socket_path, zend_phpdbg_globals, phpdbg_globals) + STD_PHP_INI_ENTRY("phpdbg.eol", "2", PHP_INI_ALL, OnUpdateEol, socket_path, zend_phpdbg_globals, phpdbg_globals) PHP_INI_END() static zend_bool phpdbg_booted = 0; @@ -116,7 +105,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ memset(&pg->swd, 0, sizeof(struct win32_sigio_watcher_data)); #endif - pg->eol = "\n"; + pg->eol = PHPDBG_EOL_LF; } /* }}} */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ diff --git a/phpdbg.h b/phpdbg.h index 41124eada36..b7346ab8bf2 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -286,7 +286,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HANDLE sigio_watcher_thread; /* sigio watcher thread handle */ struct win32_sigio_watcher_data swd; #endif - char *eol; + int8_t eol; ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ #endif diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 387054f0d07..20de859f035 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -83,7 +83,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0, PHPDBG_ASYNC_SAFE), PHPDBG_COMMAND_D(wait, "wait for other process", 'W', NULL, 0, 0), PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss", 0), - PHPDBG_COMMAND_D(eol, "set eol", 'E', NULL, "|s", 0), + PHPDBG_COMMAND_D(eol, "set EOL", 'E', NULL, "|s", 0), PHPDBG_END_COMMAND }; /* }}} */ @@ -1567,18 +1567,11 @@ next: PHPDBG_COMMAND(eol) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - //phpdbg_notice("eol", "variable=\"%.*s\"", "Set watchpoint on %.*s", (int) param->len, param->str); phpdbg_notice("eol", "argument required, supported crlf, lfcr, lf, cr", "argument required, supported crlf, lfcr, lf, cr"); } else switch (param->type) { case STR_PARAM: - if (0 == strcmp(param->str, "CRLF", 4) || 0 == strcmp(param->str, "crlf", 4)) { - PHPDBG_G(eol) = "\r\n"; - } else if (0 == strcmp(param->str, "LF", 2) || 0 == strcmp(param->str, "lf", 4)) { - PHPDBG_G(eol) = "\n"; - } else if (0 == strcmp(param->str, "CR", 2) || 0 == strcmp(param->str, "cr", 4)) { - PHPDBG_G(eol) = "\r"; - } else if (0 == strcmp(param->str, "LFCR", 4) || 0 == strcmp(param->str, "lfcr", 4)) { - PHPDBG_G(eol) = "\n\r"; + if (FAILURE == phpdbg_update_eol_global(param->str TSRMLS_CC)) { + phpdbg_notice("eol", "unknown EOL name '%s', give crlf, lfcr, lf, cr", "unknown EOL name '%s', give crlf, lfcr, lf, cr", param->str); } break; From 0f3448ef8bf7364e137ac52160c202e442bd4e52 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 11:46:32 +0200 Subject: [PATCH 104/125] start sigio watcher only for run and eval for now there myght be more needing that --- phpdbg_prompt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 20de859f035..d72b1d5aa11 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -39,6 +39,7 @@ #include "phpdbg_lexer.h" #include "phpdbg_parser.h" #include "phpdbg_wait.h" +#include "phpdbg_eol.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -1205,7 +1206,8 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */ phpdbg_activate_err_buf(1 TSRMLS_CC); #ifdef PHP_WIN32 - if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { +#define PARA ((phpdbg_param_t *)stack.next)->type + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) { sigio_watcher_start(); } #endif @@ -1234,9 +1236,10 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */ phpdbg_activate_err_buf(0 TSRMLS_CC); phpdbg_free_err_buf(TSRMLS_C); #ifdef PHP_WIN32 - if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) { sigio_watcher_stop(); } +#undef PARA #endif } @@ -1577,5 +1580,7 @@ PHPDBG_COMMAND(eol) /* {{{ */ phpdbg_default_switch_case(); } + + return SUCCESS; } /* }}} */ From a741d3b266a6b6bfa668172d05f0f7460cf7ba00 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 15:50:55 +0200 Subject: [PATCH 105/125] basic EOL implementation for CRLF --- phpdbg.c | 2 +- phpdbg_help.c | 1 + phpdbg_prompt.c | 4 ++-- phpdbg_utils.c | 4 ++++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 8686dcd1c36..88313585b56 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -52,7 +52,7 @@ static PHP_INI_MH(OnUpdateEol) return FAILURE; } - return phpdbg_update_eol_global(new_value TSRMLS_CC); + return phpdbg_eol_global_update(new_value TSRMLS_CC); } PHP_INI_BEGIN() diff --git a/phpdbg_help.c b/phpdbg_help.c index 8a7084bb5ae..652e1706942 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -22,6 +22,7 @@ #include "phpdbg.h" #include "phpdbg_help.h" #include "phpdbg_prompt.h" +#include "phpdbg_eol.h" #include "zend.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index d72b1d5aa11..7b09821c77e 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1570,10 +1570,10 @@ next: PHPDBG_COMMAND(eol) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_notice("eol", "argument required, supported crlf, lfcr, lf, cr", "argument required, supported crlf, lfcr, lf, cr"); + phpdbg_notice("eol", "argument required", "argument required"); } else switch (param->type) { case STR_PARAM: - if (FAILURE == phpdbg_update_eol_global(param->str TSRMLS_CC)) { + if (FAILURE == phpdbg_eol_global_update(param->str TSRMLS_CC)) { phpdbg_notice("eol", "unknown EOL name '%s', give crlf, lfcr, lf, cr", "unknown EOL name '%s', give crlf, lfcr, lf, cr", param->str); } break; diff --git a/phpdbg_utils.c b/phpdbg_utils.c index ecdb5fbfea3..e1aeef2b4ba 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1269,9 +1269,11 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m } phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen); + phpdbg_eol_convert(&xmlout, &xmloutlen TSRMLS_CC); phpdbg_mixed_write(fd, xmlout, xmloutlen TSRMLS_CC); efree(xmlout); } else if (msgout) { + phpdbg_eol_convert(&msgout, &msgoutlen TSRMLS_CC); phpdbg_mixed_write(fd, msgout, msgoutlen TSRMLS_CC); } @@ -1443,6 +1445,7 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { msglen = phpdbg_encode_xml(&msg, buffer, buflen, 256, NULL); phpdbg_encode_ctrl_chars(&msg, &msglen); + phpdbg_eol_convert(&msg, &msglen TSRMLS_CC); if (PHPDBG_G(in_script_xml)) { phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); @@ -1453,6 +1456,7 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { len = phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC); phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); } else { + phpdbg_eol_convert(&buffer, &buflen TSRMLS_CC); len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); } From 6fcf7ede49880f67026b781bb55ee42d775aecce Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 16:18:44 +0200 Subject: [PATCH 106/125] added phpdbg_eol.* sources --- phpdbg_eol.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_eol.h | 50 ++++++++++++++ 2 files changed, 229 insertions(+) create mode 100644 phpdbg_eol.c create mode 100644 phpdbg_eol.h diff --git a/phpdbg_eol.c b/phpdbg_eol.c new file mode 100644 index 00000000000..27a0d120428 --- /dev/null +++ b/phpdbg_eol.c @@ -0,0 +1,179 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 7-4 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Anatol Belski | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "phpdbg.h" +#include "phpdbg_eol.h" + + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +#define EOL_LIST_LEN 4 +struct phpdbg_eol_rep phpdbg_eol_list[EOL_LIST_LEN] = { + {"CRLF", "\r\n", PHPDBG_EOL_CRLF}, +/* {"LFCR", "\n\r", PHPDBG_EOL_LFCR},*/ + {"LF", "\n", PHPDBG_EOL_LF}, + {"CR", "\r", PHPDBG_EOL_CR}, +}; + +int8_t +phpdbg_eol_global_update(char *name TSRMLS_DC) +{ + + if (0 == memcmp(name, "CRLF", 4) || 0 == memcmp(name, "crlf", 4) || 0 == memcmp(name, "DOS", 3) || 0 == memcmp(name, "dos", 3)) { + PHPDBG_G(eol) = PHPDBG_EOL_CRLF; + } else if (0 == memcmp(name, "LF", 2) || 0 == memcmp(name, "lf", 2) || 0 == memcmp(name, "UNIX", 4) || 0 == memcmp(name, "unix", 4)) { + PHPDBG_G(eol) = PHPDBG_EOL_LF; + } else if (0 == memcmp(name, "CR", 2) || 0 == memcmp(name, "cr", 2) || 0 == memcmp(name, "MAC", 3) || 0 == memcmp(name, "mac", 3)) { + PHPDBG_G(eol) = PHPDBG_EOL_CR; + } else { + return FAILURE; + } + + return SUCCESS; +} + +char * +phpdbg_eol_name(int8_t id) +{ + size_t i = 0; + + while (i < EOL_LIST_LEN) { + + if (id == phpdbg_eol_list[i].id) { + return phpdbg_eol_list[i].name; + } + + i++; + } + + return NULL; +} + +char * +phpdbg_eol_rep(int8_t id) +{ + size_t i = 0; + + while (i < EOL_LIST_LEN) { + + if (id == phpdbg_eol_list[i].id) { + return phpdbg_eol_list[i].rep; + } + + i++; + } + + return NULL; +} + + +void +phpdbg_eol_convert(char **str, int *len TSRMLS_DC) +{ + char *in = *str, *out ; + int in_len = *len, out_len, cursor, i; + char last, cur; + + if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) != PHPDBG_IS_REMOTE) { + return; + } + + out_len = *len; + if (PHPDBG_EOL_CRLF == PHPDBG_G(eol)) { /* XXX add LFCR case if it's gonna be needed */ + /* depending on the source EOL the out str will have all CR/LF duplicated */ + for (i = 0; i < in_len; i++) { + if (0x0a == in[i] || 0x0d == in[i]) { + out_len++; + } + } + out = (char *)emalloc(out_len); + + last = cur = in[0]; + i = cursor = 0; + for (; i < in_len;) { + if (0x0a == cur && last != 0x0d) { + out[cursor] = 0x0d; + cursor++; + out[cursor] = cur; + } else if(0x0d == cur) { + if (i + 1 < in_len && 0x0a != in[i+1]) { + out[cursor] = cur; + cursor++; + out[cursor] = 0x0a; + last = 0x0a; + } else { + out[cursor] = 0x0d; + last = 0x0d; + } + } else { + out[cursor] = cur; + last = cur; + } + + i++; + cursor++; + cur = in[i]; + } + + } else if (PHPDBG_EOL_LF == PHPDBG_G(eol) || PHPDBG_EOL_CR == PHPDBG_G(eol)) { + char want, kick; + + if (PHPDBG_EOL_LF == PHPDBG_G(eol)) { + want = 0x0a; + kick = 0x0d; + } else { + want = 0x0d; + kick = 0x0a; + } + + /* We gonna have a smaller or equally long string, estimation is almost neglecting */ + out = (char *)emalloc(out_len); + + last = cur = in[0]; + i = cursor = 0; + for (; cursor < in_len;) { + if (kick == cur) { + out[cursor] = want; + } else if (want == cur) { + if (kick != last) { + out[cursor] = want; + } + } else { + out[cursor] = cur; + } + + last = cur; + cursor++; + cur = in[cursor]; + } + } else { + return; + } + + efree(*str); + *str = erealloc(out, cursor); + *len = cursor; + in = NULL; +} + + + diff --git a/phpdbg_eol.h b/phpdbg_eol.h new file mode 100644 index 00000000000..5c499fc924a --- /dev/null +++ b/phpdbg_eol.h @@ -0,0 +1,50 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 7-4 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Anatol Belski | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_EOL_H +#define PHPDBG_EOL_H + +#include "phpdbg.h" + +struct phpdbg_eol_rep { + char *name; + char *rep; + int8_t id; +}; + +enum { + PHPDBG_EOL_CRLF, /* DOS */ + /*PHPDBG_EOL_LFCR,*/ /* for Risc OS? */ + PHPDBG_EOL_LF, /* UNIX */ + PHPDBG_EOL_CR /* MAC */ +}; + +int8_t +phpdbg_eol_global_update(char *name TSRMLS_DC); + +char * +phpdbg_eol_name(int8_t id); + +char * +phpdbg_eol_rep(int8_t id); + +void +phpdbg_eol_convert(char **str, int *len TSRMLS_DC); + +#endif /* PHPDBG_EOL_H */ + From b8368a7bcf2490ff119dcc2dafab8787e766efd4 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 16:19:31 +0200 Subject: [PATCH 107/125] some minor fixes --- phpdbg_prompt.c | 2 +- phpdbg_utils.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 7b09821c77e..6611e8b8f46 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1574,7 +1574,7 @@ PHPDBG_COMMAND(eol) /* {{{ */ } else switch (param->type) { case STR_PARAM: if (FAILURE == phpdbg_eol_global_update(param->str TSRMLS_CC)) { - phpdbg_notice("eol", "unknown EOL name '%s', give crlf, lfcr, lf, cr", "unknown EOL name '%s', give crlf, lfcr, lf, cr", param->str); + phpdbg_notice("eol", "unknown EOL name '%s', give crlf, lf, cr", "unknown EOL name '%s', give crlf, lf, cr", param->str); } break; diff --git a/phpdbg_utils.c b/phpdbg_utils.c index e1aeef2b4ba..76f870df7dd 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -28,6 +28,7 @@ #include "phpdbg_opcode.h" #include "phpdbg_io.h" #include "phpdbg_utils.h" +#include "phpdbg_eol.h" #include "ext/standard/html.h" #ifdef _WIN32 From d7229b2bb6f420d86a07165876179bcdbaa6a9cf Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 16:56:06 +0200 Subject: [PATCH 108/125] restart listening on socket if remote sent somthing else than ctrl+c while performing something blocking --- phpdbg_sigio_win32.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpdbg_sigio_win32.c b/phpdbg_sigio_win32.c index b10f2a352cc..24e9ac0e0aa 100644 --- a/phpdbg_sigio_win32.c +++ b/phpdbg_sigio_win32.c @@ -33,8 +33,10 @@ SigIoWatcherThread(VOID *p) struct win32_sigio_watcher_data *swd = (struct win32_sigio_watcher_data *)p; #ifdef ZTS void ***tsrm_ls = swd->tsrm_ls; +top: (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1, tsrm_ls); #else +top: (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1); #endif @@ -57,6 +59,8 @@ SigIoWatcherThread(VOID *p) } /* XXX set signaled flag to the caller thread, question is - whether it's needed */ ExitThread(sig); + } else { + goto top; } } From 242387e51b389fb5ae98e003c9a51166420bbbb8 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Oct 2014 17:43:23 +0200 Subject: [PATCH 109/125] add comment --- phpdbg_eol.c | 1 + 1 file changed, 1 insertion(+) diff --git a/phpdbg_eol.c b/phpdbg_eol.c index 27a0d120428..f2946cb68b8 100644 --- a/phpdbg_eol.c +++ b/phpdbg_eol.c @@ -86,6 +86,7 @@ phpdbg_eol_rep(int8_t id) } +/* Inspired by https://ccrma.stanford.edu/~craig/utility/flip/flip.cpp */ void phpdbg_eol_convert(char **str, int *len TSRMLS_DC) { From 801080cf7ef1ed333e97741e6a002bc5a2636fed Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 22 Oct 2014 19:58:52 +0200 Subject: [PATCH 110/125] Try fixing 5.4 and 5.5 build, again --- phpdbg.h | 3 +++ phpdbg_prompt.c | 2 +- phpdbg_utils.c | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/phpdbg.h b/phpdbg.h index b7346ab8bf2..ce90c6a95e0 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -29,6 +29,8 @@ # define PHPDBG_API #endif +#include +#include #include "php.h" #include "php_globals.h" #include "php_variables.h" @@ -48,6 +50,7 @@ #if defined(_WIN32) && !defined(__MINGW32__) # include # include "config.w32.h" +# include "win32/php_stdint.h" # undef strcasecmp # undef strncasecmp # define strcasecmp _stricmp diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 6611e8b8f46..6c78ec6d130 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -557,7 +557,7 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ zval_ptr_dtor(&trace); } else { - phpdbg_error("exception", "name=\"%s\"" "Uncaught %s!", Z_OBJCE(exception)->name); + phpdbg_error("exception", "name=\"%s\"", "Uncaught %s!", Z_OBJCE(exception)->name); } /* output useful information about address */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 76f870df7dd..69dc7d12d4c 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -1227,7 +1227,11 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m efree(stream_buf); PHPDBG_G(in_script_xml) = type; } +#if PHP_VERSION_ID >= 50600 buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); +#else + buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, SG(default_charset) ? SG(default_charset) : "UTF-8" TSRMLS_CC); +#endif phpdbg_encode_ctrl_chars(&buf, &buflen); phpdbg_mixed_write(fd, buf, buflen TSRMLS_CC); efree(buf); From d61a12799cb50974cc6beac7eb61adfa3ceaae73 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 23 Oct 2014 12:23:48 +0200 Subject: [PATCH 111/125] Do not display dots in xml output for i v/i d --- phpdbg_info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_info.c b/phpdbg_info.c index 74352878a02..d523968dca2 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -133,7 +133,7 @@ PHPDBG_INFO(constants) /* {{{ */ switch (Z_TYPE(data->value)) { case IS_STRING: phpdbg_try_access { - VARIABLEINFO("length=\"%d\" value=\"%.*s%s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN(data->value), Z_STRLEN(data->value) < 255 ? Z_STRLEN(data->value) : 255, Z_STRVAL(data->value), Z_STRLEN(data->value) > 255 ? "..." : ""); + VARIABLEINFO("length=\"%d\" value=\"%.*s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN(data->value), Z_STRLEN(data->value) < 255 ? Z_STRLEN(data->value) : 255, Z_STRVAL(data->value), Z_STRLEN(data->value) > 255 ? "..." : ""); } phpdbg_catch_access { VARIABLEINFO("", ""); } phpdbg_end_try_access(); @@ -266,7 +266,7 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) { break; case IS_STRING: phpdbg_try_access { - VARIABLEINFO("length=\"%d\" value=\"%.*s%s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN_PP(data), Z_STRLEN_PP(data) < 255 ? Z_STRLEN_PP(data) : 255, Z_STRVAL_PP(data), Z_STRLEN_PP(data) > 255 ? "..." : ""); + VARIABLEINFO("length=\"%d\" value=\"%.*s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN_PP(data), Z_STRLEN_PP(data) < 255 ? Z_STRLEN_PP(data) : 255, Z_STRVAL_PP(data), Z_STRLEN_PP(data) > 255 ? "..." : ""); } phpdbg_catch_access { VARIABLEINFO("", ""); } phpdbg_end_try_access(); From 504448bce3e76a559d5fb15395db92fb0a15c490 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 23 Oct 2014 12:38:35 +0200 Subject: [PATCH 112/125] Fixed frame numbering in xml output --- phpdbg_frame.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 8baaf771906..df304e35411 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -225,10 +225,11 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ } if (user_defined == SUCCESS) { - phpdbg_out("frame #%d: ", i++); + phpdbg_out("frame #%d: ", i); phpdbg_xml(" "); phpdbg_xml(" Date: Thu, 23 Oct 2014 13:02:50 +0200 Subject: [PATCH 113/125] Do not use int8_t when it is useless... --- phpdbg_eol.c | 20 ++++++-------------- phpdbg_eol.h | 16 ++++++---------- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/phpdbg_eol.c b/phpdbg_eol.c index f2946cb68b8..fc20d567bc6 100644 --- a/phpdbg_eol.c +++ b/phpdbg_eol.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 7-4 The PHP Group | + | Copyright (c) 1997-2014 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 | @@ -17,13 +17,12 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif #include "phpdbg.h" #include "phpdbg_eol.h" - ZEND_EXTERN_MODULE_GLOBALS(phpdbg); #define EOL_LIST_LEN 4 @@ -34,8 +33,7 @@ struct phpdbg_eol_rep phpdbg_eol_list[EOL_LIST_LEN] = { {"CR", "\r", PHPDBG_EOL_CR}, }; -int8_t -phpdbg_eol_global_update(char *name TSRMLS_DC) +int phpdbg_eol_global_update(char *name TSRMLS_DC) { if (0 == memcmp(name, "CRLF", 4) || 0 == memcmp(name, "crlf", 4) || 0 == memcmp(name, "DOS", 3) || 0 == memcmp(name, "dos", 3)) { @@ -51,8 +49,7 @@ phpdbg_eol_global_update(char *name TSRMLS_DC) return SUCCESS; } -char * -phpdbg_eol_name(int8_t id) +char *phpdbg_eol_name(int id) { size_t i = 0; @@ -68,8 +65,7 @@ phpdbg_eol_name(int8_t id) return NULL; } -char * -phpdbg_eol_rep(int8_t id) +char *phpdbg_eol_rep(int id) { size_t i = 0; @@ -87,8 +83,7 @@ phpdbg_eol_rep(int8_t id) /* Inspired by https://ccrma.stanford.edu/~craig/utility/flip/flip.cpp */ -void -phpdbg_eol_convert(char **str, int *len TSRMLS_DC) +void phpdbg_eol_convert(char **str, int *len TSRMLS_DC) { char *in = *str, *out ; int in_len = *len, out_len, cursor, i; @@ -175,6 +170,3 @@ phpdbg_eol_convert(char **str, int *len TSRMLS_DC) *len = cursor; in = NULL; } - - - diff --git a/phpdbg_eol.h b/phpdbg_eol.h index 5c499fc924a..68b54cbe343 100644 --- a/phpdbg_eol.h +++ b/phpdbg_eol.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 7-4 The PHP Group | + | Copyright (c) 1997-2014 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 | @@ -24,7 +24,7 @@ struct phpdbg_eol_rep { char *name; char *rep; - int8_t id; + int id; }; enum { @@ -34,17 +34,13 @@ enum { PHPDBG_EOL_CR /* MAC */ }; -int8_t -phpdbg_eol_global_update(char *name TSRMLS_DC); +int phpdbg_eol_global_update(char *name TSRMLS_DC); -char * -phpdbg_eol_name(int8_t id); +char *phpdbg_eol_name(int id); -char * -phpdbg_eol_rep(int8_t id); +char *phpdbg_eol_rep(int id); -void -phpdbg_eol_convert(char **str, int *len TSRMLS_DC); +void phpdbg_eol_convert(char **str, int *len TSRMLS_DC); #endif /* PHPDBG_EOL_H */ From 6ee2dc47f3313c05d00fedfc49837622dacd6963 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 23 Oct 2014 13:16:00 +0200 Subject: [PATCH 114/125] Move phpdbg_print and helper functions to phpdbg_out.* --- config.m4 | 2 +- config.w32 | 2 +- phpdbg.h | 3 +- phpdbg_out.c | 1305 ++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_out.h | 89 ++++ phpdbg_utils.c | 1287 +---------------------------------------------- phpdbg_utils.h | 58 --- 7 files changed, 1399 insertions(+), 1347 deletions(-) create mode 100644 phpdbg_out.c create mode 100644 phpdbg_out.h diff --git a/config.m4 b/config.m4 index 3f24e303dec..528abb5822b 100644 --- a/config.m4 +++ b/config.m4 @@ -33,7 +33,7 @@ if test "$BUILD_PHPDBG" == "" && test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c phpdbg_eol.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c phpdbg_eol.c phpdbg_out.c" if test "$PHP_READLINE" != "no" -o "$PHP_LIBEDIT" != "no"; then PHPDBG_EXTRA_LIBS="$PHP_READLINE_LIBS" diff --git a/config.w32 b/config.w32 index 3f4639399be..6f0bd8f8113 100644 --- a/config.w32 +++ b/config.w32 @@ -5,7 +5,7 @@ PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help. 'phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c ' + 'phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c '+ 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c ' + - 'phpdbg_sigio_win32.c phpdbg_eol.c'; + 'phpdbg_sigio_win32.c phpdbg_eol.c phpdbg_out.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; diff --git a/phpdbg.h b/phpdbg.h index ce90c6a95e0..8c0dbb4afa0 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 7-4 The PHP Group | + | Copyright (c) 1997-2014 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 | @@ -110,6 +110,7 @@ #endif #include "phpdbg_sigsafe.h" +#include "phpdbg_out.h" #include "phpdbg_lexer.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" diff --git a/phpdbg_out.c b/phpdbg_out.c new file mode 100644 index 00000000000..a4793f144f6 --- /dev/null +++ b/phpdbg_out.c @@ -0,0 +1,1305 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "php.h" +#include "spprintf.h" +#include "phpdbg.h" +#include "phpdbg_io.h" +#include "phpdbg_eol.h" +#include "ext/standard/html.h" + +#ifdef _WIN32 +# include "win32/time.h" +#endif + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +/* copied from php-src/main/snprintf.c and slightly modified */ +/* + * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions + * + * XXX: this is a magic number; do not decrease it + * Emax = 1023 + * NDIG = 320 + * NUM_BUF_SIZE >= strlen("-") + Emax + strlrn(".") + NDIG + strlen("E+1023") + 1; + */ +#define NUM_BUF_SIZE 2048 + +/* + * Descriptor for buffer area + */ +struct buf_area { + char *buf_end; + char *nextb; /* pointer to next byte to read/write */ +}; + +typedef struct buf_area buffy; + +/* + * The INS_CHAR macro inserts a character in the buffer and writes + * the buffer back to disk if necessary + * It uses the char pointers sp and bep: + * sp points to the next available character in the buffer + * bep points to the end-of-buffer+1 + * While using this macro, note that the nextb pointer is NOT updated. + * + * NOTE: Evaluation of the c argument should not have any side-effects + */ +#define INS_CHAR(c, sp, bep, cc) \ + { \ + if (sp < bep) \ + { \ + *sp++ = c; \ + } \ + cc++; \ + } + +#define NUM( c ) ( c - '0' ) + +#define STR_TO_DEC( str, num ) \ + num = NUM( *str++ ) ; \ + while ( isdigit((int)*str ) ) \ + { \ + num *= 10 ; \ + num += NUM( *str++ ) ; \ + } + +/* + * This macro does zero padding so that the precision + * requirement is satisfied. The padding is done by + * adding '0's to the left of the string that is going + * to be printed. + */ +#define FIX_PRECISION( adjust, precision, s, s_len ) \ + if ( adjust ) \ + while ( s_len < precision ) \ + { \ + *--s = '0' ; \ + s_len++ ; \ + } + +/* + * Macro that does padding. The padding is done by printing + * the character ch. + */ +#define PAD( width, len, ch ) do \ + { \ + INS_CHAR( ch, sp, bep, cc ) ; \ + width-- ; \ + } \ + while ( width > len ) + +/* + * Prefix the character ch to the string str + * Increase length + * Set the has_prefix flag + */ +#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES + + +#ifdef HAVE_LOCALE_H +#include +#define LCONV_DECIMAL_POINT (*lconv->decimal_point) +#else +#define LCONV_DECIMAL_POINT '.' +#endif +#define NUL '\0' +#define S_NULL "(null)" +#define S_NULL_LEN 6 +#define FLOAT_DIGITS 6 + +/* + * Do format conversion placing the output in buffer + */ +static int format_converter(register buffy *odp, const char *fmt, zend_bool escape_xml, va_list ap TSRMLS_DC) { + char *sp; + char *bep; + int cc = 0; + int i; + + char *s = NULL, *free_s = NULL; + int s_len, free_zcopy; + zval *zvp, zcopy; + + int min_width = 0; + int precision = 0; + enum { + LEFT, RIGHT + } adjust; + char pad_char; + char prefix_char; + + double fp_num; + wide_int i_num = (wide_int) 0; + u_wide_int ui_num; + + char num_buf[NUM_BUF_SIZE]; + char char_buf[2]; /* for printing %% and % */ + +#ifdef HAVE_LOCALE_H + struct lconv *lconv = NULL; +#endif + + /* + * Flag variables + */ + length_modifier_e modifier; + boolean_e alternate_form; + boolean_e print_sign; + boolean_e print_blank; + boolean_e adjust_precision; + boolean_e adjust_width; + bool_int is_negative; + + sp = odp->nextb; + bep = odp->buf_end; + + while (*fmt) { + if (*fmt != '%') { + INS_CHAR(*fmt, sp, bep, cc); + } else { + /* + * Default variable settings + */ + adjust = RIGHT; + alternate_form = print_sign = print_blank = NO; + pad_char = ' '; + prefix_char = NUL; + free_zcopy = 0; + + fmt++; + + /* + * Try to avoid checking for flags, width or precision + */ + if (isascii((int)*fmt) && !islower((int)*fmt)) { + /* + * Recognize flags: -, #, BLANK, + + */ + for (;; fmt++) { + if (*fmt == '-') + adjust = LEFT; + else if (*fmt == '+') + print_sign = YES; + else if (*fmt == '#') + alternate_form = YES; + else if (*fmt == ' ') + print_blank = YES; + else if (*fmt == '0') + pad_char = '0'; + else + break; + } + + /* + * Check if a width was specified + */ + if (isdigit((int)*fmt)) { + STR_TO_DEC(fmt, min_width); + adjust_width = YES; + } else if (*fmt == '*') { + min_width = va_arg(ap, int); + fmt++; + adjust_width = YES; + if (min_width < 0) { + adjust = LEFT; + min_width = -min_width; + } + } else + adjust_width = NO; + + /* + * Check if a precision was specified + */ + if (*fmt == '.') { + adjust_precision = YES; + fmt++; + if (isdigit((int)*fmt)) { + STR_TO_DEC(fmt, precision); + } else if (*fmt == '*') { + precision = va_arg(ap, int); + fmt++; + if (precision < 0) + precision = 0; + } else + precision = 0; + + if (precision > FORMAT_CONV_MAX_PRECISION && *fmt != 's' && *fmt != 'v' && *fmt != 'b') { + precision = FORMAT_CONV_MAX_PRECISION; + } + } else + adjust_precision = NO; + } else + adjust_precision = adjust_width = NO; + + /* + * Modifier check + */ + switch (*fmt) { + case 'L': + fmt++; + modifier = LM_LONG_DOUBLE; + break; + case 'I': + fmt++; +#if SIZEOF_LONG_LONG + if (*fmt == '6' && *(fmt+1) == '4') { + fmt += 2; + modifier = LM_LONG_LONG; + } else +#endif + if (*fmt == '3' && *(fmt+1) == '2') { + fmt += 2; + modifier = LM_LONG; + } else { +#ifdef _WIN64 + modifier = LM_LONG_LONG; +#else + modifier = LM_LONG; +#endif + } + break; + case 'l': + fmt++; +#if SIZEOF_LONG_LONG + if (*fmt == 'l') { + fmt++; + modifier = LM_LONG_LONG; + } else +#endif + modifier = LM_LONG; + break; + case 'z': + fmt++; + modifier = LM_SIZE_T; + break; + case 'j': + fmt++; +#if SIZEOF_INTMAX_T + modifier = LM_INTMAX_T; +#else + modifier = LM_SIZE_T; +#endif + break; + case 't': + fmt++; +#if SIZEOF_PTRDIFF_T + modifier = LM_PTRDIFF_T; +#else + modifier = LM_SIZE_T; +#endif + break; + case 'h': + fmt++; + if (*fmt == 'h') { + fmt++; + } + /* these are promoted to int, so no break */ + default: + modifier = LM_STD; + break; + } + + /* + * Argument extraction and printing. + * First we determine the argument type. + * Then, we convert the argument to a string. + * On exit from the switch, s points to the string that + * must be printed, s_len has the length of the string + * The precision requirements, if any, are reflected in s_len. + * + * NOTE: pad_char may be set to '0' because of the 0 flag. + * It is reset to ' ' by non-numeric formats + */ + switch (*fmt) { + case 'Z': + zvp = (zval*) va_arg(ap, zval*); + zend_make_printable_zval(zvp, &zcopy, &free_zcopy); + if (free_zcopy) { + zvp = &zcopy; + } + s_len = Z_STRLEN_P(zvp); + s = Z_STRVAL_P(zvp); + if (adjust_precision && precision < s_len) { + s_len = precision; + } + break; + case 'u': + switch(modifier) { + default: + i_num = (wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG_DOUBLE: + goto fmt_error; + case LM_LONG: + i_num = (wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + i_num = (wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + i_num = (wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + i_num = (wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + i_num = (wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + /* + * The rest also applies to other integer formats, so fall + * into that case. + */ + case 'd': + case 'i': + /* + * Get the arg if we haven't already. + */ + if ((*fmt) != 'u') { + switch(modifier) { + default: + i_num = (wide_int) va_arg(ap, int); + break; + case LM_LONG_DOUBLE: + goto fmt_error; + case LM_LONG: + i_num = (wide_int) va_arg(ap, long int); + break; + case LM_SIZE_T: +#if SIZEOF_SSIZE_T + i_num = (wide_int) va_arg(ap, ssize_t); +#else + i_num = (wide_int) va_arg(ap, size_t); +#endif + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + i_num = (wide_int) va_arg(ap, wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + i_num = (wide_int) va_arg(ap, intmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + i_num = (wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + } + s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + FIX_PRECISION(adjust_precision, precision, s, s_len); + + if (*fmt != 'u') { + if (is_negative) { + prefix_char = '-'; + } else if (print_sign) { + prefix_char = '+'; + } else if (print_blank) { + prefix_char = ' '; + } + } + break; + + + case 'o': + switch(modifier) { + default: + ui_num = (u_wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG_DOUBLE: + goto fmt_error; + case LM_LONG: + ui_num = (u_wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + ui_num = (u_wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + ui_num = (u_wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + s = ap_php_conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); + FIX_PRECISION(adjust_precision, precision, s, s_len); + if (alternate_form && *s != '0') { + *--s = '0'; + s_len++; + } + break; + + + case 'x': + case 'X': + switch(modifier) { + default: + ui_num = (u_wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG_DOUBLE: + goto fmt_error; + case LM_LONG: + ui_num = (u_wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + ui_num = (u_wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + ui_num = (u_wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + s = ap_php_conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); + FIX_PRECISION(adjust_precision, precision, s, s_len); + if (alternate_form && i_num != 0) { + *--s = *fmt; /* 'x' or 'X' */ + *--s = '0'; + s_len += 2; + } + break; + + + case 's': + case 'v': + s = va_arg(ap, char *); + if (s != NULL) { + if (adjust_precision) { + s_len = precision; + } else { + s_len = strlen(s); + } + + if (escape_xml) { + /* added: support for xml escaping */ + + int old_slen = s_len, i = 0; + char *old_s = s, *s_ptr; + free_s = s_ptr = s = emalloc(old_slen * 6 + 1); + do { + if (old_s[i] == '&' || old_s[i] == '"' || old_s[i] == '<') { + *s_ptr++ = '&'; + switch (old_s[i]) { + case '"': + s_len += 5; + *s_ptr++ = 'q'; + *s_ptr++ = 'u'; + *s_ptr++ = 'o'; + *s_ptr++ = 't'; + break; + case '<': + s_len += 3; + *s_ptr++ = 'l'; + *s_ptr++ = 't'; + break; + case '&': + s_len += 4; + *s_ptr++ = 'a'; + *s_ptr++ = 'm'; + *s_ptr++ = 'p'; + break; + } + *s_ptr++ = ';'; + } else { + *s_ptr++ = old_s[i]; + } + } while (i++ < old_slen); + } + } else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + break; + + + case 'b': + if (escape_xml) { + s = PHPDBG_G(err_buf).xml; + } else { + s = PHPDBG_G(err_buf).msg; + } + + if (s != NULL) { + if (escape_xml) { + s_len = PHPDBG_G(err_buf).xmllen; + } else { + s_len = PHPDBG_G(err_buf).msglen; + } + + if (adjust_precision && precision != s_len) { + s_len = precision; + } + } else { + s = ""; + s_len = 0; + } + pad_char = ' '; + break; + + + case 'r': + if (PHPDBG_G(req_id)) { + s_len = spprintf(&s, 0, "req=\"%lu\"", PHPDBG_G(req_id)); + free_s = s; + } else { + s = ""; + s_len = 0; + } + break; + + + case 'f': + case 'F': + case 'e': + case 'E': + + switch(modifier) { + case LM_LONG_DOUBLE: + fp_num = (double) va_arg(ap, long double); + break; + case LM_STD: + fp_num = va_arg(ap, double); + break; + default: + goto fmt_error; + } + + if (zend_isnan(fp_num)) { + s = "NAN"; + s_len = 3; + } else if (zend_isinf(fp_num)) { + s = "INF"; + s_len = 3; + } else { +#ifdef HAVE_LOCALE_H + if (!lconv) { + lconv = localeconv(); + } +#endif + s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form, + (adjust_precision == NO) ? FLOAT_DIGITS : precision, + (*fmt == 'f')?LCONV_DECIMAL_POINT:'.', + &is_negative, &num_buf[1], &s_len); + if (is_negative) + prefix_char = '-'; + else if (print_sign) + prefix_char = '+'; + else if (print_blank) + prefix_char = ' '; + } + break; + + + case 'g': + case 'k': + case 'G': + case 'H': + switch(modifier) { + case LM_LONG_DOUBLE: + fp_num = (double) va_arg(ap, long double); + break; + case LM_STD: + fp_num = va_arg(ap, double); + break; + default: + goto fmt_error; + } + + if (zend_isnan(fp_num)) { + s = "NAN"; + s_len = 3; + break; + } else if (zend_isinf(fp_num)) { + if (fp_num > 0) { + s = "INF"; + s_len = 3; + } else { + s = "-INF"; + s_len = 4; + } + break; + } + + if (adjust_precision == NO) { + precision = FLOAT_DIGITS; + } else if (precision == 0) { + precision = 1; + } + /* + * * We use &num_buf[ 1 ], so that we have room for the sign + */ +#ifdef HAVE_LOCALE_H + if (!lconv) { + lconv = localeconv(); + } +#endif + s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]); + if (*s == '-') { + prefix_char = *s++; + } else if (print_sign) { + prefix_char = '+'; + } else if (print_blank) { + prefix_char = ' '; + } + + s_len = strlen(s); + + if (alternate_form && (strchr(s, '.')) == NULL) { + s[s_len++] = '.'; + } + break; + + + case 'c': + char_buf[0] = (char) (va_arg(ap, int)); + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; + break; + + + case '%': + char_buf[0] = '%'; + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; + break; + + + case 'n': + *(va_arg(ap, int *)) = cc; + goto skip_output; + + /* + * Always extract the argument as a "char *" pointer. We + * should be using "void *" but there are still machines + * that don't understand it. + * If the pointer size is equal to the size of an unsigned + * integer we convert the pointer to a hex number, otherwise + * we print "%p" to indicate that we don't handle "%p". + */ + case 'p': + if (sizeof(char *) <= sizeof(u_wide_int)) { + ui_num = (u_wide_int)((size_t) va_arg(ap, char *)); + s = ap_php_conv_p2(ui_num, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + if (ui_num != 0) { + *--s = 'x'; + *--s = '0'; + s_len += 2; + } + } else { + s = "%p"; + s_len = 2; + } + pad_char = ' '; + break; + + + case NUL: + /* + * The last character of the format string was %. + * We ignore it. + */ + continue; + + +fmt_error: + php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt); + /* + * The default case is for unrecognized %'s. + * We print % to help the user identify what + * option is not understood. + * This is also useful in case the user wants to pass + * the output of format_converter to another function + * that understands some other % (like syslog). + * Note that we can't point s inside fmt because the + * unknown could be preceded by width etc. + */ + default: + char_buf[0] = '%'; + char_buf[1] = *fmt; + s = char_buf; + s_len = 2; + pad_char = ' '; + break; + } + + if (prefix_char != NUL) { + *--s = prefix_char; + s_len++; + } + if (adjust_width && adjust == RIGHT && min_width > s_len) { + if (pad_char == '0' && prefix_char != NUL) { + INS_CHAR(*s, sp, bep, cc) + s++; + s_len--; + min_width--; + } + PAD(min_width, s_len, pad_char); + } + /* + * Print the string s. + */ + for (i = s_len; i != 0; i--) { + INS_CHAR(*s, sp, bep, cc); + s++; + } + + if (adjust_width && adjust == LEFT && min_width > s_len) + PAD(min_width, s_len, pad_char); + if (free_zcopy) { + zval_dtor(&zcopy); + } + } +skip_output: + if (free_s) { + efree(free_s); + free_s = NULL; + } + + fmt++; + } + odp->nextb = sp; + return (cc); +} + +static void strx_printv(int *ccp, char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { + buffy od; + int cc; + + /* + * First initialize the descriptor + * Notice that if no length is given, we initialize buf_end to the + * highest possible address. + */ + if (len == 0) { + od.buf_end = (char *) ~0; + od.nextb = (char *) ~0; + } else { + od.buf_end = &buf[len-1]; + od.nextb = buf; + } + + /* + * Do the conversion + */ + cc = format_converter(&od, format, escape_xml, ap TSRMLS_CC); + if (len != 0 && od.nextb <= od.buf_end) { + *(od.nextb) = '\0'; + } + if (ccp) { + *ccp = cc; + } +} + +static int phpdbg_xml_vsnprintf(char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { + int cc; + + strx_printv(&cc, buf, len, format, escape_xml, ap TSRMLS_CC); + return (cc); +} + +PHPDBG_API int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { + va_list ap2; + int cc; + + va_copy(ap2, ap); + cc = phpdbg_xml_vsnprintf(NULL, 0, format, escape_xml, ap2 TSRMLS_CC); + va_end(ap2); + + *buf = NULL; + + if (cc >= 0) { + if ((*buf = emalloc(++cc)) != NULL) { + if ((cc = phpdbg_xml_vsnprintf(*buf, cc, format, escape_xml, ap TSRMLS_CC)) < 0) { + efree(*buf); + *buf = NULL; + } + } + } + + return cc; +} +/* copy end */ + +PHPDBG_API int _phpdbg_xml_asprintf(char **buf TSRMLS_DC, const char *format, zend_bool escape_xml, ...) { + int ret; + va_list va; + + va_start(va, escape_xml); + ret = phpdbg_xml_vasprintf(buf, format, escape_xml, va TSRMLS_CC); + va_end(va); + + return ret; +} + +PHPDBG_API int _phpdbg_asprintf(char **buf TSRMLS_DC, const char *format, ...) { + int ret; + va_list va; + + va_start(va, format); + ret = phpdbg_xml_vasprintf(buf, format, 0, va TSRMLS_CC); + va_end(va); + + return ret; +} + +static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char *to) { + int i; + int tolen = to ? strlen(to) : 5; + char *tmp = *buf = emalloc(msglen * tolen); + for (i = 0; i++ < msglen; msg++) { + if (*msg == '&') { + memcpy(tmp, ZEND_STRL("&")); + tmp += sizeof("&") - 1; + } else if (*msg == '<') { + memcpy(tmp, ZEND_STRL("<")); + tmp += sizeof("<") - 1; + } else if (((int) *msg) == from) { + memcpy(tmp, to, tolen); + tmp += tolen; + } else { + *tmp++ = *msg; + } + } + + { + int len = tmp - *buf; + *buf = erealloc(*buf, len + 1); + return len; + } +} + +static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) { + char *tmp, *tmpptr; + int len; + int i; + + tmp = tmpptr = emalloc(*buflen * 5); + + for (i = 0; i < *buflen; i++) { + if ((*buf)[i] < 0x20) { + *tmpptr++ = '&'; + *tmpptr++ = '#'; + if ((unsigned int) ((*buf)[i]) > 9) { + *tmpptr++ = ((*buf)[i] / 10) + '0'; + } + *tmpptr++ = ((*buf)[i] % 10) + '0'; + *tmpptr++ = ';'; + } else { + *tmpptr++ = (*buf)[i]; + } + } + + len = tmpptr - tmp; + + efree(*buf); + *buf = erealloc(tmp, len + 1); + *buflen = len; +} + +static int phpdbg_process_print(int fd, int type, const char *tag, const char *msg, int msglen, const char *xml, int xmllen TSRMLS_DC) { + char *msgout = NULL, *buf; + int msgoutlen, xmloutlen, buflen; + const char *severity; + + if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML) && PHPDBG_G(in_script_xml) && PHPDBG_G(in_script_xml) != type) { + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); + PHPDBG_G(in_script_xml) = 0; + } + + switch (type) { + case P_ERROR: + severity = "error"; + if (!PHPDBG_G(last_was_newline)) { + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + phpdbg_mixed_write(fd, ZEND_STRL("\n" "") TSRMLS_CC); + } else { + phpdbg_mixed_write(fd, ZEND_STRL("\n") TSRMLS_CC); + } + PHPDBG_G(last_was_newline) = 1; + } + if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { + msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); + } else { + msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg); + } + break; + + case P_NOTICE: + severity = "notice"; + if (!PHPDBG_G(last_was_newline)) { + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + phpdbg_mixed_write(fd, ZEND_STRL("\n" "") TSRMLS_CC); + } else { + phpdbg_mixed_write(fd, ZEND_STRL("\n") TSRMLS_CC); + } + PHPDBG_G(last_was_newline) = 1; + } + if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { + msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); + } else { + msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg); + } + break; + + case P_WRITELN: + severity = "normal"; + if (msg) { + msgoutlen = phpdbg_asprintf(&msgout, "%.*s\n", msglen, msg); + } else { + msgoutlen = 1; + msgout = estrdup("\n"); + } + PHPDBG_G(last_was_newline) = 1; + break; + + case P_WRITE: + severity = "normal"; + if (msg) { + msgout = estrndup(msg, msglen); + msgoutlen = msglen; + PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n'; + } else { + msgoutlen = 0; + msgout = estrdup(""); + } + break; + + case P_STDOUT: + case P_STDERR: + if (msg) { + PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n'; + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + if (PHPDBG_G(in_script_xml) != type) { + char *stream_buf; + int stream_buflen = phpdbg_asprintf(&stream_buf, "", type == P_STDERR ? "stderr" : "stdout"); + phpdbg_mixed_write(fd, stream_buf, stream_buflen TSRMLS_CC); + efree(stream_buf); + PHPDBG_G(in_script_xml) = type; + } +#if PHP_VERSION_ID >= 50600 + buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); +#else + buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, SG(default_charset) ? SG(default_charset) : "UTF-8" TSRMLS_CC); +#endif + phpdbg_encode_ctrl_chars(&buf, &buflen); + phpdbg_mixed_write(fd, buf, buflen TSRMLS_CC); + efree(buf); + } else { + phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC); + } + return msglen; + } + break; + + /* no formatting on logging output */ + case P_LOG: + severity = "log"; + if (msg) { + struct timeval tp; + if (gettimeofday(&tp, NULL) == SUCCESS) { + msgoutlen = phpdbg_asprintf(&msgout, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); + } else { + msgoutlen = FAILURE; + } + } + break; + } + + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + char *xmlout; + + if (PHPDBG_G(req_id)) { + char *xmlbuf = NULL; + xmllen = phpdbg_asprintf(&xmlbuf, "req=\"%lu\" %.*s", PHPDBG_G(req_id), xmllen, xml); + xml = xmlbuf; + } + if (msgout) { + buflen = phpdbg_encode_xml(&buf, msgout, msgoutlen, '"', """); + xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf); + + efree(buf); + } else { + xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"\" />", tag, severity, xmllen, xml); + } + + phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen); + phpdbg_eol_convert(&xmlout, &xmloutlen TSRMLS_CC); + phpdbg_mixed_write(fd, xmlout, xmloutlen TSRMLS_CC); + efree(xmlout); + } else if (msgout) { + phpdbg_eol_convert(&msgout, &msgoutlen TSRMLS_CC); + phpdbg_mixed_write(fd, msgout, msgoutlen TSRMLS_CC); + } + + if (PHPDBG_G(req_id) && (PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { + efree((char *) xml); + } + + if (msgout) { + efree(msgout); + } + + return msgout ? msgoutlen : xmloutlen; +} /* }}} */ + +PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, va_list args) { + char *msg = NULL, *xml = NULL; + int msglen = 0, xmllen = 0; + int len; + va_list argcpy; + + if (strfmt != NULL && strlen(strfmt) > 0L) { + va_copy(argcpy, args); + msglen = phpdbg_xml_vasprintf(&msg, strfmt, 0, argcpy TSRMLS_CC); + va_end(argcpy); + } + + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + if (xmlfmt != NULL && strlen(xmlfmt) > 0L) { + va_copy(argcpy, args); + xmllen = phpdbg_xml_vasprintf(&xml, xmlfmt, 1, argcpy TSRMLS_CC); + va_end(argcpy); + } else { + xml = estrdup(""); + } + } + + if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) { + PHPDBG_G(err_buf).type = type; + PHPDBG_G(err_buf).fd = fd; + PHPDBG_G(err_buf).tag = estrdup(tag); + PHPDBG_G(err_buf).msg = msg; + PHPDBG_G(err_buf).msglen = msglen; + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + PHPDBG_G(err_buf).xml = xml; + PHPDBG_G(err_buf).xmllen = xmllen; + } + + return msglen; + } + + len = phpdbg_process_print(fd, type, tag, msg, msglen, xml, xmllen TSRMLS_CC); + + if (msg) { + efree(msg); + } + + if (xml) { + efree(xml); + } + + return len; +} + +PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D) { + if (PHPDBG_G(err_buf).type == 0) { + return; + } + + PHPDBG_G(err_buf).type = 0; + + efree(PHPDBG_G(err_buf).tag); + efree(PHPDBG_G(err_buf).msg); + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + efree(PHPDBG_G(err_buf).xml); + } +} + +PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC) { + PHPDBG_G(err_buf).active = active; +} + +PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt TSRMLS_DC, ...) { + int len; + va_list args; + int errbuf_active = PHPDBG_G(err_buf).active; + + PHPDBG_G(err_buf).active = 0; + +#ifdef ZTS + va_start(args, tsrm_ls); +#else + va_start(args, strfmt); +#endif + len = phpdbg_vprint(PHPDBG_G(err_buf).type TSRMLS_CC, PHPDBG_G(err_buf).fd, tag ? tag : PHPDBG_G(err_buf).tag, xmlfmt, strfmt, args); + va_end(args); + + PHPDBG_G(err_buf).active = errbuf_active; + phpdbg_free_err_buf(TSRMLS_C); + + return len; +} + +PHPDBG_API int phpdbg_print(int type TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) { + va_list args; + int len; + + va_start(args, strfmt); + len = phpdbg_vprint(type TSRMLS_CC, fd, tag, xmlfmt, strfmt, args); + va_end(args); + + return len; +} + +PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) { + int len = 0; + + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + va_list args; + char *buffer; + int buflen; + + va_start(args, fmt); + buflen = phpdbg_xml_vasprintf(&buffer, fmt, 1, args TSRMLS_CC); + va_end(args); + + phpdbg_encode_ctrl_chars(&buffer, &buflen); + + if (PHPDBG_G(in_script_xml)) { + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); + PHPDBG_G(in_script_xml) = 0; + } + + len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); + efree(buffer); + } + + return len; +} + +PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...) { + va_list args; + char *buffer; + int buflen; + int len = 0; + + va_start(args, fmt); + buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); + va_end(args); + + len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); + efree(buffer); + + return len; +} + +PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { + va_list args; + char *buffer; + int buflen; + int len = 0; + + va_start(args, fmt); + buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); + va_end(args); + + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + char *msg; + int msglen; + + msglen = phpdbg_encode_xml(&msg, buffer, buflen, 256, NULL); + phpdbg_encode_ctrl_chars(&msg, &msglen); + phpdbg_eol_convert(&msg, &msglen TSRMLS_CC); + + if (PHPDBG_G(in_script_xml)) { + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); + PHPDBG_G(in_script_xml) = 0; + } + + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); + len = phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC); + phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); + } else { + phpdbg_eol_convert(&buffer, &buflen TSRMLS_CC); + len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); + } + + return len; +} + + +PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...) { /* {{{ */ + int rc = 0; + + va_list args; + struct timeval tp; + + va_start(args, fmt); + if (gettimeofday(&tp, NULL) == SUCCESS) { + char friendly[100]; + char *format = NULL, *buffer = NULL, *outbuf = NULL; + const time_t tt = tp.tv_sec; + +#ifdef PHP_WIN32 + strftime(friendly, 100, "%a %b %d %H.%%04d %Y", localtime(&tt)); +#else + strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt)); +#endif + phpdbg_asprintf(&buffer, friendly, tp.tv_usec/1000); + phpdbg_asprintf(&format, "[%s]: %s\n", buffer, fmt); + rc = phpdbg_xml_vasprintf(&outbuf, format, 0, args TSRMLS_CC); + + if (outbuf) { + rc = phpdbg_mixed_write(fd, outbuf, rc TSRMLS_CC); + efree(outbuf); + } + + efree(format); + efree(buffer); + } + va_end(args); + + return rc; +} /* }}} */ diff --git a/phpdbg_out.h b/phpdbg_out.h new file mode 100644 index 00000000000..d94fbd73852 --- /dev/null +++ b/phpdbg_out.h @@ -0,0 +1,89 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_OUT_H +#define PHPDBG_OUT_H + +/** + * Error/notice/formatting helpers + */ +enum { + P_ERROR = 1, + P_NOTICE, + P_WRITELN, + P_WRITE, + P_STDOUT, + P_STDERR, + P_LOG +}; + +#ifdef ZTS +PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 6, 7); +#else +PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 5, 6); +#endif + +PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...); +PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...); +PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...); + +PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...); +#define phpdbg_rlog(fd, fmt, ...) phpdbg_rlog_internal(fd TSRMLS_CC, fmt, ##__VA_ARGS__) + +#define phpdbg_error(tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_notice(tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_writeln(tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_write(tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_script(type, fmt, ...) phpdbg_print(type TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, NULL, NULL, fmt, ##__VA_ARGS__) +#define phpdbg_log(fmt, ...) phpdbg_log_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_xml(fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_out(fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) + +#define phpdbg_error_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_notice_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_writeln_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_write_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) +#define phpdbg_script_ex(out, type, fmt, ...) phpdbg_print(type TSRMLS_CC, out, NULL, NULL, fmt, ##__VA_ARGS__) +#define phpdbg_log_ex(out, fmt, ...) phpdbg_log_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_xml_ex(out, fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_out_ex(out, fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) + +#define phpdbg_xml_asprintf(buf, ...) _phpdbg_xml_asprintf(buf TSRMLS_CC, ##__VA_ARGS__) +PHPDBG_API int _phpdbg_xml_asprintf(char **buf TSRMLS_DC, const char *format, zend_bool escape_xml, ...); + +#define phpdbg_asprintf(buf, ...) _phpdbg_asprintf(buf TSRMLS_CC, ##__VA_ARGS__) +PHPDBG_API int _phpdbg_asprintf(char **buf TSRMLS_DC, const char *format, ...); + + +#if PHPDBG_DEBUG +# define phpdbg_debug(fmt, ...) phpdbg_log_ex(PHPDBG_G(io)[PHPDBG_STDERR].fd TSRMLS_CC, fmt, ##__VA_ARGS__) +#else +# define phpdbg_debug(fmt, ...) +#endif + +PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D); +PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC); +PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt TSRMLS_DC, ...); + + +/* {{{ For separation */ +#define SEPARATE "------------------------------------------------" /* }}} */ + +#endif /* PHPDBG_OUT_H */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 69dc7d12d4c..fa4b8b0baa0 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -18,22 +18,13 @@ +----------------------------------------------------------------------+ */ -#include -#include -#include #include "zend.h" #include "php.h" -#include "spprintf.h" #include "phpdbg.h" #include "phpdbg_opcode.h" -#include "phpdbg_io.h" #include "phpdbg_utils.h" -#include "phpdbg_eol.h" -#include "ext/standard/html.h" -#ifdef _WIN32 -# include "win32/time.h" -#elif defined(HAVE_SYS_IOCTL_H) +#if defined(HAVE_SYS_IOCTL_H) # include "sys/ioctl.h" # ifndef GWINSZ_IN_SYS_IOCTL # include @@ -227,1282 +218,6 @@ PHPDBG_API char *phpdbg_trim(const char *str, size_t len, size_t *new_len) /* {{ } /* }}} */ -/* copied from php-src/main/snprintf.c and slightly modified */ -/* - * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions - * - * XXX: this is a magic number; do not decrease it - * Emax = 1023 - * NDIG = 320 - * NUM_BUF_SIZE >= strlen("-") + Emax + strlrn(".") + NDIG + strlen("E+1023") + 1; - */ -#define NUM_BUF_SIZE 2048 - -/* - * Descriptor for buffer area - */ -struct buf_area { - char *buf_end; - char *nextb; /* pointer to next byte to read/write */ -}; - -typedef struct buf_area buffy; - -/* - * The INS_CHAR macro inserts a character in the buffer and writes - * the buffer back to disk if necessary - * It uses the char pointers sp and bep: - * sp points to the next available character in the buffer - * bep points to the end-of-buffer+1 - * While using this macro, note that the nextb pointer is NOT updated. - * - * NOTE: Evaluation of the c argument should not have any side-effects - */ -#define INS_CHAR(c, sp, bep, cc) \ - { \ - if (sp < bep) \ - { \ - *sp++ = c; \ - } \ - cc++; \ - } - -#define NUM( c ) ( c - '0' ) - -#define STR_TO_DEC( str, num ) \ - num = NUM( *str++ ) ; \ - while ( isdigit((int)*str ) ) \ - { \ - num *= 10 ; \ - num += NUM( *str++ ) ; \ - } - -/* - * This macro does zero padding so that the precision - * requirement is satisfied. The padding is done by - * adding '0's to the left of the string that is going - * to be printed. - */ -#define FIX_PRECISION( adjust, precision, s, s_len ) \ - if ( adjust ) \ - while ( s_len < precision ) \ - { \ - *--s = '0' ; \ - s_len++ ; \ - } - -/* - * Macro that does padding. The padding is done by printing - * the character ch. - */ -#define PAD( width, len, ch ) do \ - { \ - INS_CHAR( ch, sp, bep, cc ) ; \ - width-- ; \ - } \ - while ( width > len ) - -/* - * Prefix the character ch to the string str - * Increase length - * Set the has_prefix flag - */ -#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES - - -#ifdef HAVE_LOCALE_H -#include -#define LCONV_DECIMAL_POINT (*lconv->decimal_point) -#else -#define LCONV_DECIMAL_POINT '.' -#endif -#define NUL '\0' -#define S_NULL "(null)" -#define S_NULL_LEN 6 -#define FLOAT_DIGITS 6 - -/* - * Do format conversion placing the output in buffer - */ -static int format_converter(register buffy *odp, const char *fmt, zend_bool escape_xml, va_list ap TSRMLS_DC) { - char *sp; - char *bep; - int cc = 0; - int i; - - char *s = NULL, *free_s = NULL; - int s_len, free_zcopy; - zval *zvp, zcopy; - - int min_width = 0; - int precision = 0; - enum { - LEFT, RIGHT - } adjust; - char pad_char; - char prefix_char; - - double fp_num; - wide_int i_num = (wide_int) 0; - u_wide_int ui_num; - - char num_buf[NUM_BUF_SIZE]; - char char_buf[2]; /* for printing %% and % */ - -#ifdef HAVE_LOCALE_H - struct lconv *lconv = NULL; -#endif - - /* - * Flag variables - */ - length_modifier_e modifier; - boolean_e alternate_form; - boolean_e print_sign; - boolean_e print_blank; - boolean_e adjust_precision; - boolean_e adjust_width; - bool_int is_negative; - - sp = odp->nextb; - bep = odp->buf_end; - - while (*fmt) { - if (*fmt != '%') { - INS_CHAR(*fmt, sp, bep, cc); - } else { - /* - * Default variable settings - */ - adjust = RIGHT; - alternate_form = print_sign = print_blank = NO; - pad_char = ' '; - prefix_char = NUL; - free_zcopy = 0; - - fmt++; - - /* - * Try to avoid checking for flags, width or precision - */ - if (isascii((int)*fmt) && !islower((int)*fmt)) { - /* - * Recognize flags: -, #, BLANK, + - */ - for (;; fmt++) { - if (*fmt == '-') - adjust = LEFT; - else if (*fmt == '+') - print_sign = YES; - else if (*fmt == '#') - alternate_form = YES; - else if (*fmt == ' ') - print_blank = YES; - else if (*fmt == '0') - pad_char = '0'; - else - break; - } - - /* - * Check if a width was specified - */ - if (isdigit((int)*fmt)) { - STR_TO_DEC(fmt, min_width); - adjust_width = YES; - } else if (*fmt == '*') { - min_width = va_arg(ap, int); - fmt++; - adjust_width = YES; - if (min_width < 0) { - adjust = LEFT; - min_width = -min_width; - } - } else - adjust_width = NO; - - /* - * Check if a precision was specified - */ - if (*fmt == '.') { - adjust_precision = YES; - fmt++; - if (isdigit((int)*fmt)) { - STR_TO_DEC(fmt, precision); - } else if (*fmt == '*') { - precision = va_arg(ap, int); - fmt++; - if (precision < 0) - precision = 0; - } else - precision = 0; - - if (precision > FORMAT_CONV_MAX_PRECISION && *fmt != 's' && *fmt != 'v' && *fmt != 'b') { - precision = FORMAT_CONV_MAX_PRECISION; - } - } else - adjust_precision = NO; - } else - adjust_precision = adjust_width = NO; - - /* - * Modifier check - */ - switch (*fmt) { - case 'L': - fmt++; - modifier = LM_LONG_DOUBLE; - break; - case 'I': - fmt++; -#if SIZEOF_LONG_LONG - if (*fmt == '6' && *(fmt+1) == '4') { - fmt += 2; - modifier = LM_LONG_LONG; - } else -#endif - if (*fmt == '3' && *(fmt+1) == '2') { - fmt += 2; - modifier = LM_LONG; - } else { -#ifdef _WIN64 - modifier = LM_LONG_LONG; -#else - modifier = LM_LONG; -#endif - } - break; - case 'l': - fmt++; -#if SIZEOF_LONG_LONG - if (*fmt == 'l') { - fmt++; - modifier = LM_LONG_LONG; - } else -#endif - modifier = LM_LONG; - break; - case 'z': - fmt++; - modifier = LM_SIZE_T; - break; - case 'j': - fmt++; -#if SIZEOF_INTMAX_T - modifier = LM_INTMAX_T; -#else - modifier = LM_SIZE_T; -#endif - break; - case 't': - fmt++; -#if SIZEOF_PTRDIFF_T - modifier = LM_PTRDIFF_T; -#else - modifier = LM_SIZE_T; -#endif - break; - case 'h': - fmt++; - if (*fmt == 'h') { - fmt++; - } - /* these are promoted to int, so no break */ - default: - modifier = LM_STD; - break; - } - - /* - * Argument extraction and printing. - * First we determine the argument type. - * Then, we convert the argument to a string. - * On exit from the switch, s points to the string that - * must be printed, s_len has the length of the string - * The precision requirements, if any, are reflected in s_len. - * - * NOTE: pad_char may be set to '0' because of the 0 flag. - * It is reset to ' ' by non-numeric formats - */ - switch (*fmt) { - case 'Z': - zvp = (zval*) va_arg(ap, zval*); - zend_make_printable_zval(zvp, &zcopy, &free_zcopy); - if (free_zcopy) { - zvp = &zcopy; - } - s_len = Z_STRLEN_P(zvp); - s = Z_STRVAL_P(zvp); - if (adjust_precision && precision < s_len) { - s_len = precision; - } - break; - case 'u': - switch(modifier) { - default: - i_num = (wide_int) va_arg(ap, unsigned int); - break; - case LM_LONG_DOUBLE: - goto fmt_error; - case LM_LONG: - i_num = (wide_int) va_arg(ap, unsigned long int); - break; - case LM_SIZE_T: - i_num = (wide_int) va_arg(ap, size_t); - break; -#if SIZEOF_LONG_LONG - case LM_LONG_LONG: - i_num = (wide_int) va_arg(ap, u_wide_int); - break; -#endif -#if SIZEOF_INTMAX_T - case LM_INTMAX_T: - i_num = (wide_int) va_arg(ap, uintmax_t); - break; -#endif -#if SIZEOF_PTRDIFF_T - case LM_PTRDIFF_T: - i_num = (wide_int) va_arg(ap, ptrdiff_t); - break; -#endif - } - /* - * The rest also applies to other integer formats, so fall - * into that case. - */ - case 'd': - case 'i': - /* - * Get the arg if we haven't already. - */ - if ((*fmt) != 'u') { - switch(modifier) { - default: - i_num = (wide_int) va_arg(ap, int); - break; - case LM_LONG_DOUBLE: - goto fmt_error; - case LM_LONG: - i_num = (wide_int) va_arg(ap, long int); - break; - case LM_SIZE_T: -#if SIZEOF_SSIZE_T - i_num = (wide_int) va_arg(ap, ssize_t); -#else - i_num = (wide_int) va_arg(ap, size_t); -#endif - break; -#if SIZEOF_LONG_LONG - case LM_LONG_LONG: - i_num = (wide_int) va_arg(ap, wide_int); - break; -#endif -#if SIZEOF_INTMAX_T - case LM_INTMAX_T: - i_num = (wide_int) va_arg(ap, intmax_t); - break; -#endif -#if SIZEOF_PTRDIFF_T - case LM_PTRDIFF_T: - i_num = (wide_int) va_arg(ap, ptrdiff_t); - break; -#endif - } - } - s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative, - &num_buf[NUM_BUF_SIZE], &s_len); - FIX_PRECISION(adjust_precision, precision, s, s_len); - - if (*fmt != 'u') { - if (is_negative) { - prefix_char = '-'; - } else if (print_sign) { - prefix_char = '+'; - } else if (print_blank) { - prefix_char = ' '; - } - } - break; - - - case 'o': - switch(modifier) { - default: - ui_num = (u_wide_int) va_arg(ap, unsigned int); - break; - case LM_LONG_DOUBLE: - goto fmt_error; - case LM_LONG: - ui_num = (u_wide_int) va_arg(ap, unsigned long int); - break; - case LM_SIZE_T: - ui_num = (u_wide_int) va_arg(ap, size_t); - break; -#if SIZEOF_LONG_LONG - case LM_LONG_LONG: - ui_num = (u_wide_int) va_arg(ap, u_wide_int); - break; -#endif -#if SIZEOF_INTMAX_T - case LM_INTMAX_T: - ui_num = (u_wide_int) va_arg(ap, uintmax_t); - break; -#endif -#if SIZEOF_PTRDIFF_T - case LM_PTRDIFF_T: - ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); - break; -#endif - } - s = ap_php_conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); - FIX_PRECISION(adjust_precision, precision, s, s_len); - if (alternate_form && *s != '0') { - *--s = '0'; - s_len++; - } - break; - - - case 'x': - case 'X': - switch(modifier) { - default: - ui_num = (u_wide_int) va_arg(ap, unsigned int); - break; - case LM_LONG_DOUBLE: - goto fmt_error; - case LM_LONG: - ui_num = (u_wide_int) va_arg(ap, unsigned long int); - break; - case LM_SIZE_T: - ui_num = (u_wide_int) va_arg(ap, size_t); - break; -#if SIZEOF_LONG_LONG - case LM_LONG_LONG: - ui_num = (u_wide_int) va_arg(ap, u_wide_int); - break; -#endif -#if SIZEOF_INTMAX_T - case LM_INTMAX_T: - ui_num = (u_wide_int) va_arg(ap, uintmax_t); - break; -#endif -#if SIZEOF_PTRDIFF_T - case LM_PTRDIFF_T: - ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); - break; -#endif - } - s = ap_php_conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); - FIX_PRECISION(adjust_precision, precision, s, s_len); - if (alternate_form && i_num != 0) { - *--s = *fmt; /* 'x' or 'X' */ - *--s = '0'; - s_len += 2; - } - break; - - - case 's': - case 'v': - s = va_arg(ap, char *); - if (s != NULL) { - if (adjust_precision) { - s_len = precision; - } else { - s_len = strlen(s); - } - - if (escape_xml) { - /* added: support for xml escaping */ - - int old_slen = s_len, i = 0; - char *old_s = s, *s_ptr; - free_s = s_ptr = s = emalloc(old_slen * 6 + 1); - do { - if (old_s[i] == '&' || old_s[i] == '"' || old_s[i] == '<') { - *s_ptr++ = '&'; - switch (old_s[i]) { - case '"': - s_len += 5; - *s_ptr++ = 'q'; - *s_ptr++ = 'u'; - *s_ptr++ = 'o'; - *s_ptr++ = 't'; - break; - case '<': - s_len += 3; - *s_ptr++ = 'l'; - *s_ptr++ = 't'; - break; - case '&': - s_len += 4; - *s_ptr++ = 'a'; - *s_ptr++ = 'm'; - *s_ptr++ = 'p'; - break; - } - *s_ptr++ = ';'; - } else { - *s_ptr++ = old_s[i]; - } - } while (i++ < old_slen); - } - } else { - s = S_NULL; - s_len = S_NULL_LEN; - } - pad_char = ' '; - break; - - - case 'b': - if (escape_xml) { - s = PHPDBG_G(err_buf).xml; - } else { - s = PHPDBG_G(err_buf).msg; - } - - if (s != NULL) { - if (escape_xml) { - s_len = PHPDBG_G(err_buf).xmllen; - } else { - s_len = PHPDBG_G(err_buf).msglen; - } - - if (adjust_precision && precision != s_len) { - s_len = precision; - } - } else { - s = ""; - s_len = 0; - } - pad_char = ' '; - break; - - - case 'r': - if (PHPDBG_G(req_id)) { - s_len = spprintf(&s, 0, "req=\"%lu\"", PHPDBG_G(req_id)); - free_s = s; - } else { - s = ""; - s_len = 0; - } - break; - - - case 'f': - case 'F': - case 'e': - case 'E': - - switch(modifier) { - case LM_LONG_DOUBLE: - fp_num = (double) va_arg(ap, long double); - break; - case LM_STD: - fp_num = va_arg(ap, double); - break; - default: - goto fmt_error; - } - - if (zend_isnan(fp_num)) { - s = "NAN"; - s_len = 3; - } else if (zend_isinf(fp_num)) { - s = "INF"; - s_len = 3; - } else { -#ifdef HAVE_LOCALE_H - if (!lconv) { - lconv = localeconv(); - } -#endif - s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form, - (adjust_precision == NO) ? FLOAT_DIGITS : precision, - (*fmt == 'f')?LCONV_DECIMAL_POINT:'.', - &is_negative, &num_buf[1], &s_len); - if (is_negative) - prefix_char = '-'; - else if (print_sign) - prefix_char = '+'; - else if (print_blank) - prefix_char = ' '; - } - break; - - - case 'g': - case 'k': - case 'G': - case 'H': - switch(modifier) { - case LM_LONG_DOUBLE: - fp_num = (double) va_arg(ap, long double); - break; - case LM_STD: - fp_num = va_arg(ap, double); - break; - default: - goto fmt_error; - } - - if (zend_isnan(fp_num)) { - s = "NAN"; - s_len = 3; - break; - } else if (zend_isinf(fp_num)) { - if (fp_num > 0) { - s = "INF"; - s_len = 3; - } else { - s = "-INF"; - s_len = 4; - } - break; - } - - if (adjust_precision == NO) { - precision = FLOAT_DIGITS; - } else if (precision == 0) { - precision = 1; - } - /* - * * We use &num_buf[ 1 ], so that we have room for the sign - */ -#ifdef HAVE_LOCALE_H - if (!lconv) { - lconv = localeconv(); - } -#endif - s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]); - if (*s == '-') { - prefix_char = *s++; - } else if (print_sign) { - prefix_char = '+'; - } else if (print_blank) { - prefix_char = ' '; - } - - s_len = strlen(s); - - if (alternate_form && (strchr(s, '.')) == NULL) { - s[s_len++] = '.'; - } - break; - - - case 'c': - char_buf[0] = (char) (va_arg(ap, int)); - s = &char_buf[0]; - s_len = 1; - pad_char = ' '; - break; - - - case '%': - char_buf[0] = '%'; - s = &char_buf[0]; - s_len = 1; - pad_char = ' '; - break; - - - case 'n': - *(va_arg(ap, int *)) = cc; - goto skip_output; - - /* - * Always extract the argument as a "char *" pointer. We - * should be using "void *" but there are still machines - * that don't understand it. - * If the pointer size is equal to the size of an unsigned - * integer we convert the pointer to a hex number, otherwise - * we print "%p" to indicate that we don't handle "%p". - */ - case 'p': - if (sizeof(char *) <= sizeof(u_wide_int)) { - ui_num = (u_wide_int)((size_t) va_arg(ap, char *)); - s = ap_php_conv_p2(ui_num, 4, 'x', - &num_buf[NUM_BUF_SIZE], &s_len); - if (ui_num != 0) { - *--s = 'x'; - *--s = '0'; - s_len += 2; - } - } else { - s = "%p"; - s_len = 2; - } - pad_char = ' '; - break; - - - case NUL: - /* - * The last character of the format string was %. - * We ignore it. - */ - continue; - - -fmt_error: - php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt); - /* - * The default case is for unrecognized %'s. - * We print % to help the user identify what - * option is not understood. - * This is also useful in case the user wants to pass - * the output of format_converter to another function - * that understands some other % (like syslog). - * Note that we can't point s inside fmt because the - * unknown could be preceded by width etc. - */ - default: - char_buf[0] = '%'; - char_buf[1] = *fmt; - s = char_buf; - s_len = 2; - pad_char = ' '; - break; - } - - if (prefix_char != NUL) { - *--s = prefix_char; - s_len++; - } - if (adjust_width && adjust == RIGHT && min_width > s_len) { - if (pad_char == '0' && prefix_char != NUL) { - INS_CHAR(*s, sp, bep, cc) - s++; - s_len--; - min_width--; - } - PAD(min_width, s_len, pad_char); - } - /* - * Print the string s. - */ - for (i = s_len; i != 0; i--) { - INS_CHAR(*s, sp, bep, cc); - s++; - } - - if (adjust_width && adjust == LEFT && min_width > s_len) - PAD(min_width, s_len, pad_char); - if (free_zcopy) { - zval_dtor(&zcopy); - } - } -skip_output: - if (free_s) { - efree(free_s); - free_s = NULL; - } - - fmt++; - } - odp->nextb = sp; - return (cc); -} - -static void strx_printv(int *ccp, char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { - buffy od; - int cc; - - /* - * First initialize the descriptor - * Notice that if no length is given, we initialize buf_end to the - * highest possible address. - */ - if (len == 0) { - od.buf_end = (char *) ~0; - od.nextb = (char *) ~0; - } else { - od.buf_end = &buf[len-1]; - od.nextb = buf; - } - - /* - * Do the conversion - */ - cc = format_converter(&od, format, escape_xml, ap TSRMLS_CC); - if (len != 0 && od.nextb <= od.buf_end) { - *(od.nextb) = '\0'; - } - if (ccp) { - *ccp = cc; - } -} - -static int phpdbg_xml_vsnprintf(char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { - int cc; - - strx_printv(&cc, buf, len, format, escape_xml, ap TSRMLS_CC); - return (cc); -} - -PHPDBG_API int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool escape_xml, va_list ap TSRMLS_DC) { - va_list ap2; - int cc; - - va_copy(ap2, ap); - cc = phpdbg_xml_vsnprintf(NULL, 0, format, escape_xml, ap2 TSRMLS_CC); - va_end(ap2); - - *buf = NULL; - - if (cc >= 0) { - if ((*buf = emalloc(++cc)) != NULL) { - if ((cc = phpdbg_xml_vsnprintf(*buf, cc, format, escape_xml, ap TSRMLS_CC)) < 0) { - efree(*buf); - *buf = NULL; - } - } - } - - return cc; -} -/* copy end */ - -#define phpdbg_xml_asprintf(buf, ...) _phpdbg_xml_asprintf(buf TSRMLS_CC, ##__VA_ARGS__) -PHPDBG_API int _phpdbg_xml_asprintf(char **buf TSRMLS_DC, const char *format, zend_bool escape_xml, ...) { - int ret; - va_list va; - - va_start(va, escape_xml); - ret = phpdbg_xml_vasprintf(buf, format, escape_xml, va TSRMLS_CC); - va_end(va); - - return ret; -} - -#define phpdbg_asprintf(buf, ...) _phpdbg_asprintf(buf TSRMLS_CC, ##__VA_ARGS__) -PHPDBG_API int _phpdbg_asprintf(char **buf TSRMLS_DC, const char *format, ...) { - int ret; - va_list va; - - va_start(va, format); - ret = phpdbg_xml_vasprintf(buf, format, 0, va TSRMLS_CC); - va_end(va); - - return ret; -} - -static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char *to) { - int i; - int tolen = to ? strlen(to) : 5; - char *tmp = *buf = emalloc(msglen * tolen); - for (i = 0; i++ < msglen; msg++) { - if (*msg == '&') { - memcpy(tmp, ZEND_STRL("&")); - tmp += sizeof("&") - 1; - } else if (*msg == '<') { - memcpy(tmp, ZEND_STRL("<")); - tmp += sizeof("<") - 1; - } else if (((int) *msg) == from) { - memcpy(tmp, to, tolen); - tmp += tolen; - } else { - *tmp++ = *msg; - } - } - - { - int len = tmp - *buf; - *buf = erealloc(*buf, len + 1); - return len; - } -} - -static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) { - char *tmp, *tmpptr; - int len; - int i; - - tmp = tmpptr = emalloc(*buflen * 5); - - for (i = 0; i < *buflen; i++) { - if ((*buf)[i] < 0x20) { - *tmpptr++ = '&'; - *tmpptr++ = '#'; - if ((unsigned int) ((*buf)[i]) > 9) { - *tmpptr++ = ((*buf)[i] / 10) + '0'; - } - *tmpptr++ = ((*buf)[i] % 10) + '0'; - *tmpptr++ = ';'; - } else { - *tmpptr++ = (*buf)[i]; - } - } - - len = tmpptr - tmp; - - efree(*buf); - *buf = erealloc(tmp, len + 1); - *buflen = len; -} - -static int phpdbg_process_print(int fd, int type, const char *tag, const char *msg, int msglen, const char *xml, int xmllen TSRMLS_DC) { - char *msgout = NULL, *buf; - int msgoutlen, xmloutlen, buflen; - const char *severity; - - if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML) && PHPDBG_G(in_script_xml) && PHPDBG_G(in_script_xml) != type) { - phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); - PHPDBG_G(in_script_xml) = 0; - } - - /* TODO(anyone) colours */ - - switch (type) { - case P_ERROR: - severity = "error"; - if (!PHPDBG_G(last_was_newline)) { - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_mixed_write(fd, ZEND_STRL("\n" "") TSRMLS_CC); - } else { - phpdbg_mixed_write(fd, ZEND_STRL("\n") TSRMLS_CC); - } - PHPDBG_G(last_was_newline) = 1; - } - if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg); - } else { - msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg); - } - break; - - case P_NOTICE: - severity = "notice"; - if (!PHPDBG_G(last_was_newline)) { - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - phpdbg_mixed_write(fd, ZEND_STRL("\n" "") TSRMLS_CC); - } else { - phpdbg_mixed_write(fd, ZEND_STRL("\n") TSRMLS_CC); - } - PHPDBG_G(last_was_newline) = 1; - } - if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg); - } else { - msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg); - } - break; - - case P_WRITELN: - severity = "normal"; - if (msg) { - msgoutlen = phpdbg_asprintf(&msgout, "%.*s\n", msglen, msg); - } else { - msgoutlen = 1; - msgout = estrdup("\n"); - } - PHPDBG_G(last_was_newline) = 1; - break; - - case P_WRITE: - severity = "normal"; - if (msg) { - msgout = estrndup(msg, msglen); - msgoutlen = msglen; - PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n'; - } else { - msgoutlen = 0; - msgout = estrdup(""); - } - break; - - case P_STDOUT: - case P_STDERR: - if (msg) { - PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n'; - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - if (PHPDBG_G(in_script_xml) != type) { - char *stream_buf; - int stream_buflen = phpdbg_asprintf(&stream_buf, "", type == P_STDERR ? "stderr" : "stdout"); - phpdbg_mixed_write(fd, stream_buf, stream_buflen TSRMLS_CC); - efree(stream_buf); - PHPDBG_G(in_script_xml) = type; - } -#if PHP_VERSION_ID >= 50600 - buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC); -#else - buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, SG(default_charset) ? SG(default_charset) : "UTF-8" TSRMLS_CC); -#endif - phpdbg_encode_ctrl_chars(&buf, &buflen); - phpdbg_mixed_write(fd, buf, buflen TSRMLS_CC); - efree(buf); - } else { - phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC); - } - return msglen; - } - break; - - /* no formatting on logging output */ - case P_LOG: - severity = "log"; - if (msg) { - struct timeval tp; - if (gettimeofday(&tp, NULL) == SUCCESS) { - msgoutlen = phpdbg_asprintf(&msgout, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg); - } else { - msgoutlen = FAILURE; - } - } - break; - } - - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - char *xmlout; - - if (PHPDBG_G(req_id)) { - char *xmlbuf = NULL; - xmllen = phpdbg_asprintf(&xmlbuf, "req=\"%lu\" %.*s", PHPDBG_G(req_id), xmllen, xml); - xml = xmlbuf; - } - if (msgout) { - buflen = phpdbg_encode_xml(&buf, msgout, msgoutlen, '"', """); - xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf); - - efree(buf); - } else { - xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"\" />", tag, severity, xmllen, xml); - } - - phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen); - phpdbg_eol_convert(&xmlout, &xmloutlen TSRMLS_CC); - phpdbg_mixed_write(fd, xmlout, xmloutlen TSRMLS_CC); - efree(xmlout); - } else if (msgout) { - phpdbg_eol_convert(&msgout, &msgoutlen TSRMLS_CC); - phpdbg_mixed_write(fd, msgout, msgoutlen TSRMLS_CC); - } - - if (PHPDBG_G(req_id) && (PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { - efree((char *) xml); - } - - if (msgout) { - efree(msgout); - } - - return msgout ? msgoutlen : xmloutlen; -} /* }}} */ - -PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, va_list args) { - char *msg = NULL, *xml = NULL; - int msglen = 0, xmllen = 0; - int len; - va_list argcpy; - - if (strfmt != NULL && strlen(strfmt) > 0L) { - va_copy(argcpy, args); - msglen = phpdbg_xml_vasprintf(&msg, strfmt, 0, argcpy TSRMLS_CC); - va_end(argcpy); - } - - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - if (xmlfmt != NULL && strlen(xmlfmt) > 0L) { - va_copy(argcpy, args); - xmllen = phpdbg_xml_vasprintf(&xml, xmlfmt, 1, argcpy TSRMLS_CC); - va_end(argcpy); - } else { - xml = estrdup(""); - } - } - - if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) { - PHPDBG_G(err_buf).type = type; - PHPDBG_G(err_buf).fd = fd; - PHPDBG_G(err_buf).tag = estrdup(tag); - PHPDBG_G(err_buf).msg = msg; - PHPDBG_G(err_buf).msglen = msglen; - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - PHPDBG_G(err_buf).xml = xml; - PHPDBG_G(err_buf).xmllen = xmllen; - } - - return msglen; - } - - len = phpdbg_process_print(fd, type, tag, msg, msglen, xml, xmllen TSRMLS_CC); - - if (msg) { - efree(msg); - } - - if (xml) { - efree(xml); - } - - return len; -} - -PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D) { - if (PHPDBG_G(err_buf).type == 0) { - return; - } - - PHPDBG_G(err_buf).type = 0; - - efree(PHPDBG_G(err_buf).tag); - efree(PHPDBG_G(err_buf).msg); - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - efree(PHPDBG_G(err_buf).xml); - } -} - -PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC) { - PHPDBG_G(err_buf).active = active; -} - -PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt TSRMLS_DC, ...) { - int len; - va_list args; - int errbuf_active = PHPDBG_G(err_buf).active; - - PHPDBG_G(err_buf).active = 0; - -#ifdef ZTS - va_start(args, tsrm_ls); -#else - va_start(args, strfmt); -#endif - len = phpdbg_vprint(PHPDBG_G(err_buf).type TSRMLS_CC, PHPDBG_G(err_buf).fd, tag ? tag : PHPDBG_G(err_buf).tag, xmlfmt, strfmt, args); - va_end(args); - - PHPDBG_G(err_buf).active = errbuf_active; - phpdbg_free_err_buf(TSRMLS_C); - - return len; -} - -PHPDBG_API int phpdbg_print(int type TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) { - va_list args; - int len; - - va_start(args, strfmt); - len = phpdbg_vprint(type TSRMLS_CC, fd, tag, xmlfmt, strfmt, args); - va_end(args); - - return len; -} - -PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) { - int len = 0; - - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - va_list args; - char *buffer; - int buflen; - - va_start(args, fmt); - buflen = phpdbg_xml_vasprintf(&buffer, fmt, 1, args TSRMLS_CC); - va_end(args); - - phpdbg_encode_ctrl_chars(&buffer, &buflen); - - if (PHPDBG_G(in_script_xml)) { - phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); - PHPDBG_G(in_script_xml) = 0; - } - - len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); - efree(buffer); - } - - return len; -} - -PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...) { - va_list args; - char *buffer; - int buflen; - int len = 0; - - va_start(args, fmt); - buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); - va_end(args); - - len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); - efree(buffer); - - return len; -} - -PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { - va_list args; - char *buffer; - int buflen; - int len = 0; - - va_start(args, fmt); - buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); - va_end(args); - - if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { - char *msg; - int msglen; - - msglen = phpdbg_encode_xml(&msg, buffer, buflen, 256, NULL); - phpdbg_encode_ctrl_chars(&msg, &msglen); - phpdbg_eol_convert(&msg, &msglen TSRMLS_CC); - - if (PHPDBG_G(in_script_xml)) { - phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); - PHPDBG_G(in_script_xml) = 0; - } - - phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); - len = phpdbg_mixed_write(fd, msg, msglen TSRMLS_CC); - phpdbg_mixed_write(fd, ZEND_STRL("") TSRMLS_CC); - } else { - phpdbg_eol_convert(&buffer, &buflen TSRMLS_CC); - len = phpdbg_mixed_write(fd, buffer, buflen TSRMLS_CC); - } - - return len; -} - - -PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...) { /* {{{ */ - int rc = 0; - - va_list args; - struct timeval tp; - - va_start(args, fmt); - if (gettimeofday(&tp, NULL) == SUCCESS) { - char friendly[100]; - char *format = NULL, *buffer = NULL, *outbuf = NULL; - const time_t tt = tp.tv_sec; - -#ifdef PHP_WIN32 - strftime(friendly, 100, "%a %b %d %H.%%04d %Y", localtime(&tt)); -#else - strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt)); -#endif - phpdbg_asprintf(&buffer, friendly, tp.tv_usec/1000); - phpdbg_asprintf(&format, "[%s]: %s\n", buffer, fmt); - rc = phpdbg_xml_vasprintf(&outbuf, format, 0, args TSRMLS_CC); - - if (outbuf) { - rc = phpdbg_mixed_write(fd, outbuf, rc TSRMLS_CC); - efree(outbuf); - } - - efree(format); - efree(buffer); - } - va_end(args); - - return rc; -} /* }}} */ - PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_length TSRMLS_DC) /* {{{ */ { const phpdbg_color_t *color = colors; diff --git a/phpdbg_utils.h b/phpdbg_utils.h index cee39c4879f..52338c18363 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -33,64 +33,6 @@ PHPDBG_API char *phpdbg_resolve_path(const char* TSRMLS_DC); PHPDBG_API char *phpdbg_trim(const char*, size_t, size_t*); PHPDBG_API const zend_function *phpdbg_get_function(const char*, const char* TSRMLS_DC); -/** - * Error/notice/formatting helpers - */ -enum { - P_ERROR = 1, - P_NOTICE, - P_WRITELN, - P_WRITE, - P_STDOUT, - P_STDERR, - P_LOG -}; - -#ifdef ZTS -PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 6, 7); -#else -PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 5, 6); -#endif - -PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...); -PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...); -PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...); - -PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...); -#define phpdbg_rlog(fd, fmt, ...) phpdbg_rlog_internal(fd TSRMLS_CC, fmt, ##__VA_ARGS__) - -#define phpdbg_error(tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) -#define phpdbg_notice(tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) -#define phpdbg_writeln(tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) -#define phpdbg_write(tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) -#define phpdbg_script(type, fmt, ...) phpdbg_print(type TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, NULL, NULL, fmt, ##__VA_ARGS__) -#define phpdbg_log(fmt, ...) phpdbg_log_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) -#define phpdbg_xml(fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) -#define phpdbg_out(fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) - -#define phpdbg_error_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) -#define phpdbg_notice_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) -#define phpdbg_writeln_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) -#define phpdbg_write_ex(out, tag, xmlfmt, strfmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, out, tag, xmlfmt, strfmt, ##__VA_ARGS__) -#define phpdbg_script_ex(out, type, fmt, ...) phpdbg_print(type TSRMLS_CC, out, NULL, NULL, fmt, ##__VA_ARGS__) -#define phpdbg_log_ex(out, fmt, ...) phpdbg_log_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) -#define phpdbg_xml_ex(out, fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) -#define phpdbg_out_ex(out, fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) - -#if PHPDBG_DEBUG -# define phpdbg_debug(fmt, ...) phpdbg_log_ex(PHPDBG_G(io)[PHPDBG_STDERR].fd TSRMLS_CC, fmt, ##__VA_ARGS__) -#else -# define phpdbg_debug(fmt, ...) -#endif - -PHPDBG_API void phpdbg_free_err_buf(TSRMLS_D); -PHPDBG_API void phpdbg_activate_err_buf(zend_bool active TSRMLS_DC); -PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt TSRMLS_DC, ...); - - -/* {{{ For separation */ -#define SEPARATE "------------------------------------------------" /* }}} */ - /* {{{ Color Management */ #define PHPDBG_COLOR_LEN 12 #define PHPDBG_COLOR_D(color, code) \ From 28dcdb2d130d63d4aece862d96fa27c440397705 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 23 Oct 2014 13:23:37 +0200 Subject: [PATCH 115/125] Fix some compiler warnings --- phpdbg_cmd.h | 2 +- phpdbg_io.c | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index e164691e591..3896551c9a2 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -171,7 +171,7 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) #define PHPDBG_COMMAND_ARGS param TSRMLS_CC -#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', NULL, 0} +#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, NULL, NULL, 0} /* * Default Switch Case diff --git a/phpdbg_io.c b/phpdbg_io.c index 019e1e8e1b8..97f0356285c 100644 --- a/phpdbg_io.c +++ b/phpdbg_io.c @@ -41,16 +41,12 @@ #include #endif #include - #include - #include #endif - ZEND_EXTERN_MODULE_GLOBALS(phpdbg); - PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC) { int got_now, i = len, j; char *p = ptr; @@ -117,7 +113,7 @@ recv_once: PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len) { int sent, i = len; - char *p = ptr; + const char *p = ptr; /* XXX poll/select needed here? */ while(i > 0) { sent = send(sock, p, i, 0); From f0254826784df569bfd5ae8aca16a05b04a9aa2e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 23 Oct 2014 17:19:26 +0200 Subject: [PATCH 116/125] Add xml formatted deep dump of return value from ev --- phpdbg_prompt.c | 4 ++ phpdbg_utils.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_utils.h | 2 + xml.md | 83 +++++++++++++++++++++++++++++ 4 files changed, 227 insertions(+) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 6c78ec6d130..82444fbf1d3 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -707,6 +707,10 @@ PHPDBG_COMMAND(ev) /* {{{ */ zend_try { if (zend_eval_stringl(param->str, param->len,&retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { phpdbg_xml(""); + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { + zval *zvp = &retval; + phpdbg_xml_var_dump(&zvp TSRMLS_CC); + } zend_print_zval_r(&retval, 0 TSRMLS_CC); phpdbg_xml(""); phpdbg_out("\n"); diff --git a/phpdbg_utils.c b/phpdbg_utils.c index fa4b8b0baa0..6dfec7d272d 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -19,6 +19,7 @@ */ #include "zend.h" + #include "php.h" #include "phpdbg.h" #include "phpdbg_opcode.h" @@ -502,3 +503,140 @@ PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable phpdbg_error("variable", "type=\"invalidinput\"", "Malformed input"); return FAILURE; } + +static int phpdbg_xml_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) { + phpdbg_xml("nKeyLength == 0) { /* numeric key */ + phpdbg_xml(" name=\"%ld\"", hash_key->h); + } else { /* string key */ + phpdbg_xml(" name=\"%.*s\"", hash_key->arKey, hash_key->nKeyLength - 1); + } + } phpdbg_catch_access { + phpdbg_xml(" severity=\"error\" >"); + return 0; + } phpdbg_end_try_access(); + + phpdbg_xml(">"); + + phpdbg_xml_var_dump(zv TSRMLS_CC); + + phpdbg_xml(""); + + return 0; +} + +static int phpdbg_xml_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) { + phpdbg_xml("nKeyLength == 0) { /* numeric key */ + phpdbg_xml(" name=\"%ld\"", hash_key->h); + } else { /* string key */ + const char *prop_name, *class_name; + int unmangle = zend_unmangle_property_name(hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name); + + if (class_name && unmangle == SUCCESS) { + phpdbg_xml(" name=\"%s\"", prop_name); + if (class_name[0] == '*') { + phpdbg_xml(" protection=\"protected\""); + } else { + phpdbg_xml("class=\"%s\" protection=\"private\"", class_name); + } + } else { + phpdbg_xml(" name=\"%.*s\" protection=\"public\"", hash_key->arKey, hash_key->nKeyLength - 1); + } + } + } phpdbg_catch_access { + phpdbg_xml(" severity=\"error\" >"); + return 0; + } phpdbg_end_try_access(); + + phpdbg_xml(">"); + + phpdbg_xml_var_dump(zv TSRMLS_CC); + + phpdbg_xml(""); + + return 0; +} + +#define COMMON (Z_ISREF_PP(zv) ? "&" : "") + +PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) { + HashTable *myht; + const char *class_name; + zend_uint class_name_len; + int (*element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*); + int is_temp; + + phpdbg_try_access { + switch (Z_TYPE_PP(zv)) { + case IS_BOOL: + phpdbg_xml("", COMMON, Z_LVAL_PP(zv) ? "true" : "false"); + break; + case IS_NULL: + phpdbg_xml("", COMMON); + break; + case IS_LONG: + phpdbg_xml("", COMMON, Z_LVAL_PP(zv)); + break; + case IS_DOUBLE: + php_printf("", COMMON, (int) EG(precision), Z_DVAL_PP(zv)); + break; + case IS_STRING: + php_printf("", COMMON, Z_STRLEN_PP(zv), Z_STRLEN_PP(zv), Z_STRVAL_PP(zv)); + break; + case IS_ARRAY: + myht = Z_ARRVAL_PP(zv); + if (++myht->nApplyCount > 1) { + phpdbg_xml(""); + --myht->nApplyCount; + break; + } + phpdbg_xml("", COMMON, zend_hash_num_elements(myht)); + element_dump_func = phpdbg_xml_array_element_dump; + is_temp = 0; + goto head_done; + case IS_OBJECT: + myht = Z_OBJDEBUG_PP(zv, is_temp); + if (myht && ++myht->nApplyCount > 1) { + phpdbg_xml(""); + --myht->nApplyCount; + break; + } + + if (Z_OBJ_HANDLER(**zv, get_class_name)) { + Z_OBJ_HANDLER(**zv, get_class_name)(*zv, &class_name, &class_name_len, 0 TSRMLS_CC); + phpdbg_xml("", COMMON, class_name, Z_OBJ_HANDLE_PP(zv), myht ? zend_hash_num_elements(myht) : 0); + efree((char*)class_name); + } else { + phpdbg_xml("", COMMON, Z_OBJ_HANDLE_PP(zv), myht ? zend_hash_num_elements(myht) : 0); + } + element_dump_func = phpdbg_xml_object_property_dump; +head_done: + if (myht) { + zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) element_dump_func, 0); + --myht->nApplyCount; + if (is_temp) { + zend_hash_destroy(myht); + efree(myht); + } + } + if (Z_TYPE_PP(zv) == IS_ARRAY) { + phpdbg_xml(""); + } else { + phpdbg_xml(""); + } + break; + case IS_RESOURCE: { + const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(zv) TSRMLS_CC); + phpdbg_xml("", COMMON, Z_LVAL_PP(zv), type_name ? type_name : "unknown"); + break; + } + default: + break; + } + } phpdbg_end_try_access(); +} diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 52338c18363..d657dc79fd9 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -110,4 +110,6 @@ typedef int (*phpdbg_parse_var_with_arg_func)(char *name, size_t len, char *keyn PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, zend_bool silent TSRMLS_DC); PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, zend_bool silent, void *arg TSRMLS_DC); +PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC); + #endif /* PHPDBG_UTILS_H */ diff --git a/xml.md b/xml.md index 05734d6be89..9d3b83f8269 100644 --- a/xml.md +++ b/xml.md @@ -60,6 +60,7 @@ type - general attribute for most errors, describes the genre of the error + General tags ============ @@ -460,6 +461,7 @@ ev - eval()uates some code - output wrapped in <eval> tags +- output is here first a dump of xml tags (see "Variable Dump" section), then a dump wrapped in tags sh -- @@ -633,6 +635,7 @@ dl - errors may have the module or extension attribute when their name is already known at the point of failure + Other tags ========== @@ -673,3 +676,83 @@ Other tags - generally emitted when data couldn't be fetched (e.g. by accessing inconsistent data); only used in hard interrupt mode - it might mean that data couldn't be fetched at all, or that only incomplete data was fetched (e.g. when a fixed number of following attributes are fetched, this tag will mark a stop of fetching if none or not all tags were printed) + + +Variable Dump +============= + +- all except property and element tags have a refstatus attribute, is set to non-empty if it's a reference + +object properties +----------------- + +- wrapped in a property tag <property name="" protection=""> + - name: name of key + - protection: one of these three values: public / protected / private + - class: only present if protection attribute is set to "private", contains the name of the class to which the property belongs +- if the property tag contains any serverity="error" attribute, there was some crucial error to read it, just skip it + +array elements +-------------- +- wrapped in an element tag <property name="" protection=""> + - name: name of key +- if the element tag contains any serverity="error" attribute, there was some crucial error to read it, jsut skip it + +int +--- + +- <int refstatus="" value="" /> + - value is the integer + +float +----- + +- <float refstatus="" value="" /> + - value is the float + +bool +---- + +- <bool refstatus="" value="" /> + -value: true or false + +string +------ + +- <string refstatus="" length="" value="" /> + - length: length or string + - value: the string + +null +---- + +- <null refstatus="" /> + +array +----- + +- <array refstatus="" num=""> + - num: number of elements + - contains <element> tags + +object +------ + +- <object refstatus="" class="" id="" num=""> + - class: name of the class the object is an instance of (may be empty if unknown) + - id: id of the object + - num: number of properties + - contains <property> tags + +resource +-------- + +- <resource refstatus="" id="" type="" /> + - id: resource id + - type: type of resource + +recursion +--------- + +- <recursion /> +- if that tag appears, there's a recursive reference inside the value to be printed From 23a408a51bf17dad1918eb6c6c14089cb76376b9 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 23 Oct 2014 20:14:12 +0200 Subject: [PATCH 117/125] Too much copypaste... --- phpdbg_utils.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 6dfec7d272d..448aad3b3ab 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -583,10 +583,10 @@ PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) { phpdbg_xml("", COMMON, Z_LVAL_PP(zv)); break; case IS_DOUBLE: - php_printf("", COMMON, (int) EG(precision), Z_DVAL_PP(zv)); + phpdbg_xml("", COMMON, (int) EG(precision), Z_DVAL_PP(zv)); break; case IS_STRING: - php_printf("", COMMON, Z_STRLEN_PP(zv), Z_STRLEN_PP(zv), Z_STRVAL_PP(zv)); + phpdbg_xml("", COMMON, Z_STRLEN_PP(zv), Z_STRLEN_PP(zv), Z_STRVAL_PP(zv)); break; case IS_ARRAY: myht = Z_ARRVAL_PP(zv); @@ -603,7 +603,7 @@ PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) { myht = Z_OBJDEBUG_PP(zv, is_temp); if (myht && ++myht->nApplyCount > 1) { phpdbg_xml(""); - --myht->nApplyCount; + --myht->nApplyCount; break; } @@ -621,7 +621,7 @@ head_done: --myht->nApplyCount; if (is_temp) { zend_hash_destroy(myht); - efree(myht); + efree(myht); } } if (Z_TYPE_PP(zv) == IS_ARRAY) { @@ -634,7 +634,7 @@ head_done: const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(zv) TSRMLS_CC); phpdbg_xml("", COMMON, Z_LVAL_PP(zv), type_name ? type_name : "unknown"); break; - } + } default: break; } From 56b3eda3772b0e538ccbe6d4d04a0f6cc897b7a2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 24 Oct 2014 12:32:48 +0200 Subject: [PATCH 118/125] Fixed parameter order on %.*s --- phpdbg_utils.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 448aad3b3ab..8ff010076d5 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -511,7 +511,7 @@ static int phpdbg_xml_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_l if (hash_key->nKeyLength == 0) { /* numeric key */ phpdbg_xml(" name=\"%ld\"", hash_key->h); } else { /* string key */ - phpdbg_xml(" name=\"%.*s\"", hash_key->arKey, hash_key->nKeyLength - 1); + phpdbg_xml(" name=\"%.*s\"", hash_key->nKeyLength - 1, hash_key->arKey); } } phpdbg_catch_access { phpdbg_xml(" severity=\"error\" >"); @@ -545,7 +545,7 @@ static int phpdbg_xml_object_property_dump(zval **zv TSRMLS_DC, int num_args, va phpdbg_xml("class=\"%s\" protection=\"private\"", class_name); } } else { - phpdbg_xml(" name=\"%.*s\" protection=\"public\"", hash_key->arKey, hash_key->nKeyLength - 1); + phpdbg_xml(" name=\"%.*s\" protection=\"public\"", hash_key->nKeyLength - 1, hash_key->arKey); } } } phpdbg_catch_access { @@ -583,10 +583,10 @@ PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) { phpdbg_xml("", COMMON, Z_LVAL_PP(zv)); break; case IS_DOUBLE: - phpdbg_xml("", COMMON, (int) EG(precision), Z_DVAL_PP(zv)); + php_printf("", COMMON, (int) EG(precision), Z_DVAL_PP(zv)); break; case IS_STRING: - phpdbg_xml("", COMMON, Z_STRLEN_PP(zv), Z_STRLEN_PP(zv), Z_STRVAL_PP(zv)); + php_printf("", COMMON, Z_STRLEN_PP(zv), Z_STRLEN_PP(zv), Z_STRVAL_PP(zv)); break; case IS_ARRAY: myht = Z_ARRVAL_PP(zv); @@ -603,7 +603,7 @@ PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) { myht = Z_OBJDEBUG_PP(zv, is_temp); if (myht && ++myht->nApplyCount > 1) { phpdbg_xml(""); - --myht->nApplyCount; + --myht->nApplyCount; break; } @@ -621,7 +621,7 @@ head_done: --myht->nApplyCount; if (is_temp) { zend_hash_destroy(myht); - efree(myht); + efree(myht); } } if (Z_TYPE_PP(zv) == IS_ARRAY) { @@ -634,7 +634,7 @@ head_done: const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(zv) TSRMLS_CC); phpdbg_xml("", COMMON, Z_LVAL_PP(zv), type_name ? type_name : "unknown"); break; - } + } default: break; } From 9ce03bc7da95a5448bd478f6f538fe75629bf57c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 24 Oct 2014 12:55:44 +0200 Subject: [PATCH 119/125] Fix output to wrong function --- phpdbg_bp.c | 8 ++++---- phpdbg_out.h | 18 +++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 26e6ee29713..81674a0daf1 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -1414,10 +1414,10 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ case PHPDBG_BREAK_METHOD_OPLINE: case PHPDBG_BREAK_FUNCTION_OPLINE: case PHPDBG_BREAK_FILE_OPLINE: - phpdbg_out("opline", "id=\"%d\" num=\"%#lx\" type=\"%s\" disabled=\"%s\"", "#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline, - brake->type == PHPDBG_BREAK_METHOD_OPLINE?"method": - brake->type == PHPDBG_BREAK_FUNCTION_OPLINE?"function": - brake->type == PHPDBG_BREAK_FILE_OPLINE?"file": + phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" type=\"%s\" disabled=\"%s\"", "#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline, + brake->type == PHPDBG_BREAK_METHOD_OPLINE ? "method" : + brake->type == PHPDBG_BREAK_FUNCTION_OPLINE ? "function" : + brake->type == PHPDBG_BREAK_FILE_OPLINE ? "file" : "--- error ---", ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); break; diff --git a/phpdbg_out.h b/phpdbg_out.h index d94fbd73852..ea25b04279d 100644 --- a/phpdbg_out.h +++ b/phpdbg_out.h @@ -36,16 +36,18 @@ enum { #ifdef ZTS PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 6, 7); +PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); #else -PHPDBG_API int phpdbg_print(int severity TSRMLS_DC, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 5, 6); +PHPDBG_API int phpdbg_print(int severity, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 5, 6); +PHPDBG_API int phpdbg_xml_internal(int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); +PHPDBG_API int phpdbg_log_internal(int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); +PHPDBG_API int phpdbg_out_internal(int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); +PHPDBG_API int phpdbg_rlog_internal(int fd, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); #endif -PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...); -PHPDBG_API int phpdbg_log_internal(int fd TSRMLS_DC, const char *fmt, ...); -PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...); - -PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...); -#define phpdbg_rlog(fd, fmt, ...) phpdbg_rlog_internal(fd TSRMLS_CC, fmt, ##__VA_ARGS__) #define phpdbg_error(tag, xmlfmt, strfmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) #define phpdbg_notice(tag, xmlfmt, strfmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT].fd, tag, xmlfmt, strfmt, ##__VA_ARGS__) @@ -65,6 +67,8 @@ PHPDBG_API int phpdbg_rlog_internal(int fd TSRMLS_DC, const char *fmt, ...); #define phpdbg_xml_ex(out, fmt, ...) phpdbg_xml_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) #define phpdbg_out_ex(out, fmt, ...) phpdbg_out_internal(PHPDBG_G(io)[PHPDBG_STDOUT].fd TSRMLS_CC, fmt, ##__VA_ARGS__) +#define phpdbg_rlog(fd, fmt, ...) phpdbg_rlog_internal(fd TSRMLS_CC, fmt, ##__VA_ARGS__) + #define phpdbg_xml_asprintf(buf, ...) _phpdbg_xml_asprintf(buf TSRMLS_CC, ##__VA_ARGS__) PHPDBG_API int _phpdbg_xml_asprintf(char **buf TSRMLS_DC, const char *format, zend_bool escape_xml, ...); From b0089e3c2f649af08d27acf6762c4f4a166f9710 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 24 Oct 2014 13:11:14 +0200 Subject: [PATCH 120/125] Do not print out xml as PHP print... --- phpdbg_utils.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 8ff010076d5..bbc8b0c1d93 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -583,10 +583,10 @@ PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) { phpdbg_xml("", COMMON, Z_LVAL_PP(zv)); break; case IS_DOUBLE: - php_printf("", COMMON, (int) EG(precision), Z_DVAL_PP(zv)); - break; + phpdbg_xml("", COMMON, (int) EG(precision), Z_DVAL_PP(zv)); + break; case IS_STRING: - php_printf("", COMMON, Z_STRLEN_PP(zv), Z_STRLEN_PP(zv), Z_STRVAL_PP(zv)); + phpdbg_xml("", COMMON, Z_STRLEN_PP(zv), Z_STRLEN_PP(zv), Z_STRVAL_PP(zv)); break; case IS_ARRAY: myht = Z_ARRVAL_PP(zv); @@ -601,9 +601,9 @@ PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) { goto head_done; case IS_OBJECT: myht = Z_OBJDEBUG_PP(zv, is_temp); - if (myht && ++myht->nApplyCount > 1) { + if (myht && ++myht->nApplyCount > 1) { phpdbg_xml(""); - --myht->nApplyCount; + --myht->nApplyCount; break; } @@ -621,11 +621,11 @@ head_done: --myht->nApplyCount; if (is_temp) { zend_hash_destroy(myht); - efree(myht); + efree(myht); } } if (Z_TYPE_PP(zv) == IS_ARRAY) { - phpdbg_xml(""); + phpdbg_xml(""); } else { phpdbg_xml(""); } @@ -634,7 +634,7 @@ head_done: const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(zv) TSRMLS_CC); phpdbg_xml("", COMMON, Z_LVAL_PP(zv), type_name ? type_name : "unknown"); break; - } + } default: break; } From 9053b8a4d4a4ea0d59e2300f7a6b29b6cbcdcad5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 24 Oct 2014 14:16:49 +0200 Subject: [PATCH 121/125] Name the tag if the error id during ev cmd --- phpdbg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpdbg.c b/phpdbg.c index 88313585b56..f09dc4ee13d 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -463,6 +463,11 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */ * We must not request TSRM before being boot */ if (phpdbg_booted) { + if (PHPDBG_G(flags) & PHPDBG_IN_EVAL) { + phpdbg_error("eval", "msg=\"%s\"", "%s", message); + return; + } + phpdbg_error("php", "msg=\"%s\"", "%s", message); switch (PG(last_error_type)) { From 87c055e95e034f872da05d78dfc5191ba6cc771e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 24 Oct 2014 14:18:02 +0200 Subject: [PATCH 122/125] Add note about tag for errors in xml.md --- xml.md | 1 + 1 file changed, 1 insertion(+) diff --git a/xml.md b/xml.md index 9d3b83f8269..0556fb24152 100644 --- a/xml.md +++ b/xml.md @@ -462,6 +462,7 @@ ev - eval()uates some code - output wrapped in <eval> tags - output is here first a dump of xml tags (see "Variable Dump" section), then a dump wrapped in tags +- if there's an error, the tag will be , instead of the usual tag sh -- From dc61a5c359d84c8963bc2ff1b7b0fc2200caf64a Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 24 Oct 2014 14:29:06 +0200 Subject: [PATCH 123/125] Fix info classes file name in xml --- phpdbg_info.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/phpdbg_info.c b/phpdbg_info.c index d523968dca2..4774fa5a9e7 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -433,9 +433,7 @@ PHPDBG_INFO(classes) /* {{{ */ } if ((*ce)->info.user.filename) { - phpdbg_writeln("classsource", "file=\"\" line=\"%u\"", "|---- in %s on line %u", - (*ce)->info.user.filename, - (*ce)->info.user.line_start); + phpdbg_writeln("classsource", "file=\"%s\" line=\"%u\"", "|---- in %s on line %u", (*ce)->info.user.filename, (*ce)->info.user.line_start); } else { phpdbg_writeln("classsource", "", "|---- no source code"); } From 36399428919ef518bcd744e120e48c00610a8b86 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 24 Oct 2014 14:42:18 +0200 Subject: [PATCH 124/125] Make xml valid (missing space between attrs) --- phpdbg_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_utils.c b/phpdbg_utils.c index bbc8b0c1d93..85b6eeb3b52 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -542,7 +542,7 @@ static int phpdbg_xml_object_property_dump(zval **zv TSRMLS_DC, int num_args, va if (class_name[0] == '*') { phpdbg_xml(" protection=\"protected\""); } else { - phpdbg_xml("class=\"%s\" protection=\"private\"", class_name); + phpdbg_xml(" class=\"%s\" protection=\"private\"", class_name); } } else { phpdbg_xml(" name=\"%.*s\" protection=\"public\"", hash_key->nKeyLength - 1, hash_key->arKey); From c03ac47bafd0ea55055a2f3d4de0bc6bb4d98d8d Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 24 Oct 2014 19:26:04 +0200 Subject: [PATCH 125/125] Added some NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 1947e2aa688..b1d56ac0f5b 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,10 @@ PHP NEWS array notation) (Florian) . Implemented 64-bit format codes for pack() and unpack(). (Leigh) +- phpdbg: + . Added XML protocol (-x command line flag). (Bob) + . Added hard interruptions (twice SIGINT). (Bob) + - Fileinfo: . Fixed bug #66242 (libmagic: don't assume char is signed). (ArdB) . Fixed bug #68224 (buffer-overflow in libmagic/readcdf.c caught by