[lttng-dev] [PATCH lttng-tools] Warn that wildcards must be used as the last character in a string

Jérémie Galarneau jeremie.galarneau at efficios.com
Mon Aug 4 14:10:27 EDT 2014


Wildcards are currently only supported as the last character
in a string literal used in an event filter. This rule is not
checked which may confuse users who expect complete wildcard
support in filter expressions.

An error is now reported and the filter string is treated
as invalid.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau at efficios.com>
---
 src/lib/lttng-ctl/filter/Makefile.am               |   1 +
 src/lib/lttng-ctl/filter/filter-ast.h              |   1 +
 .../filter/filter-visitor-ir-validate-string.c     | 148 +++++++++++++++++++++
 src/lib/lttng-ctl/lttng-ctl.c                      |   6 +
 4 files changed, 156 insertions(+)
 create mode 100644 src/lib/lttng-ctl/filter/filter-visitor-ir-validate-string.c

diff --git a/src/lib/lttng-ctl/filter/Makefile.am b/src/lib/lttng-ctl/filter/Makefile.am
index 4ff345a..71a53c1 100644
--- a/src/lib/lttng-ctl/filter/Makefile.am
+++ b/src/lib/lttng-ctl/filter/Makefile.am
@@ -14,6 +14,7 @@ libfilter_la_SOURCES = filter-lexer.l filter-parser.y \
 	filter-visitor-xml.c \
 	filter-visitor-generate-ir.c \
 	filter-visitor-ir-check-binary-op-nesting.c \
+	filter-visitor-ir-validate-string.c \
 	filter-visitor-generate-bytecode.c \
 	align.h \
 	bug.h \
diff --git a/src/lib/lttng-ctl/filter/filter-ast.h b/src/lib/lttng-ctl/filter/filter-ast.h
index 405c668..7f1883f 100644
--- a/src/lib/lttng-ctl/filter/filter-ast.h
+++ b/src/lib/lttng-ctl/filter/filter-ast.h
@@ -186,5 +186,6 @@ int filter_visitor_bytecode_generate(struct filter_parser_ctx *ctx);
 void filter_bytecode_free(struct filter_parser_ctx *ctx);
 int filter_visitor_ir_check_binary_op_nesting(struct filter_parser_ctx *ctx);
 int filter_visitor_ir_check_binary_comparator(struct filter_parser_ctx *ctx);
+int filter_visitor_ir_validate_string(struct filter_parser_ctx *ctx);
 
 #endif /* _FILTER_AST_H */
diff --git a/src/lib/lttng-ctl/filter/filter-visitor-ir-validate-string.c b/src/lib/lttng-ctl/filter/filter-visitor-ir-validate-string.c
new file mode 100644
index 0000000..34b4b19
--- /dev/null
+++ b/src/lib/lttng-ctl/filter/filter-visitor-ir-validate-string.c
@@ -0,0 +1,148 @@
+/*
+ * filter-visitor-ir-validate-string.c
+ *
+ * LTTng filter IR validate string
+ *
+ * Copyright 2014 - Jérémie Galarneau <jeremie.galarneau at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include "filter-ast.h"
+#include "filter-parser.h"
+#include "filter-ir.h"
+
+enum parse_char_result {
+	PARSE_CHAR_UNKNOWN = -2,
+	PARSE_CHAR_WILDCARD = -1,
+	PARSE_CHAR_NORMAL = 0,
+};
+
+static
+enum parse_char_result parse_char(const char **p)
+{
+	switch (**p) {
+	case '\\':
+		(*p)++;
+		switch (**p) {
+		case '\\':
+		case '*':
+			return PARSE_CHAR_NORMAL;
+		default:
+			return PARSE_CHAR_UNKNOWN;
+		}
+	case '*':
+		return PARSE_CHAR_WILDCARD;
+	default:
+		return PARSE_CHAR_NORMAL;
+	}
+}
+
+static
+int validate_string(struct ir_op *node)
+{
+	switch (node->op) {
+	case IR_OP_UNKNOWN:
+	default:
+		fprintf(stderr, "[error] %s: unknown op type\n", __func__);
+		return -EINVAL;
+
+	case IR_OP_ROOT:
+		return validate_string(node->u.root.child);
+	case IR_OP_LOAD:
+	{
+		int ret = 0;
+
+		if (node->data_type == IR_DATA_STRING) {
+			const char *str;
+
+			assert(node->u.load.u.string);
+			str = node->u.load.u.string;
+
+			/*
+			 * Make sure that if a non-escaped wildcard is
+			 * present, it is the last character of the string.
+			 */
+			for (;;) {
+				enum parse_char_result res;
+
+				if (!(*str)) {
+					break;
+				}
+
+				res = parse_char(&str);
+				str++;
+
+				switch (res) {
+				case PARSE_CHAR_WILDCARD:
+				{
+					if (*str) {
+						/*
+						 * Found a wildcard followed by non-null
+						 * character; unsupported.
+						 */
+						ret = -EINVAL;
+						fprintf(stderr,
+							"Wildcards may only be used as the last character of a string in a filter.\n");
+						goto end_load;
+					}
+					break;
+				}
+				case PARSE_CHAR_UNKNOWN:
+					ret = -EINVAL;
+					fprintf(stderr,
+						"Unsupported escape character detected.\n");
+					goto end_load;
+				case PARSE_CHAR_NORMAL:
+				default:
+					break;
+				}
+			}
+		}
+end_load:
+		return ret;
+	}
+	case IR_OP_UNARY:
+		return validate_string(node->u.unary.child);
+	case IR_OP_BINARY:
+	{
+		int ret = validate_string(node->u.binary.left);
+
+		if (ret)
+			return ret;
+		return validate_string(node->u.binary.right);
+	}
+	case IR_OP_LOGICAL:
+	{
+		int ret;
+
+		ret = validate_string(node->u.logical.left);
+		if (ret)
+			return ret;
+		return validate_string(node->u.logical.right);
+	}
+	}
+}
+
+int filter_visitor_ir_validate_string(struct filter_parser_ctx *ctx)
+{
+	return validate_string(ctx->ir_root);
+}
diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c
index 536d41b..b9dc1ef 100644
--- a/src/lib/lttng-ctl/lttng-ctl.c
+++ b/src/lib/lttng-ctl/lttng-ctl.c
@@ -825,6 +825,12 @@ static int generate_filter(char *filter_expression,
 		ret = -LTTNG_ERR_FILTER_INVAL;
 		goto parse_error;
 	}
+	/* Validate strings used as literals in the expression */
+	ret = filter_visitor_ir_validate_string(ctx);
+	if (ret) {
+		ret = -LTTNG_ERR_FILTER_INVAL;
+		goto parse_error;
+	}
 	dbg_printf("done\n");
 
 	dbg_printf("Generating bytecode... ");
-- 
2.0.3




More information about the lttng-dev mailing list