X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Ffilter%2Ffilter-parser.y;h=12605cd382b8af4d65c3d59b7076b3d982870af5;hp=6250054a0eb788a59f7dbffe42bf9e32d0f9ffa4;hb=661dfdd190c65bad5a044e21c1d5f9ad59144bf8;hpb=a187da1ab55a90f95fed8a29ed232b344f0d32b2 diff --git a/src/lib/lttng-ctl/filter/filter-parser.y b/src/lib/lttng-ctl/filter/filter-parser.y index 6250054a0..12605cd38 100644 --- a/src/lib/lttng-ctl/filter/filter-parser.y +++ b/src/lib/lttng-ctl/filter/filter-parser.y @@ -34,15 +34,20 @@ #include +#define WIDTH_u64_SCANF_IS_A_BROKEN_API "20" +#define WIDTH_o64_SCANF_IS_A_BROKEN_API "22" +#define WIDTH_x64_SCANF_IS_A_BROKEN_API "17" +#define WIDTH_lg_SCANF_IS_A_BROKEN_API "4096" /* Hugely optimistic approximation */ + LTTNG_HIDDEN int yydebug; LTTNG_HIDDEN int filter_parser_debug = 0; LTTNG_HIDDEN -int yyparse(struct filter_parser_ctx *parser_ctx); +int yyparse(struct filter_parser_ctx *parser_ctx, yyscan_t scanner); LTTNG_HIDDEN -int yylex(union YYSTYPE *yyval, struct filter_parser_ctx *parser_ctx); +int yylex(union YYSTYPE *yyval, yyscan_t scanner); LTTNG_HIDDEN int yylex_init_extra(struct filter_parser_ctx *parser_ctx, yyscan_t * ptr_yy_globals); LTTNG_HIDDEN @@ -84,9 +89,13 @@ static struct gc_string *gc_string_alloc(struct filter_parser_ctx *parser_ctx, for (alloclen = 8; alloclen < sizeof(long) + sizeof(*gstr) + len; alloclen *= 2); - gstr = malloc(alloclen); + gstr = zmalloc(alloclen); + if (!gstr) { + goto end; + } cds_list_add(&gstr->gc, &parser_ctx->allocated_strings); gstr->alloclen = alloclen; +end: return gstr; } @@ -138,7 +147,7 @@ static struct filter_node *make_node(struct filter_parser_ctx *scanner, struct filter_ast *ast = filter_parser_get_ast(scanner); struct filter_node *node; - node = malloc(sizeof(*node)); + node = zmalloc(sizeof(*node)); if (!node) return NULL; memset(node, 0, sizeof(*node)); @@ -175,7 +184,7 @@ static struct filter_node *make_op_node(struct filter_parser_ctx *scanner, struct filter_ast *ast = filter_parser_get_ast(scanner); struct filter_node *node; - node = malloc(sizeof(*node)); + node = zmalloc(sizeof(*node)); if (!node) return NULL; memset(node, 0, sizeof(*node)); @@ -188,7 +197,7 @@ static struct filter_node *make_op_node(struct filter_parser_ctx *scanner, } LTTNG_HIDDEN -void yyerror(struct filter_parser_ctx *parser_ctx, const char *str) +void yyerror(struct filter_parser_ctx *parser_ctx, yyscan_t scanner, const char *str) { fprintf(stderr, "error %s\n", str); } @@ -201,7 +210,7 @@ int yywrap(void) #define parse_error(parser_ctx, str) \ do { \ - yyerror(parser_ctx, YY_("parse error: " str "\n")); \ + yyerror(parser_ctx, parser_ctx->scanner, YY_("parse error: " str "\n")); \ YYERROR; \ } while (0) @@ -217,7 +226,7 @@ static struct filter_ast *filter_ast_alloc(void) { struct filter_ast *ast; - ast = malloc(sizeof(*ast)); + ast = zmalloc(sizeof(*ast)); if (!ast) return NULL; memset(ast, 0, sizeof(*ast)); @@ -238,7 +247,7 @@ static void filter_ast_free(struct filter_ast *ast) LTTNG_HIDDEN int filter_parser_ctx_append_ast(struct filter_parser_ctx *parser_ctx) { - return yyparse(parser_ctx); + return yyparse(parser_ctx, parser_ctx->scanner); } LTTNG_HIDDEN @@ -249,7 +258,7 @@ struct filter_parser_ctx *filter_parser_ctx_alloc(FILE *input) yydebug = filter_parser_debug; - parser_ctx = malloc(sizeof(*parser_ctx)); + parser_ctx = zmalloc(sizeof(*parser_ctx)); if (!parser_ctx) return NULL; memset(parser_ctx, 0, sizeof(*parser_ctx)); @@ -301,7 +310,8 @@ void filter_parser_ctx_free(struct filter_parser_ctx *parser_ctx) %define api.pure /* %locations */ %parse-param {struct filter_parser_ctx *parser_ctx} -%lex-param {struct filter_parser_ctx *parser_ctx} +%parse-param {yyscan_t scanner} +%lex-param {yyscan_t scanner} %start translation_unit %token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE %token ESCSEQ CHAR_STRING_TOKEN @@ -313,7 +323,7 @@ void filter_parser_ctx_free(struct filter_parser_ctx *parser_ctx) %token ASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA %token XOR_BIN AND_BIN OR_BIN NOT_BIN -%token IDENTIFIER +%token IDENTIFIER GLOBAL_IDENTIFIER %token ERROR %union { @@ -387,33 +397,50 @@ primary_expression $$->u.expression.type = AST_EXP_IDENTIFIER; $$->u.expression.u.identifier = yylval.gs->s; } + | GLOBAL_IDENTIFIER + { + $$ = make_node(parser_ctx, NODE_EXPRESSION); + $$->u.expression.type = AST_EXP_GLOBAL_IDENTIFIER; + $$->u.expression.u.identifier = yylval.gs->s; + } + | DECIMAL_CONSTANT { $$ = make_node(parser_ctx, NODE_EXPRESSION); $$->u.expression.type = AST_EXP_CONSTANT; - sscanf(yylval.gs->s, "%" PRIu64, - &$$->u.expression.u.constant); + if (sscanf(yylval.gs->s, "%" WIDTH_u64_SCANF_IS_A_BROKEN_API SCNu64, + &$$->u.expression.u.constant) != 1) { + parse_error(parser_ctx, "cannot scanf decimal constant"); + } } | OCTAL_CONSTANT { $$ = make_node(parser_ctx, NODE_EXPRESSION); $$->u.expression.type = AST_EXP_CONSTANT; - sscanf(yylval.gs->s, "0%" PRIo64, - &$$->u.expression.u.constant); + if (!strcmp(yylval.gs->s, "0")) { + $$->u.expression.u.constant = 0; + } else if (sscanf(yylval.gs->s, "0%" WIDTH_o64_SCANF_IS_A_BROKEN_API SCNo64, + &$$->u.expression.u.constant) != 1) { + parse_error(parser_ctx, "cannot scanf octal constant"); + } } | HEXADECIMAL_CONSTANT { $$ = make_node(parser_ctx, NODE_EXPRESSION); $$->u.expression.type = AST_EXP_CONSTANT; - sscanf(yylval.gs->s, "0x%" PRIx64, - &$$->u.expression.u.constant); + if (sscanf(yylval.gs->s, "0x%" WIDTH_x64_SCANF_IS_A_BROKEN_API SCNx64, + &$$->u.expression.u.constant) != 1) { + parse_error(parser_ctx, "cannot scanf hexadecimal constant"); + } } | FLOAT_CONSTANT { $$ = make_node(parser_ctx, NODE_EXPRESSION); $$->u.expression.type = AST_EXP_FLOAT_CONSTANT; - sscanf(yylval.gs->s, "%lg", - &$$->u.expression.u.float_constant); + if (sscanf(yylval.gs->s, "%" WIDTH_lg_SCANF_IS_A_BROKEN_API "lg", + &$$->u.expression.u.float_constant) != 1) { + parse_error(parser_ctx, "cannot scanf float constant"); + } } | STRING_LITERAL_START DQUOTE { @@ -444,6 +471,12 @@ primary_expression postfix_expression : primary_expression { $$ = $1; } + | postfix_expression LSBRAC unary_expression RSBRAC + { + $$ = $1; + $$->u.expression.pre_op = AST_LINK_BRACKET; + $$->u.expression.next = $3; + } | postfix_expression DOT IDENTIFIER { $$ = make_node(parser_ctx, NODE_EXPRESSION);