The common paradigm here is that all parser rules converting string
tokens into symbols must free the string token if it's not used anymore.
This is unrelated to the %destructor directive, since that will apply
only if the parser discards the token, which is not the case then.

While being at it, simplify error handling in parser rule for listing
conntrack helpers (error() won't return NULL) and drop the unused extra
parameter passed to error() in level_type rule.

Signed-off-by: Phil Sutter <[email protected]>
---
 src/parser_bison.y | 46 ++++++++++++++++++++++++++++++++++++----------
 src/rule.c         |  1 +
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/src/parser_bison.y b/src/parser_bison.y
index d149178c2679b..d4b29029186b2 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -724,6 +724,7 @@ common_block                :       INCLUDE         
QUOTED_STRING   stmt_separator
                                if (symbol_lookup(scope, $2) != NULL) {
                                        erec_queue(error(&@2, "redefinition of 
symbol '%s'", $2),
                                                   state->msgs);
+                                       xfree($2);
                                        YYERROR;
                                }
 
@@ -860,6 +861,7 @@ add_cmd                     :       TABLE           
table_spec
                                int type;
 
                                erec = ct_objtype_parse(&@$, $2, &type);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -939,6 +941,7 @@ create_cmd          :       TABLE           table_spec
                                int type;
 
                                erec = ct_objtype_parse(&@$, $2, &type);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -992,6 +995,7 @@ delete_cmd          :       TABLE           table_spec
                                int type;
 
                                erec = ct_objtype_parse(&@$, $2, &type);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -1079,6 +1083,7 @@ list_cmd          :       TABLE           table_spec
                                int type;
 
                                erec = ct_objtype_parse(&@$, $2, &type);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -1093,16 +1098,12 @@ list_cmd                :       TABLE           
table_spec
                                if (strcmp($2, "helpers") == 0) {
                                        cmd = CMD_OBJ_CT_HELPERS;
                                } else {
-                                       struct error_record *erec;
-
-                                       erec = error(&@$, "unknown ct class 
'%s', want 'helpers'", $2);
-
-                                       if (erec != NULL) {
-                                               erec_queue(erec, state->msgs);
-                                               YYERROR;
-                                       } else
-                                               YYERROR;
+                                       erec_queue(error(&@$, "unknown ct class 
'%s', want 'helpers'", $2),
+                                                  state->msgs);
+                                       xfree($2);
+                                       YYERROR;
                                }
+                               xfree($2);
 
                                $$ = cmd_alloc(CMD_LIST, cmd, &$4, &@$, NULL);
                        }
@@ -1231,9 +1232,11 @@ table_options            :       FLAGS           STRING
                        {
                                if (strcmp($2, "dormant") == 0) {
                                        $<table>0->flags = TABLE_F_DORMANT;
+                                       xfree($2);
                                } else {
                                        erec_queue(error(&@2, "unknown table 
option %s", $2),
                                                   state->msgs);
+                                       xfree($2);
                                        YYERROR;
                                }
                        }
@@ -1302,6 +1305,7 @@ table_block               :       /* empty */     { $$ = 
$<table>-1; }
                                int type;
 
                                erec = ct_objtype_parse(&@$, $3, &type);
+                               xfree($3);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -1478,8 +1482,10 @@ type_identifier_list     :       type_identifier
                                if (dtype == NULL) {
                                        erec_queue(error(&@3, "unknown datatype 
%s", $3),
                                                   state->msgs);
+                                       xfree($3);
                                        YYERROR;
                                }
+                               xfree($3);
                                $$ = concat_subtype_add($$, dtype->type);
                        }
                        ;
@@ -1533,6 +1539,7 @@ hook_spec         :       TYPE            STRING          
HOOK            STRING          dev_spec        PRIORITY        prio_spec
                                if (chain_type == NULL) {
                                        erec_queue(error(&@2, "unknown chain 
type %s", $2),
                                                   state->msgs);
+                                       xfree($2);
                                        YYERROR;
                                }
                                $<chain>0->type         = xstrdup(chain_type);
@@ -1542,6 +1549,7 @@ hook_spec         :       TYPE            STRING          
HOOK            STRING          dev_spec        PRIORITY        prio_spec
                                if ($<chain>0->hookstr == NULL) {
                                        erec_queue(error(&@4, "unknown chain 
hook %s", $4),
                                                   state->msgs);
+                                       xfree($4);
                                        YYERROR;
                                }
                                xfree($4);
@@ -1589,6 +1597,7 @@ time_spec         :       STRING
                                uint64_t res;
 
                                erec = time_parse(&@1, $1, &res);
+                               xfree($1);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -1919,10 +1928,12 @@ level_type              :       string
                                else if (!strcmp("debug", $1))
                                        $$ = LOG_DEBUG;
                                else {
-                                       erec_queue(error(&@1, "invalid log 
level", $1),
+                                       erec_queue(error(&@1, "invalid log 
level"),
                                                   state->msgs);
+                                       xfree($1);
                                        YYERROR;
                                }
+                               xfree($1);
                        }
                        ;
 
@@ -1980,6 +1991,7 @@ limit_stmt                :       LIMIT   RATE    
limit_mode      NUM     SLASH   time_unit       limit_burst
                                uint64_t rate, unit;
 
                                erec = rate_parse(&@$, $5, &rate, &unit);
+                               xfree($5);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -2010,6 +2022,7 @@ quota_used                :       /* empty */     { $$ = 
0; }
                                uint64_t rate;
 
                                erec = data_unit_parse(&@$, $3, &rate);
+                               xfree($3);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -2024,6 +2037,7 @@ quota_stmt                :       QUOTA   quota_mode NUM 
quota_unit quota_used
                                uint64_t rate;
 
                                erec = data_unit_parse(&@$, $4, &rate);
+                               xfree($4);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -2055,6 +2069,7 @@ limit_burst               :       /* empty */             
        { $$ = 0; }
                                uint64_t rate;
 
                                erec = data_unit_parse(&@$, $3, &rate);
+                               xfree($3);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -2093,6 +2108,7 @@ reject_opts               :       /* empty */
                                                          current_scope(state),
                                                          $4);
                                $<stmt>0->reject.expr->dtype = &icmp_code_type;
+                               xfree($4);
                        }
                        |       WITH    ICMP6   TYPE    STRING
                        {
@@ -2103,6 +2119,7 @@ reject_opts               :       /* empty */
                                                          current_scope(state),
                                                          $4);
                                $<stmt>0->reject.expr->dtype = 
&icmpv6_code_type;
+                               xfree($4);
                        }
                        |       WITH    ICMPX   TYPE    STRING
                        {
@@ -2112,6 +2129,7 @@ reject_opts               :       /* empty */
                                                          current_scope(state),
                                                          $4);
                                $<stmt>0->reject.expr->dtype = &icmpx_code_type;
+                               xfree($4);
                        }
                        |       WITH    TCP     RESET
                        {
@@ -2392,6 +2410,7 @@ variable_expr             :       '$'     identifier
                                if (symbol_lookup(scope, $2) == NULL) {
                                        erec_queue(error(&@2, "unknown 
identifier '%s'", $2),
                                                   state->msgs);
+                                       xfree($2);
                                        YYERROR;
                                }
 
@@ -2692,6 +2711,7 @@ quota_config              :       quota_mode NUM 
quota_unit quota_used
                                uint64_t rate;
 
                                erec = data_unit_parse(&@$, $3, &rate);
+                               xfree($3);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -2994,6 +3014,7 @@ meta_expr         :       META    meta_key
                                unsigned int key;
 
                                erec = meta_key_parse(&@$, $2, &key);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -3046,6 +3067,7 @@ meta_stmt         :       META    meta_key        SET     
expr
                                unsigned int key;
 
                                erec = meta_key_parse(&@$, $2, &key);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -3110,6 +3132,7 @@ ct_expr                   :       CT      ct_key
                                unsigned int key;
 
                                erec = ct_key_parse(&@$, $2, &key);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -3123,6 +3146,7 @@ ct_expr                   :       CT      ct_key
                                int8_t direction;
 
                                erec = ct_dir_parse(&@$, $2, &direction);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -3180,6 +3204,7 @@ ct_stmt                   :       CT      ct_key          
SET     expr
                                unsigned int key;
 
                                erec = ct_key_parse(&@$, $2, &key);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
@@ -3202,6 +3227,7 @@ ct_stmt                   :       CT      ct_key          
SET     expr
                                int8_t direction;
 
                                erec = ct_dir_parse(&@$, $2, &direction);
+                               xfree($2);
                                if (erec != NULL) {
                                        erec_queue(erec, state->msgs);
                                        YYERROR;
diff --git a/src/rule.c b/src/rule.c
index 140855f517571..44d36c16ea47f 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -926,6 +926,7 @@ struct monitor *monitor_alloc(uint32_t format, uint32_t 
type, const char *event)
 
 void monitor_free(struct monitor *m)
 {
+       xfree(m->event);
        xfree(m);
 }
 
-- 
2.13.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to