fix invalid free on syntax error
[m6w6/ext-psi] / src / parser_proc_grammar.y
index fc0b75210aad1c9bee15ec96aa19f11745804624..5c2e24dc2d3f9992a33eef5bd995d0e27816b685 100644 (file)
@@ -1,4 +1,9 @@
 %code top {
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
 }
 
 %code {
@@ -385,7 +390,7 @@ struct psi_parser;
 %type          <struct psi_token **>                           impl_stmt
 %destructor    {psi_impl_stmt_free(&$$);}                      impl_stmt
 %type          <struct psi_token *>                            impl_type_token impl_type_restricted_token impl_type_extended_token callback_rval let_func_token set_func_token assert_stmt_token
-%destructor    {psi_token_free(&$$);}                          impl_type_token impl_type_restricted_token impl_type_extended_token callback_rval let_func_token set_func_token assert_stmt_token
+%destructor    {}                                                                      impl_type_token impl_type_restricted_token impl_type_extended_token callback_rval let_func_token set_func_token assert_stmt_token
 %type          <struct psi_plist *>                            impl_args impl_stmts let_exps let_func_exps callback_arg_list callback_args set_exps set_func_exps free_exps
 %destructor    {psi_plist_free($$);}                           impl_args impl_stmts let_exps let_func_exps callback_arg_list callback_args set_exps set_func_exps free_exps
 
@@ -2291,7 +2296,7 @@ static int psi_parser_proc_lex(YYSTYPE *lvalp, struct psi_parser *P, struct psi_
 #if PSI_DEBUG_LEX
        PSI_DEBUG_PRINT(P, "PSI: LEX index %4zu ", *index);
 #endif
-       if (psi_plist_get(tokens, (*index)++, &token)) {
+       if (psi_plist_get(tokens, (*index)++, &token) && token) {
 #if PSI_DEBUG_LEX      
                PSI_DEBUG_DUMP(P, psi_token_dump, token);
 #endif
@@ -2324,11 +2329,22 @@ static void psi_parser_proc_error(struct psi_parser *P, struct psi_plist *tokens
                
                P->error(PSI_DATA(P), T, PSI_WARNING, "PSI %s at col %u", msg, T->col);
                while (i <= last || T->type != PSI_T_EOS) {
+                       const char *pos;
+                       
                        if (!psi_plist_get(tokens, i++, &T)) {
                                break;
                        }
+                       
+                       if (i < last + 1) {
+                               pos = "preceding";
+                       } else if (i > last + 1) {
+                               pos = "following";
+                       } else {
+                               pos = "offending";
+                       }
+                       
                        P->error(PSI_DATA(P), T, PSI_WARNING, "PSI %s token '%s' at col %u", 
-                                       i<last+1?"preceding":i>last+1?"following":"offending", T->text->val, T->col);
+                                       pos, T ? T->text->val : "<deleted>", T ? T->col : 0);
                }
        } else {
                P->error(PSI_DATA(P), NULL, PSI_WARNING, "PSI %s", msg);