From a9e0202a5ddb37a4ddcd50490b6e58105c427015 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 16 Feb 2014 21:38:55 +0000 Subject: [PATCH] remove leaks from stack traverse the other way fix id regex, thanks @bwoebi --- phpdbg_cmd.h | 25 +++++----- phpdbg_lexer.l | 4 +- phpdbg_parser.y | 125 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 116 insertions(+), 38 deletions(-) diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 6eb4e73e90..698c1b5544 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -40,7 +40,8 @@ typedef enum { STR_PARAM, NUMERIC_PARAM, NUMERIC_FUNCTION_PARAM, - NUMERIC_METHOD_PARAM + NUMERIC_METHOD_PARAM, + STACK_PARAM } phpdbg_param_type; typedef struct _phpdbg_input_t phpdbg_input_t; @@ -69,19 +70,21 @@ struct _phpdbg_param { char *str; size_t len; phpdbg_param_t *next; + phpdbg_param_t *top; }; #define phpdbg_init_param(v, t) do{ \ - v->type = t; \ - v->addr = 0; \ - v->num = 0; \ - v->file.name = NULL; \ - v->file.line = 0; \ - v->method.class = NULL; \ - v->method.name = NULL; \ - v->str = NULL; \ - v->len = 0; \ - v->next = NULL; \ + (v)->type = (t); \ + (v)->addr = 0; \ + (v)->num = 0; \ + (v)->file.name = NULL; \ + (v)->file.line = 0; \ + (v)->method.class = NULL; \ + (v)->method.name = NULL; \ + (v)->str = NULL; \ + (v)->len = 0; \ + (v)->next = NULL; \ + (v)->top = NULL; \ } while(0) typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*, const phpdbg_input_t* TSRMLS_DC); diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 3b6c9cae27..a078f4c40f 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -33,9 +33,9 @@ C_EVAL "eval" C_SHELL "shell" DIGITS [0-9]+ -ID [a-zA-Z][a-zA-Z0-9_]+ +ID [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* METHOD {ID}::{ID} -FILE [^ :0-9]{1,}:[0-9]+ +FILE [^ :]+:[0-9]+ OPLINE 0x[a-fA-F0-9]+ LITERAL \"(\\.|[^\\"])*\" WS [ \r\n\t]+ diff --git a/phpdbg_parser.y b/phpdbg_parser.y index dfc13a48e1..e0819fe6e1 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -14,6 +14,13 @@ #define YYSTYPE phpdbg_param_t +#include "phpdbg_parser.h" +#include "phpdbg_lexer.h" + +int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { + fprintf(stderr, "Parse Error: %s\n", msg); +} + void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { if (param && param->type) { switch (param->type) { @@ -40,8 +47,38 @@ void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { } } -#include "phpdbg_parser.h" -#include "phpdbg_lexer.h" +static 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 STR_PARAM: + if (remove->str) { + free(remove->str); + } + break; + + case FILE_PARAM: + if (remove->file.name) { + free(remove->file.name); + } + break; + } + + free(remove); + + if (next) + remove = next; + else break; + } + } +} static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); @@ -51,19 +88,51 @@ static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { *(next) = *(param); - if (stack->addr) { - next->next = - stack->next; + if (stack->top == NULL) { + stack->top = next; + stack->next = next; } else { - stack->addr = (ulong) next; + stack->top->next = next; + next->top = stack->top; + stack->top = next; } - stack->next = next; stack->len++; } -int yyerror(phpdbg_param_t **param, yyscan_t scanner, const char *msg) { - fprintf(stderr, "Parse Error: %s\n", msg); +static int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { + phpdbg_param_t *command = NULL, + *params = NULL; + + if (stack->type != STACK_PARAM) { + asprintf( + why, "the passed argument was not a stack !!"); + return FAILURE; + } + + if (!stack->len) { + asprintf( + why, "the stack contains nothing !!"); + return FAILURE; + } + + command = params = (phpdbg_param_t*) stack->next; + + if (command->type != STR_PARAM) { + asprintf( + why, "the first parameter is expected to be a string !!"); + return FAILURE; + } + + /* do resolve command(s) */ + + /* do prepare params for function */ + while (params) { + phpdbg_debug_param(params, "-> ..."); + params = params->next; + } + + return SUCCESS; } int main(int argc, char **argv) { @@ -72,9 +141,9 @@ int main(int argc, char **argv) { YY_BUFFER_STATE state; char buffer[8096]; size_t buflen = 0L; - phpdbg_param_t *stack = malloc(sizeof(phpdbg_param_t)); + phpdbg_param_t stack; - phpdbg_init_param(stack, EMPTY_PARAM); + phpdbg_init_param(&stack, STACK_PARAM); if (fgets(&buffer[0], 8096, stdin) != NULL) { if (yylex_init(&scanner)) { @@ -85,17 +154,23 @@ int main(int argc, char **argv) { state = yy_scan_string(buffer, scanner); if (yyparse(&stack, scanner) <= 0) { - fprintf(stderr, "got stack %p\n", stack); - while (stack) { - phpdbg_debug_param(stack, "\t -> "); - stack = stack->next; + char *why = NULL; + + if (phpdbg_stack_execute(&stack, &why) != SUCCESS) { + fprintf(stderr, + "Execution Error: %s\n", + why ? why : "for no particular reason"); + } + + if (why) { + free(why); } - yy_delete_buffer(state, scanner); - yylex_destroy(scanner); } + yy_delete_buffer(state, scanner); + yylex_destroy(scanner); } else fprintf(stderr, "could not get input !!\n"); - free(stack); + phpdbg_stack_free(&stack); } while (1); return 0; @@ -115,7 +190,7 @@ typedef void* yyscan_t; %define api.pure %lex-param { yyscan_t scanner } -%parse-param { phpdbg_param_t **stack } +%parse-param { phpdbg_param_t *stack } %parse-param { yyscan_t scanner } %token C_TRUTHY "truthy (true, on, yes or enabled)" @@ -139,8 +214,8 @@ input ; parameters - : parameter { phpdbg_stack_push(*stack, &$1); } - | parameters parameter { phpdbg_stack_push(*stack, &$2); } + : parameter { phpdbg_stack_push(stack, &$1); } + | parameters parameter { phpdbg_stack_push(stack, &$2); } ; params @@ -149,13 +224,13 @@ params ; normal - : T_ID { phpdbg_stack_push(*stack, &$1); } - | normal T_ID { phpdbg_stack_push(*stack, &$2); } + : T_ID { phpdbg_stack_push(stack, &$1); } + | normal T_ID { phpdbg_stack_push(stack, &$2); } ; special - : C_EVAL T_INPUT { phpdbg_stack_push(*stack, &$1); phpdbg_stack_push(*stack, &$2); } - | C_SHELL T_INPUT { phpdbg_stack_push(*stack, &$1); phpdbg_stack_push(*stack, &$2); } + : C_EVAL T_INPUT { phpdbg_stack_push(stack, &$1); phpdbg_stack_push(stack, &$2); } + | C_SHELL T_INPUT { phpdbg_stack_push(stack, &$1); phpdbg_stack_push(stack, &$2); } ; command -- 2.40.0