]> granicus.if.org Git - php/commitdiff
remove leaks from stack
authorkrakjoe <joe.watkins@live.co.uk>
Sun, 16 Feb 2014 21:38:55 +0000 (21:38 +0000)
committerkrakjoe <joe.watkins@live.co.uk>
Sun, 16 Feb 2014 21:38:55 +0000 (21:38 +0000)
traverse the other way
fix id regex, thanks @bwoebi

phpdbg_cmd.h
phpdbg_lexer.l
phpdbg_parser.y

index 6eb4e73e904c0536f17c8f96dca8f99cc678d4c0..698c1b55449400239ef1e884659f62e9f9aeb314 100644 (file)
@@ -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);
index 3b6c9cae27ea6333276ee11164bf79d3b273cbf2..a078f4c40ff41422573082f35ef319e6578aa574 100644 (file)
@@ -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]+
index dfc13a48e15c1073fbaa1fa70ab1db158a29c518..e0819fe6e158e9e8ec6ba52c14544a08b89acbc3 100644 (file)
 
 #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