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

David Goulet dgoulet at efficios.com
Tue Aug 5 17:03:56 EDT 2014


Merged and the two other patches following this email.

On 04 Aug (14:10:27), Jérémie Galarneau wrote:
> 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
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 603 bytes
Desc: Digital signature
URL: <http://lists.lttng.org/pipermail/lttng-dev/attachments/20140805/cfa40464/attachment.sig>


More information about the lttng-dev mailing list