From: krakjoe Date: Tue, 19 Nov 2013 12:39:48 +0000 (+0000) Subject: tidy up reading input, avoid leaks, restore sanity X-Git-Tag: php-5.6.0alpha1~110^2~205 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d906613eb56f67349132cfe74b2a1679fbe332d9;p=php tidy up reading input, avoid leaks, restore sanity --- diff --git a/phpdbg.h b/phpdbg.h index ae42ca65dd..889639a2ec 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -108,6 +108,7 @@ #define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues" #define PHPDBG_VERSION "0.0.2-dev" /* }}} */ +/* {{{ structs */ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ char *exec; /* file to execute */ @@ -122,7 +123,6 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable seek; /* seek oplines */ zend_ulong flags; /* phpdbg flags */ HashTable registered; /* registered */ -ZEND_END_MODULE_GLOBALS(phpdbg) -/* }}} */ +ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ #endif /* PHPDBG_H */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index ca99148664..93f57a8891 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -118,6 +118,62 @@ void phpdbg_clear_param(phpdbg_param_t *param TSRMLS_DC) /* {{{ */ } /* }}} */ +phpdbg_input_t* phpdbg_read_input(TSRMLS_D) /* {{{ */ +{ + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + phpdbg_input_t *buffer = NULL; + size_t cmd_len = 0L; + +#ifndef HAVE_LIBREADLINE + char *cmd = NULL; + char buf[PHPDBG_MAX_CMD]; + if (!phpdbg_write(PROMPT) || + !fgets(buf, PHPDBG_MAX_CMD, stdin)) { + return NULL; + } + + cmd = buf; +#else + char *cmd = readline(PROMPT); + if (!cmd) { + return NULL; + } + + add_history(cmd); +#endif + + /* strip whitespace */ + while (cmd && isspace(*cmd)) + cmd++; + cmd_len = strlen(cmd); + while (*cmd && isspace(cmd[cmd_len-1])) + cmd_len--; + cmd[cmd_len] = '\0'; + + /* allocate and sanitize buffer */ + buffer = (phpdbg_input_t*) emalloc(sizeof(phpdbg_input_t)); + if (buffer) { + buffer->length = strlen(cmd); + buffer->string = emalloc(buffer->length+1); + if (buffer->string) { + memcpy( + buffer->string, cmd, buffer->length); + buffer->string[buffer->length] = '\0'; + } + } + +#ifdef HAVE_LIBREADLINE + if (cmd) { + free(cmd); + } +#endif + + return buffer; + } + + return NULL; +} /* }}} */ + int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */ { int rc = FAILURE; diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 37341923de..7764b5d8f1 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -40,6 +40,11 @@ typedef enum { NUMERIC_PARAM } phpdbg_param_type; +typedef struct { + char *string; + size_t length; +} phpdbg_input_t; + typedef struct _phpdbg_param { phpdbg_param_type type; long num; @@ -71,10 +76,12 @@ struct _phpdbg_command_t { /* }}} */ #define PHPDBG_STRL(s) s, sizeof(s)-1 +#define PHPDBG_MAX_CMD 500 /** * Command Executor */ +phpdbg_input_t* phpdbg_read_input(TSRMLS_D); int phpdbg_do_cmd(const phpdbg_command_t*, char*, size_t TSRMLS_DC); phpdbg_param_type phpdbg_parse_param(const char*, size_t, phpdbg_param_t* TSRMLS_DC); void phpdbg_clear_param(phpdbg_param_t* TSRMLS_DC); @@ -95,6 +102,9 @@ const char* phpdbg_get_param_type(const phpdbg_param_t* TSRMLS_DC); #define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'} +/* +* Default Switch Case +*/ #define phpdbg_default_switch_case() \ default:\ phpdbg_error(\ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index d9f8a257ca..01f57f24b8 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -910,7 +910,7 @@ static PHPDBG_COMMAND(list) /* {{{ */ return SUCCESS; } /* }}} */ -static inline int phpdbg_call_register(const char *cmd, size_t cmd_len, const char * start TSRMLS_DC) +static inline int phpdbg_call_register(const char *cmd, size_t cmd_len, const char * start TSRMLS_DC) /* {{{ */ { size_t offset = strlen(cmd)+(sizeof(" ")-1); @@ -957,84 +957,51 @@ static inline int phpdbg_call_register(const char *cmd, size_t cmd_len, const ch } return FAILURE; -} +} /* }}} */ int phpdbg_interactive(TSRMLS_D) /* {{{ */ { - size_t cmd_len; int ret = SUCCESS; - char* const* start; - -#ifndef HAVE_LIBREADLINE - char cmd[PHPDBG_MAX_CMD]; - - while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING) && - phpdbg_write(PROMPT) && - (fgets(cmd, PHPDBG_MAX_CMD, stdin) != NULL)) { - cmd_len = strlen(cmd) - 1; -#else - char *cmd = NULL; - - while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - cmd = readline(PROMPT); - cmd_len = cmd ? strlen(cmd) : 0; -#endif - - start = (char* const*) cmd; - - /* trim space from end of input */ - while (*cmd && isspace(cmd[cmd_len-1])) - cmd_len--; - - /* ensure string is null terminated */ - cmd[cmd_len] = '\0'; - - if (*cmd && cmd_len > 0L) { -#ifdef HAVE_LIBREADLINE - add_history(cmd); -#endif - - switch (ret = phpdbg_do_cmd(phpdbg_prompt_commands, cmd, cmd_len TSRMLS_CC)) { - case FAILURE: - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - if (phpdbg_call_register(cmd, cmd_len, (const char*) start TSRMLS_CC) == FAILURE) { - phpdbg_error("Failed to execute %s!", cmd); - } - } - break; - case PHPDBG_LEAVE: - case PHPDBG_FINISH: - case PHPDBG_UNTIL: - case PHPDBG_NEXT: { - if (!EG(in_execution)) { - phpdbg_error("Not running"); + phpdbg_input_t* input = phpdbg_read_input(TSRMLS_C); + + if (input) { + char* const* saved = (char* const*) input->string; + + switch (ret = phpdbg_do_cmd(phpdbg_prompt_commands, input->string, input->length TSRMLS_CC)) { + case FAILURE: + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if (phpdbg_call_register(input->string, input->length, (const char*) saved TSRMLS_CC) == FAILURE) { + phpdbg_error("Failed to execute %s!", input->string); } - goto out; } - } + break; -#ifdef HAVE_LIBREADLINE - if (cmd) { - free(cmd); - cmd = NULL; - } -#endif - } else { - if (PHPDBG_G(lcmd)) { - ret = PHPDBG_G(lcmd)->handler( - &PHPDBG_G(lparam) TSRMLS_CC); + case PHPDBG_LEAVE: + case PHPDBG_FINISH: + case PHPDBG_UNTIL: + case PHPDBG_NEXT: { + if (!EG(in_execution)) { + phpdbg_error("Not running"); + } goto out; } } + } else { + if (PHPDBG_G(lcmd)) { + ret = PHPDBG_G(lcmd)->handler( + &PHPDBG_G(lparam) TSRMLS_CC); + goto out; + } } out: -#ifdef HAVE_LIBREADLINE - if (cmd) { - free(cmd); + if (input) { + if (input->string) { + efree(input->string); + } + efree(input); } -#endif return ret; } /* }}} */ diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 5f8de2b81d..08997b5346 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -23,8 +23,6 @@ /** * Maximum command length */ -#define PHPDBG_MAX_CMD 500 - void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC); int phpdbg_interactive(TSRMLS_D); void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags TSRMLS_DC);