Fix: Parenthesize previous statement when adding conditions to a filter
[lttng-tools.git] / src / lib / lttng-ctl / lttng-ctl.c
index 2d0753696efbdad55630487fb29a3882370ce4ba..4086d61c0439021d937c32721ae46a744e283274 100644 (file)
@@ -710,14 +710,14 @@ static char *set_jul_filter(const char *filter, struct lttng_event *ev)
        /* Don't add filter for the '*' event. */
        if (ev->name[0] != '*') {
                if (filter) {
-                       err = asprintf(&jul_filter, "%s && logger_name == \"%s\"", filter,
+                       err = asprintf(&jul_filter, "(%s) && (logger_name == \"%s\")", filter,
                                        ev->name);
                } else {
                        err = asprintf(&jul_filter, "logger_name == \"%s\"", ev->name);
                }
                if (err < 0) {
                        PERROR("asprintf");
-                       goto end;
+                       goto error;
                }
        }
 
@@ -731,23 +731,30 @@ static char *set_jul_filter(const char *filter, struct lttng_event *ev)
                        op = "==";
                }
 
-               if (filter) {
-                       err = asprintf(&jul_filter, "%s && int_loglevel %s %d", filter, op,
+               if (filter || jul_filter) {
+                       char *new_filter;
+
+                       err = asprintf(&new_filter, "(%s) && (int_loglevel %s %d)",
+                                       jul_filter ? jul_filter : filter, op,
                                        ev->loglevel);
+                       if (jul_filter) {
+                               free(jul_filter);
+                       }
+                       jul_filter = new_filter;
                } else {
                        err = asprintf(&jul_filter, "int_loglevel %s %d", op,
                                        ev->loglevel);
                }
                if (err < 0) {
                        PERROR("asprintf");
-                       free(jul_filter);
-                       jul_filter = NULL;
-                       goto end;
+                       goto error;
                }
        }
 
-end:
        return jul_filter;
+error:
+       free(jul_filter);
+       return NULL;
 }
 
 /*
@@ -760,7 +767,7 @@ end:
  */
 int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
                struct lttng_event *ev, const char *channel_name,
-               const char *filter_expression,
+               const char *original_filter_expression,
                int exclusion_count, char **exclusion_list)
 {
        struct lttcomm_session_msg lsm;
@@ -768,6 +775,13 @@ int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
        int ret = 0;
        struct filter_parser_ctx *ctx = NULL;
        FILE *fmem = NULL;
+       /*
+        * Cast as non-const since we may replace the filter expression
+        * by a dynamically allocated string. Otherwise, the original
+        * string is not modified.
+        */
+       char *filter_expression = (char *) original_filter_expression;
+       int free_filter_expression = 0;
 
        if (handle == NULL || ev == NULL) {
                return -LTTNG_ERR_INVALID;
@@ -828,21 +842,16 @@ int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
 
                        /* Setup JUL filter if needed. */
                        jul_filter = set_jul_filter(filter_expression, ev);
-                       if (!jul_filter) {
-                               if (!filter_expression) {
-                                       /* No JUL and no filter, just skip everything below. */
-                                       goto ask_sessiond;
-                               }
+                       if (!jul_filter && !filter_expression) {
+                               /* No JUL and no filter, just skip everything below. */
+                               goto ask_sessiond;
                        } else {
                                /*
                                 * With a JUL filter, the original filter has been added to it
                                 * thus replace the filter expression.
                                 */
-                               filter_expression = strdup(jul_filter);
-                               free(jul_filter);
-                               if (!filter_expression) {
-                                       return -LTTNG_ERR_FILTER_NOMEM;
-                               }
+                               filter_expression = jul_filter;
+                               free_filter_expression = 1;
                        }
                }
 
@@ -960,6 +969,14 @@ varlen_alloc_error:
                if (fclose(fmem) != 0) {
                        perror("fclose");
                }
+               if (free_filter_expression) {
+                       /*
+                        * The filter expression has been replaced and must be
+                        * freed as it is not the original filter expression
+                        * received as a parameter.
+                        */
+                       free(filter_expression);
+               }
        }
        return ret;
 
This page took 0.033856 seconds and 4 git commands to generate.