X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Ffilter%2Ffilter-visitor-ir-validate-string.c;fp=src%2Flib%2Flttng-ctl%2Ffilter%2Ffilter-visitor-ir-validate-string.c;h=34b4b194b5083de014de21c1610c8a1e482bcc97;hb=dcd5daf2e2acb0745d5e6ff66185147007e8ed53;hp=0000000000000000000000000000000000000000;hpb=29c0fd4d0c4f04d981df9df83d109440598b7930;p=lttng-tools.git 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 000000000..34b4b194b --- /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 + * + * 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 +#include +#include +#include +#include +#include +#include +#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); +}