From ce821fde309ed41d8cf505e84da86c72020b7613 Mon Sep 17 00:00:00 2001 From: Wesley Shields Date: Mon, 16 May 2022 10:56:51 -0400 Subject: [PATCH 1/2] Fix some compiler edge cases. Add a warning when "0 of them" is used. Point to some new documentation that explains why "none of them" is preferred. Handle some edge cases, which are all now errors: * -1 of them * "foo" of them * /foo/ of them And this one is also an error if the external variable "x" is a negative integer or a string: * x of them I've also made sure this works with a construct like "0 + x of them" where x is defined as a negative integer. Add test cases for as many of these as I can. I don't have test cases for the external variable case, but it does work as expected. Here is the output of a rule using external variables where the variable is defined to be 1, 0, -1 and foo: ``` wxs@mbp yara % cat rules/test.yara rule a { strings: $a = "FreeBSD" condition: x of them } wxs@mbp yara % ./yara -d x=1 rules/test.yara /bin/ls a /bin/ls wxs@mbp yara % ./yara -d x=0 rules/test.yara /bin/ls warning: rule "a" in rules/test.yara(5): Consider using "none" keyword, it is less ambiguous. Please see https://yara.readthedocs.io/en/stable/writingrules.html#sets-of-strings-1 for an explanation. wxs@mbp yara % ./yara -d x=-1 rules/test.yara /bin/ls error: rule "a" in rules/test.yara(5): invalid value in condition: "-1" wxs@mbp yara % ./yara -d x=foo rules/test.yara /bin/ls error: rule "a" in rules/test.yara(5): invalid value in condition: "string in for_expression is invalid" wxs@mbp yara % ``` --- docs/writingrules.rst | 12 +++ libyara/compiler.c | 7 ++ libyara/grammar.c | 170 +++++++++++++++++++++-------------- libyara/grammar.y | 36 +++++++- libyara/include/yara/error.h | 1 + tests/test-rules.c | 75 ++++++++++++++++ 6 files changed, 232 insertions(+), 69 deletions(-) diff --git a/docs/writingrules.rst b/docs/writingrules.rst index df710e7508..6defc54b8d 100644 --- a/docs/writingrules.rst +++ b/docs/writingrules.rst @@ -1200,6 +1200,18 @@ The keywords ``any``, ``all`` and ``none`` can be used as well. 1 of ($*) // same that "any of them" none of ($b*) // zero of the set of strings that start with "$b" +.. warning:: Due to the way YARA works internally, using "0 of them" is an + ambiguous part of the language which should be avoided in favor of "none + of them". To understand this, consider the meaning of "2 of them", which + is true if 2 or more of the strings match. Historically, "0 of them" + followed this principle and would evaluate to true if at least one of the + strings matched. This ambiguity is resolved in YARA 4.3.0 by making "0 of + them" evaluate to true if exactly 0 of the strings match. To improve on + the situation and make the intent clear, it is encouraged to use "none" in + place of 0. By not using an integer it is easier to reason about the meaning + of "none of them" without the historical understanding of "at least 0" + clouding the issue. + Starting with YARA 4.2.0 it is possible to express a set of strings in an integer range, like this: diff --git a/libyara/compiler.c b/libyara/compiler.c index 4bfbf9bce0..92fee82a79 100644 --- a/libyara/compiler.c +++ b/libyara/compiler.c @@ -1041,6 +1041,13 @@ YR_API char* yr_compiler_get_error_message( "rule identifier \"%s\" matches previously used wildcard rule set", compiler->last_error_extra_info); break; + case ERROR_INVALID_VALUE: + snprintf( + buffer, + buffer_size, + "invalid value in condition: \"%s\"", + compiler->last_error_extra_info); + break; } return buffer; diff --git a/libyara/grammar.c b/libyara/grammar.c index 0b6364418a..3318075ebe 100644 --- a/libyara/grammar.c +++ b/libyara/grammar.c @@ -952,10 +952,10 @@ static const yytype_int16 yyrline[] = 1755, 1801, 1800, 1844, 1851, 1858, 1865, 1872, 1879, 1886, 1890, 1898, 1899, 1924, 1944, 1972, 2046, 2074, 2082, 2091, 2115, 2130, 2149, 2159, 2158, 2167, 2181, 2182, 2187, 2197, - 2212, 2211, 2221, 2222, 2227, 2258, 2280, 2284, 2289, 2294, - 2303, 2307, 2315, 2327, 2341, 2348, 2355, 2380, 2392, 2404, - 2416, 2431, 2443, 2458, 2501, 2522, 2557, 2592, 2626, 2651, - 2668, 2678, 2688, 2698, 2708, 2728, 2748 + 2212, 2211, 2221, 2222, 2227, 2258, 2280, 2318, 2323, 2328, + 2337, 2341, 2349, 2361, 2375, 2382, 2389, 2414, 2426, 2438, + 2450, 2465, 2477, 2492, 2535, 2556, 2591, 2626, 2660, 2685, + 2702, 2712, 2722, 2732, 2742, 2762, 2782 }; #endif @@ -4359,48 +4359,82 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 136: /* for_expression: primary_expression */ #line 2281 "grammar.y" { + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER) { + if ((yyvsp[0].expression).value.integer == 0) { + yywarning(yyscanner, + "Consider using \"none\" keyword, it is less ambiguous. Please " + "see https://yara.readthedocs.io/en/stable/writingrules.html#sets-of-strings-1 for an explanation."); + } + + if ((yyvsp[0].expression).value.integer < 0) { + yr_compiler_set_error_extra_info_fmt(compiler, + "%lld", (yyvsp[0].expression).value.integer); + fail_with_error(ERROR_INVALID_VALUE); + } + } + + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_STRING) { + SIZED_STRING* ss = yr_arena_ref_to_ptr(compiler->arena, + &(yyvsp[0].expression).value.sized_string_ref); + // If the expression is an external string variable we need to get + // it some other way. + if (ss != NULL) { + yr_compiler_set_error_extra_info_fmt(compiler, "%s", ss->c_string); + } else { + yr_compiler_set_error_extra_info(compiler, + "string in for_expression is invalid"); + } + fail_with_error(ERROR_INVALID_VALUE); + } + + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_REGEXP) { + yr_compiler_set_error_extra_info(compiler, + "regexp in for_expression is invalid"); + fail_with_error(ERROR_INVALID_VALUE); + } + (yyval.integer) = FOR_EXPRESSION_ANY; } -#line 4365 "grammar.c" +#line 4399 "grammar.c" break; case 137: /* for_expression: "" */ -#line 2285 "grammar.y" +#line 2319 "grammar.y" { yr_parser_emit_push_const(yyscanner, YR_UNDEFINED); (yyval.integer) = FOR_EXPRESSION_ALL; } -#line 4374 "grammar.c" +#line 4408 "grammar.c" break; case 138: /* for_expression: "" */ -#line 2290 "grammar.y" +#line 2324 "grammar.y" { yr_parser_emit_push_const(yyscanner, 1); (yyval.integer) = FOR_EXPRESSION_ANY; } -#line 4383 "grammar.c" +#line 4417 "grammar.c" break; case 139: /* for_expression: "" */ -#line 2295 "grammar.y" +#line 2329 "grammar.y" { yr_parser_emit_push_const(yyscanner, 0); (yyval.integer) = FOR_EXPRESSION_NONE; } -#line 4392 "grammar.c" +#line 4426 "grammar.c" break; case 140: /* primary_expression: '(' primary_expression ')' */ -#line 2304 "grammar.y" +#line 2338 "grammar.y" { (yyval.expression) = (yyvsp[-1].expression); } -#line 4400 "grammar.c" +#line 4434 "grammar.c" break; case 141: /* primary_expression: "" */ -#line 2308 "grammar.y" +#line 2342 "grammar.y" { fail_if_error(yr_parser_emit( yyscanner, OP_FILESIZE, NULL)); @@ -4408,11 +4442,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4412 "grammar.c" +#line 4446 "grammar.c" break; case 142: /* primary_expression: "" */ -#line 2316 "grammar.y" +#line 2350 "grammar.y" { yywarning(yyscanner, "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " @@ -4424,11 +4458,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4428 "grammar.c" +#line 4462 "grammar.c" break; case 143: /* primary_expression: "integer function" '(' primary_expression ')' */ -#line 2328 "grammar.y" +#line 2362 "grammar.y" { check_type((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX"); @@ -4442,33 +4476,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4446 "grammar.c" +#line 4480 "grammar.c" break; case 144: /* primary_expression: "integer number" */ -#line 2342 "grammar.y" +#line 2376 "grammar.y" { fail_if_error(yr_parser_emit_push_const(yyscanner, (yyvsp[0].integer))); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = (yyvsp[0].integer); } -#line 4457 "grammar.c" +#line 4491 "grammar.c" break; case 145: /* primary_expression: "floating point number" */ -#line 2349 "grammar.y" +#line 2383 "grammar.y" { fail_if_error(yr_parser_emit_with_arg_double( yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL)); (yyval.expression).type = EXPRESSION_TYPE_FLOAT; } -#line 4468 "grammar.c" +#line 4502 "grammar.c" break; case 146: /* primary_expression: "text string" */ -#line 2356 "grammar.y" +#line 2390 "grammar.y" { YR_ARENA_REF ref; @@ -4493,11 +4527,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_STRING; (yyval.expression).value.sized_string_ref = ref; } -#line 4497 "grammar.c" +#line 4531 "grammar.c" break; case 147: /* primary_expression: "string count" "" range */ -#line 2381 "grammar.y" +#line 2415 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[-2].c_string), OP_COUNT_IN, YR_UNDEFINED); @@ -4509,11 +4543,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4513 "grammar.c" +#line 4547 "grammar.c" break; case 148: /* primary_expression: "string count" */ -#line 2393 "grammar.y" +#line 2427 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[0].c_string), OP_COUNT, YR_UNDEFINED); @@ -4525,11 +4559,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4529 "grammar.c" +#line 4563 "grammar.c" break; case 149: /* primary_expression: "string offset" '[' primary_expression ']' */ -#line 2405 "grammar.y" +#line 2439 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[-3].c_string), OP_OFFSET, YR_UNDEFINED); @@ -4541,11 +4575,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4545 "grammar.c" +#line 4579 "grammar.c" break; case 150: /* primary_expression: "string offset" */ -#line 2417 "grammar.y" +#line 2451 "grammar.y" { int result = yr_parser_emit_push_const(yyscanner, 1); @@ -4560,11 +4594,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4564 "grammar.c" +#line 4598 "grammar.c" break; case 151: /* primary_expression: "string length" '[' primary_expression ']' */ -#line 2432 "grammar.y" +#line 2466 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[-3].c_string), OP_LENGTH, YR_UNDEFINED); @@ -4576,11 +4610,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4580 "grammar.c" +#line 4614 "grammar.c" break; case 152: /* primary_expression: "string length" */ -#line 2444 "grammar.y" +#line 2478 "grammar.y" { int result = yr_parser_emit_push_const(yyscanner, 1); @@ -4595,11 +4629,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4599 "grammar.c" +#line 4633 "grammar.c" break; case 153: /* primary_expression: identifier */ -#line 2459 "grammar.y" +#line 2493 "grammar.y" { int result = ERROR_SUCCESS; @@ -4612,7 +4646,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { case OBJECT_TYPE_INTEGER: (yyval.expression).type = EXPRESSION_TYPE_INTEGER; - (yyval.expression).value.integer = YR_UNDEFINED; + (yyval.expression).value.integer = (yyvsp[0].expression).value.object->value.i; break; case OBJECT_TYPE_FLOAT: (yyval.expression).type = EXPRESSION_TYPE_FLOAT; @@ -4642,11 +4676,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4646 "grammar.c" +#line 4680 "grammar.c" break; case 154: /* primary_expression: '-' primary_expression */ -#line 2502 "grammar.y" +#line 2536 "grammar.y" { int result = ERROR_SUCCESS; @@ -4667,11 +4701,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4671 "grammar.c" +#line 4705 "grammar.c" break; case 155: /* primary_expression: primary_expression '+' primary_expression */ -#line 2523 "grammar.y" +#line 2557 "grammar.y" { int result = yr_parser_reduce_operation( yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression)); @@ -4706,11 +4740,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4710 "grammar.c" +#line 4744 "grammar.c" break; case 156: /* primary_expression: primary_expression '-' primary_expression */ -#line 2558 "grammar.y" +#line 2592 "grammar.y" { int result = yr_parser_reduce_operation( yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression)); @@ -4745,11 +4779,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4749 "grammar.c" +#line 4783 "grammar.c" break; case 157: /* primary_expression: primary_expression '*' primary_expression */ -#line 2593 "grammar.y" +#line 2627 "grammar.y" { int result = yr_parser_reduce_operation( yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression)); @@ -4783,11 +4817,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4787 "grammar.c" +#line 4821 "grammar.c" break; case 158: /* primary_expression: primary_expression '\\' primary_expression */ -#line 2627 "grammar.y" +#line 2661 "grammar.y" { int result = yr_parser_reduce_operation( yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression)); @@ -4812,11 +4846,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4816 "grammar.c" +#line 4850 "grammar.c" break; case 159: /* primary_expression: primary_expression '%' primary_expression */ -#line 2652 "grammar.y" +#line 2686 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%"); @@ -4833,11 +4867,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(ERROR_DIVISION_BY_ZERO); } } -#line 4837 "grammar.c" +#line 4871 "grammar.c" break; case 160: /* primary_expression: primary_expression '^' primary_expression */ -#line 2669 "grammar.y" +#line 2703 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); @@ -4847,11 +4881,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); } -#line 4851 "grammar.c" +#line 4885 "grammar.c" break; case 161: /* primary_expression: primary_expression '&' primary_expression */ -#line 2679 "grammar.y" +#line 2713 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); @@ -4861,11 +4895,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); } -#line 4865 "grammar.c" +#line 4899 "grammar.c" break; case 162: /* primary_expression: primary_expression '|' primary_expression */ -#line 2689 "grammar.y" +#line 2723 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|"); @@ -4875,11 +4909,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); } -#line 4879 "grammar.c" +#line 4913 "grammar.c" break; case 163: /* primary_expression: '~' primary_expression */ -#line 2699 "grammar.y" +#line 2733 "grammar.y" { check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~"); @@ -4889,11 +4923,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == YR_UNDEFINED) ? YR_UNDEFINED : ~((yyvsp[0].expression).value.integer); } -#line 4893 "grammar.c" +#line 4927 "grammar.c" break; case 164: /* primary_expression: primary_expression "<<" primary_expression */ -#line 2709 "grammar.y" +#line 2743 "grammar.y" { int result; @@ -4913,11 +4947,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4917 "grammar.c" +#line 4951 "grammar.c" break; case 165: /* primary_expression: primary_expression ">>" primary_expression */ -#line 2729 "grammar.y" +#line 2763 "grammar.y" { int result; @@ -4937,19 +4971,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4941 "grammar.c" +#line 4975 "grammar.c" break; case 166: /* primary_expression: regexp */ -#line 2749 "grammar.y" +#line 2783 "grammar.y" { (yyval.expression) = (yyvsp[0].expression); } -#line 4949 "grammar.c" +#line 4983 "grammar.c" break; -#line 4953 "grammar.c" +#line 4987 "grammar.c" default: break; } @@ -5173,5 +5207,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); return yyresult; } -#line 2754 "grammar.y" +#line 2788 "grammar.y" diff --git a/libyara/grammar.y b/libyara/grammar.y index a49c7227bb..c3dc3821f8 100644 --- a/libyara/grammar.y +++ b/libyara/grammar.y @@ -2279,6 +2279,40 @@ rule_enumeration_item for_expression : primary_expression { + if ($1.type == EXPRESSION_TYPE_INTEGER) { + if ($1.value.integer == 0) { + yywarning(yyscanner, + "Consider using \"none\" keyword, it is less ambiguous. Please " + "see https://yara.readthedocs.io/en/stable/writingrules.html#sets-of-strings-1 for an explanation."); + } + + if ($1.value.integer < 0) { + yr_compiler_set_error_extra_info_fmt(compiler, + "%lld", $1.value.integer); + fail_with_error(ERROR_INVALID_VALUE); + } + } + + if ($1.type == EXPRESSION_TYPE_STRING) { + SIZED_STRING* ss = yr_arena_ref_to_ptr(compiler->arena, + &$1.value.sized_string_ref); + // If the expression is an external string variable we need to get + // it some other way. + if (ss != NULL) { + yr_compiler_set_error_extra_info_fmt(compiler, "%s", ss->c_string); + } else { + yr_compiler_set_error_extra_info(compiler, + "string in for_expression is invalid"); + } + fail_with_error(ERROR_INVALID_VALUE); + } + + if ($1.type == EXPRESSION_TYPE_REGEXP) { + yr_compiler_set_error_extra_info(compiler, + "regexp in for_expression is invalid"); + fail_with_error(ERROR_INVALID_VALUE); + } + $$ = FOR_EXPRESSION_ANY; } | _ALL_ @@ -2468,7 +2502,7 @@ primary_expression { case OBJECT_TYPE_INTEGER: $$.type = EXPRESSION_TYPE_INTEGER; - $$.value.integer = YR_UNDEFINED; + $$.value.integer = $1.value.object->value.i; break; case OBJECT_TYPE_FLOAT: $$.type = EXPRESSION_TYPE_FLOAT; diff --git a/libyara/include/yara/error.h b/libyara/include/yara/error.h index 6ac2ce9e46..aded7be362 100644 --- a/libyara/include/yara/error.h +++ b/libyara/include/yara/error.h @@ -106,6 +106,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define ERROR_BLOCK_NOT_READY 61 #define ERROR_INVALID_PERCENTAGE 62 #define ERROR_IDENTIFIER_MATCHES_WILDCARD 63 +#define ERROR_INVALID_VALUE 64 #define GOTO_EXIT_ON_ERROR(x) \ { \ diff --git a/tests/test-rules.c b/tests/test-rules.c index 5f48be6644..37a1cb1466 100644 --- a/tests/test-rules.c +++ b/tests/test-rules.c @@ -477,6 +477,38 @@ static void test_syntax() // Test case for issue #1295 assert_error("rule test rule test", ERROR_DUPLICATED_IDENTIFIER); + assert_error( + "rule test { strings: $a = \"a\" condition: -1 of them }", + ERROR_INVALID_VALUE); + + assert_error( + "rule test { strings: $a = \"a\" condition: 0 + -1 of them }", + ERROR_INVALID_VALUE); + + assert_error( + "rule test { strings: $a = \"a\" condition: for -1 of them: ($) }", + ERROR_INVALID_VALUE); + + assert_error( + "rule test { strings: $a = \"a\" condition: for 0 + -1 of them: ($) }", + ERROR_INVALID_VALUE); + + assert_error( + "rule test { strings: $a = \"a\" condition: \"foo\" of them }", + ERROR_INVALID_VALUE); + + assert_error( + "rule test { strings: $a = \"a\" condition: for \"foo\" of them: ($) }", + ERROR_INVALID_VALUE); + + assert_error( + "rule test { strings: $a = \"a\" condition: /foo/ of them }", + ERROR_INVALID_VALUE); + + assert_error( + "rule test { strings: $a = \"a\" condition: for /foo/ of them: ($) }", + ERROR_INVALID_VALUE); + YR_DEBUG_FPRINTF(1, stderr, "} // %s()\n", __FUNCTION__); } @@ -491,6 +523,48 @@ static void test_anonymous_strings() YR_DEBUG_FPRINTF(1, stderr, "} // %s()\n", __FUNCTION__); } +static void test_warnings() { + YR_DEBUG_FPRINTF(1, stderr, "+ %s() {\n", __FUNCTION__); + + assert_warning("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + 0 of them \ + }"); + + assert_warning("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + for 0 of ($a*): ($) \ + }"); + + assert_no_warnings("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + none of them \ + }"); + + assert_no_warnings("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + for none of ($a*): ($) \ + }"); + + assert_warning("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + 1 + -1 of them \ + }"); + + + YR_DEBUG_FPRINTF(1, stderr, "} // %s()\n", __FUNCTION__); +} + static void test_strings() { YR_DEBUG_FPRINTF(1, stderr, "+ %s() {\n", __FUNCTION__); @@ -3537,6 +3611,7 @@ static void test_pass(int pass) test_global_rules(); test_tags(); test_meta(); + test_warnings(); #if !defined(USE_NO_PROC) && !defined(_WIN32) && !defined(__CYGWIN__) test_process_scan(); From c62043d3b9129cbee1a1dc1cb02b7fa2decb22bd Mon Sep 17 00:00:00 2001 From: Wesley Shields Date: Tue, 17 May 2022 11:26:33 -0400 Subject: [PATCH 2/2] More compiler warnings and errors. If you specify "2 of ($a)" it is now a warning because it will always evaluate to false, and is quite possibly not what you wanted to write. This is true for string sets, rule sets and string sets in a range like "2 of ($a) in (0..10)". If you are using an integer range it is now an error if the lower bound is greater than the upper bound. To support rule sets I needed to modify yr_parser_emit_pushes_for_rules() to use a count parameter, which it will update with the number of pushed rules. This is identical to how yr_parser_emit_pushes_for_strings() works. While I'm here, remove the link from the warning message for the "none" keyword. --- libyara/grammar.c | 1240 ++++++++++++++++--------------- libyara/grammar.h | 2 +- libyara/grammar.y | 96 ++- libyara/include/yara/compiler.h | 15 +- libyara/include/yara/parser.h | 3 +- libyara/parser.c | 10 +- tests/test-rules.c | 69 +- 7 files changed, 819 insertions(+), 616 deletions(-) diff --git a/libyara/grammar.c b/libyara/grammar.c index 3318075ebe..2ac1bbdb1e 100644 --- a/libyara/grammar.c +++ b/libyara/grammar.c @@ -378,7 +378,7 @@ extern int yara_yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 336 "grammar.y" +#line 341 "grammar.y" YR_EXPRESSION expression; SIZED_STRING* sized_string; @@ -547,7 +547,8 @@ enum yysymbol_kind_t YYSYMBOL_rule_enumeration = 133, /* rule_enumeration */ YYSYMBOL_rule_enumeration_item = 134, /* rule_enumeration_item */ YYSYMBOL_for_expression = 135, /* for_expression */ - YYSYMBOL_primary_expression = 136 /* primary_expression */ + YYSYMBOL_for_quantifier = 136, /* for_quantifier */ + YYSYMBOL_primary_expression = 137 /* primary_expression */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; @@ -875,16 +876,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 469 +#define YYLAST 468 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 84 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 53 +#define YYNNTS 54 /* YYNRULES -- Number of rules. */ -#define YYNRULES 166 +#define YYNRULES 167 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 272 +#define YYNSTATES 273 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 319 @@ -939,23 +940,23 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 354, 354, 355, 356, 357, 358, 359, 360, 368, - 381, 386, 380, 413, 416, 432, 435, 450, 455, 456, - 461, 462, 468, 471, 487, 496, 538, 539, 544, 561, - 575, 589, 603, 621, 622, 628, 627, 644, 643, 664, - 663, 688, 694, 754, 755, 756, 757, 758, 759, 765, - 786, 817, 822, 839, 844, 864, 865, 879, 880, 881, - 882, 883, 887, 888, 902, 906, 1001, 1049, 1110, 1155, - 1156, 1160, 1195, 1248, 1290, 1313, 1319, 1325, 1337, 1347, - 1357, 1367, 1377, 1387, 1397, 1407, 1421, 1436, 1447, 1522, - 1560, 1464, 1688, 1694, 1700, 1719, 1738, 1744, 1750, 1756, - 1755, 1801, 1800, 1844, 1851, 1858, 1865, 1872, 1879, 1886, - 1890, 1898, 1899, 1924, 1944, 1972, 2046, 2074, 2082, 2091, - 2115, 2130, 2149, 2159, 2158, 2167, 2181, 2182, 2187, 2197, - 2212, 2211, 2221, 2222, 2227, 2258, 2280, 2318, 2323, 2328, - 2337, 2341, 2349, 2361, 2375, 2382, 2389, 2414, 2426, 2438, - 2450, 2465, 2477, 2492, 2535, 2556, 2591, 2626, 2660, 2685, - 2702, 2712, 2722, 2732, 2742, 2762, 2782 + 0, 359, 359, 360, 361, 362, 363, 364, 365, 373, + 386, 391, 385, 418, 421, 437, 440, 455, 460, 461, + 466, 467, 473, 476, 492, 501, 543, 544, 549, 566, + 580, 594, 608, 626, 627, 633, 632, 649, 648, 669, + 668, 693, 699, 759, 760, 761, 762, 763, 764, 770, + 791, 822, 827, 844, 849, 869, 870, 884, 885, 886, + 887, 888, 892, 893, 907, 911, 1006, 1054, 1115, 1160, + 1161, 1165, 1200, 1253, 1295, 1318, 1324, 1330, 1342, 1352, + 1362, 1372, 1382, 1392, 1402, 1412, 1426, 1441, 1452, 1527, + 1565, 1469, 1693, 1704, 1715, 1734, 1753, 1765, 1771, 1777, + 1776, 1822, 1821, 1865, 1872, 1879, 1886, 1893, 1900, 1907, + 1911, 1919, 1920, 1945, 1965, 1993, 2067, 2095, 2103, 2112, + 2148, 2163, 2182, 2192, 2191, 2200, 2214, 2215, 2220, 2230, + 2245, 2244, 2257, 2258, 2263, 2296, 2321, 2366, 2373, 2379, + 2385, 2395, 2399, 2407, 2419, 2433, 2440, 2447, 2472, 2484, + 2496, 2508, 2523, 2535, 2550, 2593, 2614, 2649, 2684, 2718, + 2743, 2760, 2770, 2780, 2790, 2800, 2820, 2840 }; #endif @@ -1001,7 +1002,7 @@ static const char *const yytname[] = "integer_set", "range", "integer_enumeration", "string_iterator", "string_set", "$@10", "string_enumeration", "string_enumeration_item", "rule_set", "$@11", "rule_enumeration", "rule_enumeration_item", - "for_expression", "primary_expression", YY_NULLPTR + "for_expression", "for_quantifier", "primary_expression", YY_NULLPTR }; static const char * @@ -1011,7 +1012,7 @@ yysymbol_name (yysymbol_kind_t yysymbol) } #endif -#define YYPACT_NINF (-170) +#define YYPACT_NINF (-172) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -1025,34 +1026,34 @@ yysymbol_name (yysymbol_kind_t yysymbol) STATE-NUM. */ static const yytype_int16 yypact[] = { - -170, 107, -170, -38, -170, -17, -170, -170, 69, -170, - -170, -170, -170, 5, -170, -170, -170, -170, -42, 100, - 54, -170, 119, 128, -170, 72, 144, 145, 81, -170, - 84, 145, -170, 146, 150, 22, -170, 85, 146, -170, - 93, 98, -170, -170, -170, -170, 161, 74, -170, 66, - -170, -170, 162, 163, 165, -170, -15, 147, 106, 109, - -170, -170, 113, -170, -170, -170, -170, -170, -170, -170, - 132, -170, -170, 66, 66, 201, 201, 66, 61, -170, - 51, -170, 155, 280, -170, -170, -170, 201, 115, 115, - 201, 201, 201, 201, 6, 379, -170, -170, -170, -170, - 51, 105, 240, 66, 184, 201, -170, -170, -34, 174, - 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, - 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, - 201, 201, 157, 225, 103, 191, 379, 201, -170, -170, - 194, 290, 322, 341, -170, 8, 201, -170, -170, 123, - 130, 83, -170, 300, 66, 66, -170, 187, 181, -170, - -170, 379, 379, 379, 379, 379, 379, 379, 379, 379, - 379, 379, 379, 379, 24, 24, 389, 399, 139, 55, - 55, -170, -170, -34, -170, -170, -170, -170, 148, 149, - 151, -170, -170, -170, -170, -170, -170, -170, -170, -170, - -170, -170, 177, -170, -170, -170, -170, -8, 154, 4, - -170, 66, -170, 170, -170, 21, 214, 115, -170, -170, - 217, 216, 245, 201, -170, -170, -170, -170, -9, 226, - 83, -170, -170, -61, -170, 198, 38, -170, -170, -47, - 188, 190, 360, 192, 201, 61, -170, -170, -170, -170, - -170, 21, -170, -170, 214, 254, -170, -170, -170, -170, - 66, 39, 177, -170, -170, 195, -43, -170, 201, -170, - -170, 379 + -172, 121, -172, -39, -172, 2, -172, -172, 185, -172, + -172, -172, -172, 24, -172, -172, -172, -172, -38, 59, + 16, -172, 65, 95, -172, 29, 108, 107, 47, -172, + 48, 107, -172, 120, 126, 22, -172, 71, 120, -172, + 77, 80, -172, -172, -172, -172, 141, -6, -172, 66, + -172, -172, 140, 151, 162, -172, -16, 142, 112, 117, + -172, -172, 124, -172, -172, -172, -172, -172, -172, -172, + 132, -172, -172, 66, 66, 200, 200, 66, 104, -172, + 90, -172, 179, -172, 279, -172, -172, -172, 200, 143, + 143, 200, 200, 200, 200, 7, 378, -172, -172, -172, + -172, 90, 144, 239, 66, 214, 200, -172, -172, -35, + 204, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 157, 85, 133, 221, 378, 200, -172, + -172, 187, 289, 321, 340, -172, -4, 200, -172, -172, + 150, 147, 135, -172, 299, 66, 66, -172, 222, 198, + -172, -172, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 26, 26, 388, 398, 139, + 127, 127, -172, -172, -35, -172, -172, -172, -172, 158, + 159, 180, -172, -172, -172, -172, -172, -172, -172, -172, + -172, -172, -172, 177, -172, -172, -172, -172, -33, 183, + 4, -172, 66, -172, 208, -172, 5, 250, 143, -172, + -172, 245, 243, 244, 200, -172, -172, -172, -172, -9, + 254, 135, -172, -172, -47, -172, 202, 51, -172, -172, + -48, 189, 193, 359, 188, 200, 104, -172, -172, -172, + -172, -172, 5, -172, -172, 250, 256, -172, -172, -172, + -172, 66, 52, 177, -172, -172, 195, 23, -172, 200, + -172, -172, 378 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1065,40 +1066,40 @@ static const yytype_uint8 yydefact[] = 0, 24, 23, 13, 25, 0, 15, 0, 0, 11, 0, 14, 26, 0, 0, 0, 27, 0, 16, 33, 0, 0, 29, 28, 31, 32, 0, 35, 34, 0, - 12, 30, 0, 0, 0, 65, 85, 148, 150, 152, - 144, 145, 0, 146, 73, 141, 142, 137, 138, 139, - 0, 75, 76, 0, 0, 0, 0, 0, 153, 166, - 17, 74, 0, 109, 41, 55, 62, 0, 0, 0, - 0, 0, 0, 0, 0, 136, 97, 98, 154, 163, - 0, 74, 109, 69, 0, 0, 101, 99, 0, 0, + 12, 30, 0, 0, 0, 65, 85, 149, 151, 153, + 145, 146, 0, 147, 73, 142, 143, 138, 139, 140, + 0, 75, 76, 0, 0, 0, 0, 0, 154, 167, + 17, 74, 0, 137, 109, 41, 55, 62, 0, 0, + 0, 0, 0, 0, 0, 0, 136, 97, 98, 155, + 164, 0, 74, 109, 69, 0, 0, 101, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 38, 40, 86, 0, 87, 147, - 0, 0, 0, 0, 88, 0, 0, 110, 140, 0, - 70, 71, 66, 0, 0, 0, 125, 123, 92, 93, - 77, 78, 80, 82, 79, 81, 83, 84, 107, 108, - 103, 105, 104, 106, 164, 165, 162, 160, 161, 155, - 156, 157, 158, 0, 159, 47, 44, 43, 48, 51, - 53, 45, 46, 42, 61, 58, 57, 59, 60, 56, - 64, 63, 0, 149, 151, 143, 113, 0, 0, 0, - 68, 0, 67, 102, 100, 0, 0, 0, 94, 95, - 0, 0, 0, 0, 123, 112, 122, 90, 0, 0, - 72, 128, 129, 0, 126, 134, 0, 132, 96, 0, - 0, 0, 0, 0, 0, 115, 111, 116, 118, 114, - 124, 0, 135, 131, 0, 0, 49, 52, 54, 119, - 0, 0, 120, 127, 133, 0, 0, 117, 0, 50, - 91, 121 + 0, 0, 0, 0, 36, 38, 40, 86, 0, 87, + 148, 0, 0, 0, 0, 88, 0, 0, 110, 141, + 0, 70, 71, 66, 0, 0, 0, 125, 123, 92, + 93, 77, 78, 80, 82, 79, 81, 83, 84, 107, + 108, 103, 105, 104, 106, 165, 166, 163, 161, 162, + 156, 157, 158, 159, 0, 160, 47, 44, 43, 48, + 51, 53, 45, 46, 42, 61, 58, 57, 59, 60, + 56, 64, 63, 0, 150, 152, 144, 113, 0, 0, + 0, 68, 0, 67, 102, 100, 0, 0, 0, 94, + 95, 0, 0, 0, 0, 123, 112, 122, 90, 0, + 0, 72, 128, 129, 0, 126, 134, 0, 132, 96, + 0, 0, 0, 0, 0, 0, 115, 111, 116, 118, + 114, 124, 0, 135, 131, 0, 0, 49, 52, 54, + 119, 0, 0, 120, 127, 133, 0, 0, 117, 0, + 50, 91, 121 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -170, -170, 270, 272, -170, -170, -170, -170, -170, -170, - -170, -170, -170, -170, 247, -170, 250, -170, -170, -170, - -170, -170, -170, -170, -170, -170, 62, -170, -170, 180, - -49, -73, -170, -170, -170, -170, -170, -170, -170, -170, - -88, -170, -170, -169, -170, -170, 40, 110, -170, -170, - 57, 222, -64 + -172, -172, 272, 274, -172, -172, -172, -172, -172, -172, + -172, -172, -172, -172, 257, -172, 249, -172, -172, -172, + -172, -172, -172, -172, -172, -172, 60, -172, -172, 181, + -49, -74, -172, -172, -172, -172, -172, -172, -172, -172, + -89, -172, -172, -171, -172, -172, 38, 109, -172, -172, + 37, 240, -172, -65 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -1106,10 +1107,10 @@ static const yytype_int16 yydefgoto[] = { 0, 1, 6, 7, 18, 34, 26, 29, 41, 8, 16, 20, 22, 31, 32, 38, 39, 52, 53, 54, - 133, 193, 134, 199, 135, 201, 78, 149, 150, 79, - 100, 81, 145, 243, 155, 154, 208, 209, 246, 247, - 138, 261, 225, 158, 215, 233, 234, 159, 216, 236, - 237, 82, 83 + 134, 194, 135, 200, 136, 202, 78, 150, 151, 79, + 101, 81, 146, 244, 156, 155, 209, 210, 247, 248, + 139, 262, 226, 159, 216, 234, 235, 160, 217, 237, + 238, 82, 83, 84 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1117,104 +1118,104 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 80, 139, 55, 12, 101, 156, 95, 144, 106, 107, - 5, 98, 99, 102, 218, 87, 17, -89, 250, 206, - 255, 88, 251, 136, 96, 97, 140, 141, 142, 143, - 151, 156, 256, 231, 19, 9, 270, 232, 226, 42, - 228, 153, 43, -89, 157, 207, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 182, 184, 244, - 224, 44, 45, 202, 13, 14, 15, 55, 56, 57, - 58, 59, 184, 60, 61, 62, 63, 229, 64, 46, - 128, 129, 130, 131, 146, -39, -37, 65, 66, 67, - 68, 69, 106, 107, 70, 213, 214, 2, 3, 194, - 4, 21, -18, -18, -18, 71, 72, 253, 267, 73, - 74, 254, 268, 130, 131, 146, 195, 196, 23, 238, - 24, 197, 198, 75, -74, -74, 25, 76, 230, 103, - 248, 104, 105, 55, 77, 57, 58, 59, 27, 60, - 61, 62, 63, 28, 64, 5, 30, 33, 37, 242, - 40, 35, 47, 65, 66, 67, 68, 69, 55, 49, - 57, 58, 59, 50, 60, 61, 62, 63, 51, 64, - 262, 223, 84, 89, 147, 85, 86, 90, 65, 66, - 91, 92, 108, 137, 183, 152, 64, 200, -130, 75, - 123, 124, 210, 76, 271, 128, 129, 130, 131, 146, - 93, 266, 55, 211, 57, 58, 59, 217, 60, 61, - 62, 63, 107, 64, 75, 235, 220, 221, 76, 222, - 227, 185, 65, 66, 239, 93, 240, 249, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 146, 186, 187, - 188, 189, 190, 191, 192, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 146, 241, 252, 257, 75, 258, - 260, 265, 76, 10, 269, 11, 203, -136, 36, 93, - 109, 110, 111, 112, 113, 114, 115, 116, 48, 160, - 245, 263, 94, 219, 0, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 264, 0, 0, 0, 0, 0, -136, 0, 148, - 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 146, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 146, 0, 204, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 212, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 146, 0, 0, 0, 0, 0, 0, 0, - 0, 205, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 146, 0, 0, 0, 0, 0, 0, 0, 0, - 148, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 259, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 146, - 123, 124, 0, 126, 127, 128, 129, 130, 131, 146, - 123, 124, 0, 0, 127, 128, 129, 130, 131, 146 + 80, 140, 55, 102, 157, 96, 157, 207, 145, 5, + 99, 100, 103, 219, 88, -39, -37, 232, -89, 256, + 89, 233, 12, 137, 97, 98, 141, 142, 143, 144, + 152, 257, 251, 208, 9, 17, 252, 227, 19, 42, + 229, 154, 43, 158, -89, 225, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 185, 245, + 21, 44, 45, 203, 107, 108, 24, 55, 56, 57, + 58, 59, 185, 60, 61, 62, 63, 230, 64, 46, + 23, 186, 129, 130, 131, 132, 147, 65, 66, 67, + 68, 69, 271, 25, 70, 27, 214, 215, 187, 188, + 189, 190, 191, 192, 193, 71, 72, 28, 30, 73, + 74, 2, 3, 33, 4, 35, -18, -18, -18, 239, + 254, 268, 37, 75, 255, 269, 40, 76, 231, 195, + 249, 107, 108, 55, 77, 57, 58, 59, 47, 60, + 61, 62, 63, 49, 64, 50, 196, 197, 51, 243, + 85, 198, 199, 65, 66, 67, 68, 69, 55, 5, + 57, 58, 59, 86, 60, 61, 62, 63, 90, 64, + 263, 224, 104, 87, 105, 106, -74, -74, 65, 66, + 13, 14, 15, 91, 184, 131, 132, 147, 92, 75, + 124, 125, 93, 76, 272, 129, 130, 131, 132, 147, + 94, 55, 267, 57, 58, 59, 109, 60, 61, 62, + 63, 138, 64, 148, 75, 153, 64, 201, 76, 211, + 212, 65, 66, -130, 218, 94, 221, 222, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 147, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 147, 223, 228, + 108, 236, 240, 241, 242, 250, 261, 75, 258, 204, + 253, 76, 259, 266, 270, 10, -136, 11, 94, 110, + 111, 112, 113, 114, 115, 116, 117, 48, 36, 246, + 264, 161, 265, 220, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 95, 0, 0, 0, 0, 0, -136, 0, 149, 110, + 111, 112, 113, 114, 115, 116, 117, 0, 0, 0, + 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 147, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 147, + 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 213, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 147, 0, 0, 0, 0, 0, 0, 0, 0, + 206, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 147, 0, 0, 0, 0, 0, 0, 0, 0, 149, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 147, + 0, 0, 0, 0, 0, 0, 0, 0, 260, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 147, 124, + 125, 0, 127, 128, 129, 130, 131, 132, 147, 124, + 125, 0, 0, 128, 129, 130, 131, 132, 147 }; static const yytype_int16 yycheck[] = { - 49, 89, 11, 20, 77, 39, 70, 1, 51, 52, - 48, 75, 76, 77, 183, 30, 11, 11, 79, 11, - 67, 36, 83, 87, 73, 74, 90, 91, 92, 93, - 103, 39, 79, 12, 76, 73, 79, 16, 207, 17, - 36, 105, 20, 37, 78, 37, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 78, - 78, 49, 50, 137, 5, 6, 7, 11, 12, 13, - 14, 15, 146, 17, 18, 19, 20, 83, 22, 67, - 66, 67, 68, 69, 70, 21, 22, 31, 32, 33, - 34, 35, 51, 52, 38, 154, 155, 0, 1, 6, - 3, 11, 5, 6, 7, 49, 50, 79, 79, 53, - 54, 83, 83, 68, 69, 70, 23, 24, 74, 217, - 11, 28, 29, 67, 51, 52, 8, 71, 211, 78, - 228, 80, 81, 11, 78, 13, 14, 15, 76, 17, - 18, 19, 20, 9, 22, 48, 11, 76, 12, 223, - 10, 77, 77, 31, 32, 33, 34, 35, 11, 76, - 13, 14, 15, 75, 17, 18, 19, 20, 17, 22, - 244, 4, 20, 36, 79, 22, 21, 81, 31, 32, - 81, 78, 37, 78, 37, 11, 22, 6, 11, 67, - 61, 62, 79, 71, 268, 66, 67, 68, 69, 70, - 78, 260, 11, 83, 13, 14, 15, 36, 17, 18, - 19, 20, 52, 22, 67, 11, 78, 78, 71, 78, - 76, 6, 31, 32, 17, 78, 20, 11, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 23, 24, - 25, 26, 27, 28, 29, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 20, 68, 79, 67, 79, - 78, 17, 71, 3, 79, 3, 82, 37, 31, 78, - 40, 41, 42, 43, 44, 45, 46, 47, 38, 109, - 228, 251, 70, 183, -1, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 254, -1, -1, -1, -1, -1, 37, -1, 79, - 40, 41, 42, 43, 44, 45, 46, 47, -1, -1, - -1, -1, -1, -1, -1, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, -1, 82, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 82, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, -1, -1, -1, -1, -1, -1, -1, - -1, 79, 61, 62, 63, 64, 65, 66, 67, 68, + 49, 90, 11, 77, 39, 70, 39, 11, 1, 48, + 75, 76, 77, 184, 30, 21, 22, 12, 11, 67, + 36, 16, 20, 88, 73, 74, 91, 92, 93, 94, + 104, 79, 79, 37, 73, 11, 83, 208, 76, 17, + 36, 106, 20, 78, 37, 78, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 78, + 11, 49, 50, 138, 51, 52, 11, 11, 12, 13, + 14, 15, 147, 17, 18, 19, 20, 83, 22, 67, + 74, 6, 66, 67, 68, 69, 70, 31, 32, 33, + 34, 35, 79, 8, 38, 76, 155, 156, 23, 24, + 25, 26, 27, 28, 29, 49, 50, 9, 11, 53, + 54, 0, 1, 76, 3, 77, 5, 6, 7, 218, + 79, 79, 12, 67, 83, 83, 10, 71, 212, 6, + 229, 51, 52, 11, 78, 13, 14, 15, 77, 17, + 18, 19, 20, 76, 22, 75, 23, 24, 17, 224, + 20, 28, 29, 31, 32, 33, 34, 35, 11, 48, + 13, 14, 15, 22, 17, 18, 19, 20, 36, 22, + 245, 4, 78, 21, 80, 81, 51, 52, 31, 32, + 5, 6, 7, 81, 37, 68, 69, 70, 81, 67, + 61, 62, 78, 71, 269, 66, 67, 68, 69, 70, + 78, 11, 261, 13, 14, 15, 37, 17, 18, 19, + 20, 78, 22, 79, 67, 11, 22, 6, 71, 79, + 83, 31, 32, 11, 36, 78, 78, 78, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 78, 76, + 52, 11, 17, 20, 20, 11, 78, 67, 79, 82, + 68, 71, 79, 17, 79, 3, 37, 3, 78, 40, + 41, 42, 43, 44, 45, 46, 47, 38, 31, 229, + 252, 110, 255, 184, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 70, -1, -1, -1, -1, -1, 37, -1, 79, 40, + 41, 42, 43, 44, 45, 46, 47, -1, -1, -1, + -1, -1, -1, -1, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + -1, 82, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 82, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, -1, -1, -1, 79, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, -1, -1, -1, 79, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 61, 62, -1, 64, 65, 66, 67, 68, 69, 70, - 61, 62, -1, -1, 65, 66, 67, 68, 69, 70 + -1, -1, -1, -1, -1, -1, -1, -1, 79, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 61, + 62, -1, 64, 65, 66, 67, 68, 69, 70, 61, + 62, -1, -1, 65, 66, 67, 68, 69, 70 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of @@ -1229,26 +1230,26 @@ static const yytype_uint8 yystos[] = 75, 17, 101, 102, 103, 11, 12, 13, 14, 15, 17, 18, 19, 20, 22, 31, 32, 33, 34, 35, 38, 49, 50, 53, 54, 67, 71, 78, 110, 113, - 114, 115, 135, 136, 20, 22, 21, 30, 36, 36, - 81, 81, 78, 78, 135, 136, 114, 114, 136, 136, - 114, 115, 136, 78, 80, 81, 51, 52, 37, 40, - 41, 42, 43, 44, 45, 46, 47, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 104, 106, 108, 136, 78, 124, 124, - 136, 136, 136, 136, 1, 116, 70, 79, 79, 111, - 112, 115, 11, 136, 119, 118, 39, 78, 127, 131, - 113, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 37, 136, 6, 23, 24, 25, 26, - 27, 28, 29, 105, 6, 23, 24, 28, 29, 107, - 6, 109, 136, 82, 82, 79, 11, 37, 120, 121, - 79, 83, 82, 114, 114, 128, 132, 36, 127, 131, - 78, 78, 78, 4, 78, 126, 127, 76, 36, 83, - 115, 12, 16, 129, 130, 11, 133, 134, 124, 17, - 20, 20, 136, 117, 78, 110, 122, 123, 124, 11, - 79, 83, 68, 79, 83, 67, 79, 79, 79, 79, - 78, 125, 136, 130, 134, 17, 114, 79, 83, 79, - 79, 136 + 114, 115, 135, 136, 137, 20, 22, 21, 30, 36, + 36, 81, 81, 78, 78, 135, 137, 114, 114, 137, + 137, 114, 115, 137, 78, 80, 81, 51, 52, 37, + 40, 41, 42, 43, 44, 45, 46, 47, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 104, 106, 108, 137, 78, 124, + 124, 137, 137, 137, 137, 1, 116, 70, 79, 79, + 111, 112, 115, 11, 137, 119, 118, 39, 78, 127, + 131, 113, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 37, 137, 6, 23, 24, 25, + 26, 27, 28, 29, 105, 6, 23, 24, 28, 29, + 107, 6, 109, 137, 82, 82, 79, 11, 37, 120, + 121, 79, 83, 82, 114, 114, 128, 132, 36, 127, + 131, 78, 78, 78, 4, 78, 126, 127, 76, 36, + 83, 115, 12, 16, 129, 130, 11, 133, 134, 124, + 17, 20, 20, 137, 117, 78, 110, 122, 123, 124, + 11, 79, 83, 68, 79, 83, 67, 79, 79, 79, + 79, 78, 125, 137, 130, 134, 17, 114, 79, 83, + 79, 79, 137 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ @@ -1267,10 +1268,10 @@ static const yytype_uint8 yyr1[] = 115, 119, 115, 115, 115, 115, 115, 115, 115, 115, 115, 120, 120, 121, 121, 122, 122, 123, 123, 124, 125, 125, 126, 128, 127, 127, 129, 129, 130, 130, - 132, 131, 133, 133, 134, 134, 135, 135, 135, 135, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136 + 132, 131, 133, 133, 134, 134, 135, 135, 136, 136, + 136, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ @@ -1290,9 +1291,9 @@ static const yytype_int8 yyr2[] = 3, 3, 2, 1, 3, 1, 1, 3, 1, 5, 1, 3, 1, 0, 4, 1, 1, 3, 1, 1, 0, 4, 1, 3, 1, 2, 1, 1, 1, 1, - 3, 1, 1, 4, 1, 1, 1, 3, 1, 4, - 1, 4, 1, 1, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 2, 3, 3, 1 + 1, 3, 1, 1, 4, 1, 1, 1, 3, 1, + 4, 1, 4, 1, 1, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 2, 3, 3, 1 }; @@ -1767,61 +1768,61 @@ yydestruct (const char *yymsg, switch (yykind) { case YYSYMBOL__IDENTIFIER_: /* "identifier" */ -#line 306 "grammar.y" +#line 311 "grammar.y" { yr_free(((*yyvaluep).c_string)); ((*yyvaluep).c_string) = NULL; } -#line 1773 "grammar.c" +#line 1774 "grammar.c" break; case YYSYMBOL__STRING_IDENTIFIER_: /* "string identifier" */ -#line 310 "grammar.y" +#line 315 "grammar.y" { yr_free(((*yyvaluep).c_string)); ((*yyvaluep).c_string) = NULL; } -#line 1779 "grammar.c" +#line 1780 "grammar.c" break; case YYSYMBOL__STRING_COUNT_: /* "string count" */ -#line 307 "grammar.y" +#line 312 "grammar.y" { yr_free(((*yyvaluep).c_string)); ((*yyvaluep).c_string) = NULL; } -#line 1785 "grammar.c" +#line 1786 "grammar.c" break; case YYSYMBOL__STRING_OFFSET_: /* "string offset" */ -#line 308 "grammar.y" +#line 313 "grammar.y" { yr_free(((*yyvaluep).c_string)); ((*yyvaluep).c_string) = NULL; } -#line 1791 "grammar.c" +#line 1792 "grammar.c" break; case YYSYMBOL__STRING_LENGTH_: /* "string length" */ -#line 309 "grammar.y" +#line 314 "grammar.y" { yr_free(((*yyvaluep).c_string)); ((*yyvaluep).c_string) = NULL; } -#line 1797 "grammar.c" +#line 1798 "grammar.c" break; case YYSYMBOL__STRING_IDENTIFIER_WITH_WILDCARD_: /* "string identifier with wildcard" */ -#line 311 "grammar.y" +#line 316 "grammar.y" { yr_free(((*yyvaluep).c_string)); ((*yyvaluep).c_string) = NULL; } -#line 1803 "grammar.c" +#line 1804 "grammar.c" break; case YYSYMBOL__TEXT_STRING_: /* "text string" */ -#line 312 "grammar.y" +#line 317 "grammar.y" { yr_free(((*yyvaluep).sized_string)); ((*yyvaluep).sized_string) = NULL; } -#line 1809 "grammar.c" +#line 1810 "grammar.c" break; case YYSYMBOL__HEX_STRING_: /* "hex string" */ -#line 313 "grammar.y" +#line 318 "grammar.y" { yr_free(((*yyvaluep).sized_string)); ((*yyvaluep).sized_string) = NULL; } -#line 1815 "grammar.c" +#line 1816 "grammar.c" break; case YYSYMBOL__REGEXP_: /* "regular expression" */ -#line 314 "grammar.y" +#line 319 "grammar.y" { yr_free(((*yyvaluep).sized_string)); ((*yyvaluep).sized_string) = NULL; } -#line 1821 "grammar.c" +#line 1822 "grammar.c" break; case YYSYMBOL_string_modifiers: /* string_modifiers */ -#line 327 "grammar.y" +#line 332 "grammar.y" { if (((*yyvaluep).modifier).alphabet != NULL) { @@ -1829,11 +1830,11 @@ yydestruct (const char *yymsg, ((*yyvaluep).modifier).alphabet = NULL; } } -#line 1833 "grammar.c" +#line 1834 "grammar.c" break; case YYSYMBOL_string_modifier: /* string_modifier */ -#line 319 "grammar.y" +#line 324 "grammar.y" { if (((*yyvaluep).modifier).alphabet != NULL) { @@ -1841,19 +1842,19 @@ yydestruct (const char *yymsg, ((*yyvaluep).modifier).alphabet = NULL; } } -#line 1845 "grammar.c" +#line 1846 "grammar.c" break; case YYSYMBOL_arguments: /* arguments */ -#line 316 "grammar.y" +#line 321 "grammar.y" { yr_free(((*yyvaluep).c_string)); ((*yyvaluep).c_string) = NULL; } -#line 1851 "grammar.c" +#line 1852 "grammar.c" break; case YYSYMBOL_arguments_list: /* arguments_list */ -#line 317 "grammar.y" +#line 322 "grammar.y" { yr_free(((*yyvaluep).c_string)); ((*yyvaluep).c_string) = NULL; } -#line 1857 "grammar.c" +#line 1858 "grammar.c" break; default: @@ -2130,15 +2131,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); switch (yyn) { case 8: /* rules: rules "end of included file" */ -#line 361 "grammar.y" +#line 366 "grammar.y" { _yr_compiler_pop_file_name(compiler); } -#line 2138 "grammar.c" +#line 2139 "grammar.c" break; case 9: /* import: "" "text string" */ -#line 369 "grammar.y" +#line 374 "grammar.y" { int result = yr_parser_reduce_import(yyscanner, (yyvsp[0].sized_string)); @@ -2146,20 +2147,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2150 "grammar.c" +#line 2151 "grammar.c" break; case 10: /* @1: %empty */ -#line 381 "grammar.y" +#line 386 "grammar.y" { fail_if_error(yr_parser_reduce_rule_declaration_phase_1( yyscanner, (int32_t) (yyvsp[-2].integer), (yyvsp[0].c_string), &(yyval.rule))); } -#line 2159 "grammar.c" +#line 2160 "grammar.c" break; case 11: /* $@2: %empty */ -#line 386 "grammar.y" +#line 391 "grammar.y" { YR_RULE* rule = (YR_RULE*) yr_arena_ref_to_ptr( compiler->arena, &(yyvsp[-4].rule)); @@ -2173,11 +2174,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); rule->strings = (YR_STRING*) yr_arena_ref_to_ptr( compiler->arena, &(yyvsp[0].string)); } -#line 2177 "grammar.c" +#line 2178 "grammar.c" break; case 12: /* rule: rule_modifiers "" "identifier" @1 tags '{' meta strings $@2 condition '}' */ -#line 400 "grammar.y" +#line 405 "grammar.y" { int result = yr_parser_reduce_rule_declaration_phase_2( yyscanner, &(yyvsp[-7].rule)); // rule created in phase 1 @@ -2186,19 +2187,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2190 "grammar.c" +#line 2191 "grammar.c" break; case 13: /* meta: %empty */ -#line 413 "grammar.y" +#line 418 "grammar.y" { (yyval.meta) = YR_ARENA_NULL_REF; } -#line 2198 "grammar.c" +#line 2199 "grammar.c" break; case 14: /* meta: "" ':' meta_declarations */ -#line 417 "grammar.y" +#line 422 "grammar.y" { YR_META* meta = yr_arena_get_ptr( compiler->arena, @@ -2209,19 +2210,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.meta) = (yyvsp[0].meta); } -#line 2213 "grammar.c" +#line 2214 "grammar.c" break; case 15: /* strings: %empty */ -#line 432 "grammar.y" +#line 437 "grammar.y" { (yyval.string) = YR_ARENA_NULL_REF; } -#line 2221 "grammar.c" +#line 2222 "grammar.c" break; case 16: /* strings: "" ':' string_declarations */ -#line 436 "grammar.y" +#line 441 "grammar.y" { YR_STRING* string = (YR_STRING*) yr_arena_get_ptr( compiler->arena, @@ -2232,43 +2233,43 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.string) = (yyvsp[0].string); } -#line 2236 "grammar.c" +#line 2237 "grammar.c" break; case 18: /* rule_modifiers: %empty */ -#line 455 "grammar.y" +#line 460 "grammar.y" { (yyval.integer) = 0; } -#line 2242 "grammar.c" +#line 2243 "grammar.c" break; case 19: /* rule_modifiers: rule_modifiers rule_modifier */ -#line 456 "grammar.y" +#line 461 "grammar.y" { (yyval.integer) = (yyvsp[-1].integer) | (yyvsp[0].integer); } -#line 2248 "grammar.c" +#line 2249 "grammar.c" break; case 20: /* rule_modifier: "" */ -#line 461 "grammar.y" +#line 466 "grammar.y" { (yyval.integer) = RULE_FLAGS_PRIVATE; } -#line 2254 "grammar.c" +#line 2255 "grammar.c" break; case 21: /* rule_modifier: "" */ -#line 462 "grammar.y" +#line 467 "grammar.y" { (yyval.integer) = RULE_FLAGS_GLOBAL; } -#line 2260 "grammar.c" +#line 2261 "grammar.c" break; case 22: /* tags: %empty */ -#line 468 "grammar.y" +#line 473 "grammar.y" { (yyval.tag) = YR_ARENA_NULL_REF; } -#line 2268 "grammar.c" +#line 2269 "grammar.c" break; case 23: /* tags: ':' tag_list */ -#line 472 "grammar.y" +#line 477 "grammar.y" { // Tags list is represented in the arena as a sequence // of null-terminated strings, the sequence ends with an @@ -2280,11 +2281,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.tag) = (yyvsp[0].tag); } -#line 2284 "grammar.c" +#line 2285 "grammar.c" break; case 24: /* tag_list: "identifier" */ -#line 488 "grammar.y" +#line 493 "grammar.y" { int result = yr_arena_write_string( yyget_extra(yyscanner)->arena, YR_SZ_POOL, (yyvsp[0].c_string), &(yyval.tag)); @@ -2293,11 +2294,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2297 "grammar.c" +#line 2298 "grammar.c" break; case 25: /* tag_list: tag_list "identifier" */ -#line 497 "grammar.y" +#line 502 "grammar.y" { YR_ARENA_REF ref; @@ -2334,23 +2335,23 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.tag) = (yyvsp[-1].tag); } -#line 2338 "grammar.c" +#line 2339 "grammar.c" break; case 26: /* meta_declarations: meta_declaration */ -#line 538 "grammar.y" +#line 543 "grammar.y" { (yyval.meta) = (yyvsp[0].meta); } -#line 2344 "grammar.c" +#line 2345 "grammar.c" break; case 27: /* meta_declarations: meta_declarations meta_declaration */ -#line 539 "grammar.y" +#line 544 "grammar.y" { (yyval.meta) = (yyvsp[-1].meta); } -#line 2350 "grammar.c" +#line 2351 "grammar.c" break; case 28: /* meta_declaration: "identifier" '=' "text string" */ -#line 545 "grammar.y" +#line 550 "grammar.y" { SIZED_STRING* sized_string = (yyvsp[0].sized_string); @@ -2367,11 +2368,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2371 "grammar.c" +#line 2372 "grammar.c" break; case 29: /* meta_declaration: "identifier" '=' "integer number" */ -#line 562 "grammar.y" +#line 567 "grammar.y" { int result = yr_parser_reduce_meta_declaration( yyscanner, @@ -2385,11 +2386,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2389 "grammar.c" +#line 2390 "grammar.c" break; case 30: /* meta_declaration: "identifier" '=' '-' "integer number" */ -#line 576 "grammar.y" +#line 581 "grammar.y" { int result = yr_parser_reduce_meta_declaration( yyscanner, @@ -2403,11 +2404,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2407 "grammar.c" +#line 2408 "grammar.c" break; case 31: /* meta_declaration: "identifier" '=' "" */ -#line 590 "grammar.y" +#line 595 "grammar.y" { int result = yr_parser_reduce_meta_declaration( yyscanner, @@ -2421,11 +2422,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2425 "grammar.c" +#line 2426 "grammar.c" break; case 32: /* meta_declaration: "identifier" '=' "" */ -#line 604 "grammar.y" +#line 609 "grammar.y" { int result = yr_parser_reduce_meta_declaration( yyscanner, @@ -2439,31 +2440,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2443 "grammar.c" +#line 2444 "grammar.c" break; case 33: /* string_declarations: string_declaration */ -#line 621 "grammar.y" +#line 626 "grammar.y" { (yyval.string) = (yyvsp[0].string); } -#line 2449 "grammar.c" +#line 2450 "grammar.c" break; case 34: /* string_declarations: string_declarations string_declaration */ -#line 622 "grammar.y" +#line 627 "grammar.y" { (yyval.string) = (yyvsp[-1].string); } -#line 2455 "grammar.c" +#line 2456 "grammar.c" break; case 35: /* $@3: %empty */ -#line 628 "grammar.y" +#line 633 "grammar.y" { compiler->current_line = yyget_lineno(yyscanner); } -#line 2463 "grammar.c" +#line 2464 "grammar.c" break; case 36: /* string_declaration: "string identifier" '=' $@3 "text string" string_modifiers */ -#line 632 "grammar.y" +#line 637 "grammar.y" { int result = yr_parser_reduce_string_declaration( yyscanner, (yyvsp[0].modifier), (yyvsp[-4].c_string), (yyvsp[-1].sized_string), &(yyval.string)); @@ -2475,19 +2476,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); compiler->current_line = 0; } -#line 2479 "grammar.c" +#line 2480 "grammar.c" break; case 37: /* $@4: %empty */ -#line 644 "grammar.y" +#line 649 "grammar.y" { compiler->current_line = yyget_lineno(yyscanner); } -#line 2487 "grammar.c" +#line 2488 "grammar.c" break; case 38: /* string_declaration: "string identifier" '=' $@4 "regular expression" regexp_modifiers */ -#line 648 "grammar.y" +#line 653 "grammar.y" { int result; @@ -2503,19 +2504,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); compiler->current_line = 0; } -#line 2507 "grammar.c" +#line 2508 "grammar.c" break; case 39: /* $@5: %empty */ -#line 664 "grammar.y" +#line 669 "grammar.y" { compiler->current_line = yyget_lineno(yyscanner); } -#line 2515 "grammar.c" +#line 2516 "grammar.c" break; case 40: /* string_declaration: "string identifier" '=' $@5 "hex string" hex_modifiers */ -#line 668 "grammar.y" +#line 673 "grammar.y" { int result; @@ -2531,22 +2532,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); compiler->current_line = 0; } -#line 2535 "grammar.c" +#line 2536 "grammar.c" break; case 41: /* string_modifiers: %empty */ -#line 688 "grammar.y" +#line 693 "grammar.y" { (yyval.modifier).flags = 0; (yyval.modifier).xor_min = 0; (yyval.modifier).xor_max = 0; (yyval.modifier).alphabet = NULL; } -#line 2546 "grammar.c" +#line 2547 "grammar.c" break; case 42: /* string_modifiers: string_modifiers string_modifier */ -#line 695 "grammar.y" +#line 700 "grammar.y" { (yyval.modifier) = (yyvsp[-1].modifier); @@ -2602,51 +2603,51 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.modifier).flags = (yyval.modifier).flags | (yyvsp[0].modifier).flags; } } -#line 2606 "grammar.c" +#line 2607 "grammar.c" break; case 43: /* string_modifier: "" */ -#line 754 "grammar.y" +#line 759 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_WIDE; } -#line 2612 "grammar.c" +#line 2613 "grammar.c" break; case 44: /* string_modifier: "" */ -#line 755 "grammar.y" +#line 760 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_ASCII; } -#line 2618 "grammar.c" +#line 2619 "grammar.c" break; case 45: /* string_modifier: "" */ -#line 756 "grammar.y" +#line 761 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_NO_CASE; } -#line 2624 "grammar.c" +#line 2625 "grammar.c" break; case 46: /* string_modifier: "" */ -#line 757 "grammar.y" +#line 762 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_FULL_WORD; } -#line 2630 "grammar.c" +#line 2631 "grammar.c" break; case 47: /* string_modifier: "" */ -#line 758 "grammar.y" +#line 763 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_PRIVATE; } -#line 2636 "grammar.c" +#line 2637 "grammar.c" break; case 48: /* string_modifier: "" */ -#line 760 "grammar.y" +#line 765 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_XOR; (yyval.modifier).xor_min = 0; (yyval.modifier).xor_max = 255; } -#line 2646 "grammar.c" +#line 2647 "grammar.c" break; case 49: /* string_modifier: "" '(' "integer number" ')' */ -#line 766 "grammar.y" +#line 771 "grammar.y" { int result = ERROR_SUCCESS; @@ -2662,11 +2663,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.modifier).xor_min = (uint8_t) (yyvsp[-1].integer); (yyval.modifier).xor_max = (uint8_t) (yyvsp[-1].integer); } -#line 2666 "grammar.c" +#line 2667 "grammar.c" break; case 50: /* string_modifier: "" '(' "integer number" '-' "integer number" ')' */ -#line 787 "grammar.y" +#line 792 "grammar.y" { int result = ERROR_SUCCESS; @@ -2697,20 +2698,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.modifier).xor_min = (uint8_t) (yyvsp[-3].integer); (yyval.modifier).xor_max = (uint8_t) (yyvsp[-1].integer); } -#line 2701 "grammar.c" +#line 2702 "grammar.c" break; case 51: /* string_modifier: "" */ -#line 818 "grammar.y" +#line 823 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_BASE64; (yyval.modifier).alphabet = ss_new(DEFAULT_BASE64_ALPHABET); } -#line 2710 "grammar.c" +#line 2711 "grammar.c" break; case 52: /* string_modifier: "" '(' "text string" ')' */ -#line 823 "grammar.y" +#line 828 "grammar.y" { int result = ERROR_SUCCESS; @@ -2727,20 +2728,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.modifier).flags = STRING_FLAGS_BASE64; (yyval.modifier).alphabet = (yyvsp[-1].sized_string); } -#line 2731 "grammar.c" +#line 2732 "grammar.c" break; case 53: /* string_modifier: "" */ -#line 840 "grammar.y" +#line 845 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_BASE64_WIDE; (yyval.modifier).alphabet = ss_new(DEFAULT_BASE64_ALPHABET); } -#line 2740 "grammar.c" +#line 2741 "grammar.c" break; case 54: /* string_modifier: "" '(' "text string" ')' */ -#line 845 "grammar.y" +#line 850 "grammar.y" { int result = ERROR_SUCCESS; @@ -2757,17 +2758,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.modifier).flags = STRING_FLAGS_BASE64_WIDE; (yyval.modifier).alphabet = (yyvsp[-1].sized_string); } -#line 2761 "grammar.c" +#line 2762 "grammar.c" break; case 55: /* regexp_modifiers: %empty */ -#line 864 "grammar.y" +#line 869 "grammar.y" { (yyval.modifier).flags = 0; } -#line 2767 "grammar.c" +#line 2768 "grammar.c" break; case 56: /* regexp_modifiers: regexp_modifiers regexp_modifier */ -#line 866 "grammar.y" +#line 871 "grammar.y" { if ((yyvsp[-1].modifier).flags & (yyvsp[0].modifier).flags) { @@ -2778,47 +2779,47 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.modifier).flags = (yyvsp[-1].modifier).flags | (yyvsp[0].modifier).flags; } } -#line 2782 "grammar.c" +#line 2783 "grammar.c" break; case 57: /* regexp_modifier: "" */ -#line 879 "grammar.y" +#line 884 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_WIDE; } -#line 2788 "grammar.c" +#line 2789 "grammar.c" break; case 58: /* regexp_modifier: "" */ -#line 880 "grammar.y" +#line 885 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_ASCII; } -#line 2794 "grammar.c" +#line 2795 "grammar.c" break; case 59: /* regexp_modifier: "" */ -#line 881 "grammar.y" +#line 886 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_NO_CASE; } -#line 2800 "grammar.c" +#line 2801 "grammar.c" break; case 60: /* regexp_modifier: "" */ -#line 882 "grammar.y" +#line 887 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_FULL_WORD; } -#line 2806 "grammar.c" +#line 2807 "grammar.c" break; case 61: /* regexp_modifier: "" */ -#line 883 "grammar.y" +#line 888 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_PRIVATE; } -#line 2812 "grammar.c" +#line 2813 "grammar.c" break; case 62: /* hex_modifiers: %empty */ -#line 887 "grammar.y" +#line 892 "grammar.y" { (yyval.modifier).flags = 0; } -#line 2818 "grammar.c" +#line 2819 "grammar.c" break; case 63: /* hex_modifiers: hex_modifiers hex_modifier */ -#line 889 "grammar.y" +#line 894 "grammar.y" { if ((yyvsp[-1].modifier).flags & (yyvsp[0].modifier).flags) { @@ -2829,17 +2830,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.modifier).flags = (yyvsp[-1].modifier).flags | (yyvsp[0].modifier).flags; } } -#line 2833 "grammar.c" +#line 2834 "grammar.c" break; case 64: /* hex_modifier: "" */ -#line 902 "grammar.y" +#line 907 "grammar.y" { (yyval.modifier).flags = STRING_FLAGS_PRIVATE; } -#line 2839 "grammar.c" +#line 2840 "grammar.c" break; case 65: /* identifier: "identifier" */ -#line 907 "grammar.y" +#line 912 "grammar.y" { YR_EXPRESSION expr; @@ -2934,11 +2935,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2938 "grammar.c" +#line 2939 "grammar.c" break; case 66: /* identifier: identifier '.' "identifier" */ -#line 1002 "grammar.y" +#line 1007 "grammar.y" { int result = ERROR_SUCCESS; YR_OBJECT* field = NULL; @@ -2986,11 +2987,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 2990 "grammar.c" +#line 2991 "grammar.c" break; case 67: /* identifier: identifier '[' primary_expression ']' */ -#line 1050 "grammar.y" +#line 1055 "grammar.y" { int result = ERROR_SUCCESS; YR_OBJECT_ARRAY* array; @@ -3050,11 +3051,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 3054 "grammar.c" +#line 3055 "grammar.c" break; case 68: /* identifier: identifier '(' arguments ')' */ -#line 1111 "grammar.y" +#line 1116 "grammar.y" { YR_ARENA_REF ref = YR_ARENA_NULL_REF; int result = ERROR_SUCCESS; @@ -3095,23 +3096,23 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 3099 "grammar.c" +#line 3100 "grammar.c" break; case 69: /* arguments: %empty */ -#line 1155 "grammar.y" +#line 1160 "grammar.y" { (yyval.c_string) = yr_strdup(""); } -#line 3105 "grammar.c" +#line 3106 "grammar.c" break; case 70: /* arguments: arguments_list */ -#line 1156 "grammar.y" +#line 1161 "grammar.y" { (yyval.c_string) = (yyvsp[0].c_string); } -#line 3111 "grammar.c" +#line 3112 "grammar.c" break; case 71: /* arguments_list: expression */ -#line 1161 "grammar.y" +#line 1166 "grammar.y" { (yyval.c_string) = (char*) yr_malloc(YR_MAX_FUNCTION_ARGS + 1); @@ -3146,11 +3147,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); assert(compiler->last_error != ERROR_SUCCESS); } } -#line 3150 "grammar.c" +#line 3151 "grammar.c" break; case 72: /* arguments_list: arguments_list ',' expression */ -#line 1196 "grammar.y" +#line 1201 "grammar.y" { int result = ERROR_SUCCESS; @@ -3199,11 +3200,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.c_string) = (yyvsp[-2].c_string); } -#line 3203 "grammar.c" +#line 3204 "grammar.c" break; case 73: /* regexp: "regular expression" */ -#line 1249 "grammar.y" +#line 1254 "grammar.y" { YR_ARENA_REF re_ref; RE_ERROR error; @@ -3241,11 +3242,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_REGEXP; } -#line 3245 "grammar.c" +#line 3246 "grammar.c" break; case 74: /* boolean_expression: expression */ -#line 1291 "grammar.y" +#line 1296 "grammar.y" { if ((yyvsp[0].expression).type == EXPRESSION_TYPE_STRING) { @@ -3265,31 +3266,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3269 "grammar.c" +#line 3270 "grammar.c" break; case 75: /* expression: "" */ -#line 1314 "grammar.y" +#line 1319 "grammar.y" { fail_if_error(yr_parser_emit_push_const(yyscanner, 1)); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3279 "grammar.c" +#line 3280 "grammar.c" break; case 76: /* expression: "" */ -#line 1320 "grammar.y" +#line 1325 "grammar.y" { fail_if_error(yr_parser_emit_push_const(yyscanner, 0)); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3289 "grammar.c" +#line 3290 "grammar.c" break; case 77: /* expression: primary_expression "" regexp */ -#line 1326 "grammar.y" +#line 1331 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "matches"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_REGEXP, "matches"); @@ -3301,11 +3302,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3305 "grammar.c" +#line 3306 "grammar.c" break; case 78: /* expression: primary_expression "" primary_expression */ -#line 1338 "grammar.y" +#line 1343 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "contains"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "contains"); @@ -3315,11 +3316,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3319 "grammar.c" +#line 3320 "grammar.c" break; case 79: /* expression: primary_expression "" primary_expression */ -#line 1348 "grammar.y" +#line 1353 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "icontains"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "icontains"); @@ -3329,11 +3330,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3333 "grammar.c" +#line 3334 "grammar.c" break; case 80: /* expression: primary_expression "" primary_expression */ -#line 1358 "grammar.y" +#line 1363 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "startswith"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "startswith"); @@ -3343,11 +3344,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3347 "grammar.c" +#line 3348 "grammar.c" break; case 81: /* expression: primary_expression "" primary_expression */ -#line 1368 "grammar.y" +#line 1373 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "istartswith"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "istartswith"); @@ -3357,11 +3358,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3361 "grammar.c" +#line 3362 "grammar.c" break; case 82: /* expression: primary_expression "" primary_expression */ -#line 1378 "grammar.y" +#line 1383 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "endswith"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "endswith"); @@ -3371,11 +3372,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3375 "grammar.c" +#line 3376 "grammar.c" break; case 83: /* expression: primary_expression "" primary_expression */ -#line 1388 "grammar.y" +#line 1393 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "iendswith"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "iendswith"); @@ -3385,11 +3386,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3389 "grammar.c" +#line 3390 "grammar.c" break; case 84: /* expression: primary_expression "" primary_expression */ -#line 1398 "grammar.y" +#line 1403 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "iequals"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "iequals"); @@ -3399,11 +3400,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3403 "grammar.c" +#line 3404 "grammar.c" break; case 85: /* expression: "string identifier" */ -#line 1408 "grammar.y" +#line 1413 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, @@ -3417,11 +3418,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3421 "grammar.c" +#line 3422 "grammar.c" break; case 86: /* expression: "string identifier" "" primary_expression */ -#line 1422 "grammar.y" +#line 1427 "grammar.y" { int result; @@ -3436,11 +3437,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3440 "grammar.c" +#line 3441 "grammar.c" break; case 87: /* expression: "string identifier" "" range */ -#line 1437 "grammar.y" +#line 1442 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[-2].c_string), OP_FOUND_IN, YR_UNDEFINED); @@ -3451,11 +3452,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3455 "grammar.c" +#line 3456 "grammar.c" break; case 88: /* expression: "" for_expression error */ -#line 1448 "grammar.y" +#line 1453 "grammar.y" { // Free all the loop variable identifiers, including the variables for // the current loop (represented by loop_index), and set loop_index to @@ -3472,11 +3473,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); compiler->loop_index = -1; YYERROR; } -#line 3476 "grammar.c" +#line 3477 "grammar.c" break; case 89: /* $@6: %empty */ -#line 1522 "grammar.y" +#line 1527 "grammar.y" { // var_frame is used for accessing local variables used in this loop. // All local variables are accessed using var_frame as a reference, @@ -3514,11 +3515,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(yr_parser_emit_with_arg( yyscanner, OP_POP_M, var_frame + 2, NULL, NULL)); } -#line 3518 "grammar.c" +#line 3519 "grammar.c" break; case 90: /* $@7: %empty */ -#line 1560 "grammar.y" +#line 1565 "grammar.y" { YR_LOOP_CONTEXT* loop_ctx = &compiler->loop[compiler->loop_index]; YR_FIXUP* fixup; @@ -3567,11 +3568,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); loop_ctx->start_ref = loop_start_ref; } -#line 3571 "grammar.c" +#line 3572 "grammar.c" break; case 91: /* expression: "" for_expression $@6 for_iteration ':' $@7 '(' boolean_expression ')' */ -#line 1609 "grammar.y" +#line 1614 "grammar.y" { int32_t jmp_offset; YR_FIXUP* fixup; @@ -3651,31 +3652,41 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3655 "grammar.c" +#line 3656 "grammar.c" break; case 92: /* expression: for_expression "" string_set */ -#line 1689 "grammar.y" +#line 1694 "grammar.y" { + if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER && (yyvsp[-2].expression).value.integer > (yyvsp[0].integer)) + { + yywarning(yyscanner, + "expression always false - requesting %lld of %lld.", (yyvsp[-2].expression).value.integer, (yyvsp[0].integer)); + } yr_parser_emit_with_arg(yyscanner, OP_OF, OF_STRING_SET, NULL, NULL); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3665 "grammar.c" +#line 3671 "grammar.c" break; case 93: /* expression: for_expression "" rule_set */ -#line 1695 "grammar.y" +#line 1705 "grammar.y" { + if ((yyvsp[-2].expression).type == EXPRESSION_TYPE_INTEGER && (yyvsp[-2].expression).value.integer > (yyvsp[0].integer)) + { + yywarning(yyscanner, + "expression always false - requesting %lld of %lld.", (yyvsp[-2].expression).value.integer, (yyvsp[0].integer)); + } yr_parser_emit_with_arg(yyscanner, OP_OF, OF_RULE_SET, NULL, NULL); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3675 "grammar.c" +#line 3686 "grammar.c" break; case 94: /* expression: primary_expression '%' "" string_set */ -#line 1701 "grammar.y" +#line 1716 "grammar.y" { check_type((yyvsp[-3].expression), EXPRESSION_TYPE_INTEGER, "%"); @@ -3694,11 +3705,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yr_parser_emit_with_arg(yyscanner, OP_OF_PERCENT, OF_STRING_SET, NULL, NULL); } -#line 3698 "grammar.c" +#line 3709 "grammar.c" break; case 95: /* expression: primary_expression '%' "" rule_set */ -#line 1720 "grammar.y" +#line 1735 "grammar.y" { check_type((yyvsp[-3].expression), EXPRESSION_TYPE_INTEGER, "%"); @@ -3717,40 +3728,46 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yr_parser_emit_with_arg(yyscanner, OP_OF_PERCENT, OF_RULE_SET, NULL, NULL); } -#line 3721 "grammar.c" +#line 3732 "grammar.c" break; case 96: /* expression: for_expression "" string_set "" range */ -#line 1739 "grammar.y" +#line 1754 "grammar.y" { + if ((yyvsp[-4].expression).type == EXPRESSION_TYPE_INTEGER && (yyvsp[-4].expression).value.integer > (yyvsp[-2].integer)) + { + yywarning(yyscanner, + "expression always false - requesting %lld of %lld.", (yyvsp[-4].expression).value.integer, (yyvsp[-2].integer)); + } + yr_parser_emit(yyscanner, OP_OF_FOUND_IN, NULL); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3731 "grammar.c" +#line 3748 "grammar.c" break; case 97: /* expression: "" boolean_expression */ -#line 1745 "grammar.y" +#line 1766 "grammar.y" { yr_parser_emit(yyscanner, OP_NOT, NULL); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3741 "grammar.c" +#line 3758 "grammar.c" break; case 98: /* expression: "" boolean_expression */ -#line 1751 "grammar.y" +#line 1772 "grammar.y" { yr_parser_emit(yyscanner, OP_DEFINED, NULL); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3750 "grammar.c" +#line 3767 "grammar.c" break; case 99: /* $@8: %empty */ -#line 1756 "grammar.y" +#line 1777 "grammar.y" { YR_FIXUP* fixup; YR_ARENA_REF jmp_offset_ref; @@ -3772,11 +3789,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fixup->next = compiler->fixup_stack_head; compiler->fixup_stack_head = fixup; } -#line 3776 "grammar.c" +#line 3793 "grammar.c" break; case 100: /* expression: boolean_expression "" $@8 boolean_expression */ -#line 1778 "grammar.y" +#line 1799 "grammar.y" { YR_FIXUP* fixup; @@ -3799,11 +3816,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3803 "grammar.c" +#line 3820 "grammar.c" break; case 101: /* $@9: %empty */ -#line 1801 "grammar.y" +#line 1822 "grammar.y" { YR_FIXUP* fixup; YR_ARENA_REF jmp_offset_ref; @@ -3824,11 +3841,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fixup->next = compiler->fixup_stack_head; compiler->fixup_stack_head = fixup; } -#line 3828 "grammar.c" +#line 3845 "grammar.c" break; case 102: /* expression: boolean_expression "" $@9 boolean_expression */ -#line 1822 "grammar.y" +#line 1843 "grammar.y" { YR_FIXUP* fixup; @@ -3851,99 +3868,99 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3855 "grammar.c" +#line 3872 "grammar.c" break; case 103: /* expression: primary_expression "<" primary_expression */ -#line 1845 "grammar.y" +#line 1866 "grammar.y" { fail_if_error(yr_parser_reduce_operation( yyscanner, "<", (yyvsp[-2].expression), (yyvsp[0].expression))); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3866 "grammar.c" +#line 3883 "grammar.c" break; case 104: /* expression: primary_expression ">" primary_expression */ -#line 1852 "grammar.y" +#line 1873 "grammar.y" { fail_if_error(yr_parser_reduce_operation( yyscanner, ">", (yyvsp[-2].expression), (yyvsp[0].expression))); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3877 "grammar.c" +#line 3894 "grammar.c" break; case 105: /* expression: primary_expression "<=" primary_expression */ -#line 1859 "grammar.y" +#line 1880 "grammar.y" { fail_if_error(yr_parser_reduce_operation( yyscanner, "<=", (yyvsp[-2].expression), (yyvsp[0].expression))); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3888 "grammar.c" +#line 3905 "grammar.c" break; case 106: /* expression: primary_expression ">=" primary_expression */ -#line 1866 "grammar.y" +#line 1887 "grammar.y" { fail_if_error(yr_parser_reduce_operation( yyscanner, ">=", (yyvsp[-2].expression), (yyvsp[0].expression))); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3899 "grammar.c" +#line 3916 "grammar.c" break; case 107: /* expression: primary_expression "==" primary_expression */ -#line 1873 "grammar.y" +#line 1894 "grammar.y" { fail_if_error(yr_parser_reduce_operation( yyscanner, "==", (yyvsp[-2].expression), (yyvsp[0].expression))); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3910 "grammar.c" +#line 3927 "grammar.c" break; case 108: /* expression: primary_expression "!=" primary_expression */ -#line 1880 "grammar.y" +#line 1901 "grammar.y" { fail_if_error(yr_parser_reduce_operation( yyscanner, "!=", (yyvsp[-2].expression), (yyvsp[0].expression))); (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; } -#line 3921 "grammar.c" +#line 3938 "grammar.c" break; case 109: /* expression: primary_expression */ -#line 1887 "grammar.y" +#line 1908 "grammar.y" { (yyval.expression) = (yyvsp[0].expression); } -#line 3929 "grammar.c" +#line 3946 "grammar.c" break; case 110: /* expression: '(' expression ')' */ -#line 1891 "grammar.y" +#line 1912 "grammar.y" { (yyval.expression) = (yyvsp[-1].expression); } -#line 3937 "grammar.c" +#line 3954 "grammar.c" break; case 111: /* for_iteration: for_variables "" iterator */ -#line 1898 "grammar.y" +#line 1919 "grammar.y" { (yyval.integer) = FOR_ITERATION_ITERATOR; } -#line 3943 "grammar.c" +#line 3960 "grammar.c" break; case 112: /* for_iteration: "" string_iterator */ -#line 1900 "grammar.y" +#line 1921 "grammar.y" { int var_frame; int result = ERROR_SUCCESS; @@ -3964,11 +3981,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.integer) = FOR_ITERATION_STRING_SET; } -#line 3968 "grammar.c" +#line 3985 "grammar.c" break; case 113: /* for_variables: "identifier" */ -#line 1925 "grammar.y" +#line 1946 "grammar.y" { int result = ERROR_SUCCESS; @@ -3988,11 +4005,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); assert(loop_ctx->vars_count <= YR_MAX_LOOP_VARS); } -#line 3992 "grammar.c" +#line 4009 "grammar.c" break; case 114: /* for_variables: for_variables ',' "identifier" */ -#line 1945 "grammar.y" +#line 1966 "grammar.y" { int result = ERROR_SUCCESS; @@ -4017,11 +4034,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); loop_ctx->vars[loop_ctx->vars_count++].identifier.ptr = (yyvsp[0].c_string); } -#line 4021 "grammar.c" +#line 4038 "grammar.c" break; case 115: /* iterator: identifier */ -#line 1973 "grammar.y" +#line 1994 "grammar.y" { YR_LOOP_CONTEXT* loop_ctx = &compiler->loop[compiler->loop_index]; @@ -4095,11 +4112,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4099 "grammar.c" +#line 4116 "grammar.c" break; case 116: /* iterator: integer_set */ -#line 2047 "grammar.y" +#line 2068 "grammar.y" { int result = ERROR_SUCCESS; @@ -4123,11 +4140,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4127 "grammar.c" +#line 4144 "grammar.c" break; case 117: /* integer_set: '(' integer_enumeration ')' */ -#line 2075 "grammar.y" +#line 2096 "grammar.y" { // $2 contains the number of integers in the enumeration fail_if_error(yr_parser_emit_push_const(yyscanner, (yyvsp[-1].integer))); @@ -4135,20 +4152,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(yr_parser_emit( yyscanner, OP_ITER_START_INT_ENUM, NULL)); } -#line 4139 "grammar.c" +#line 4156 "grammar.c" break; case 118: /* integer_set: range */ -#line 2083 "grammar.y" +#line 2104 "grammar.y" { fail_if_error(yr_parser_emit( yyscanner, OP_ITER_START_INT_RANGE, NULL)); } -#line 4148 "grammar.c" +#line 4165 "grammar.c" break; case 119: /* range: '(' primary_expression ".." primary_expression ')' */ -#line 2092 "grammar.y" +#line 2113 "grammar.y" { int result = ERROR_SUCCESS; @@ -4166,13 +4183,25 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); result = ERROR_WRONG_TYPE; } + // If we can statically determine lower and upper bounds, ensure + // lower < upper. Check for upper bound here because some things (like + // string count) are EXPRESSION_TYPE_INTEGER. + if ((yyvsp[-3].expression).value.integer != YR_UNDEFINED && + (yyvsp[-1].expression).value.integer != YR_UNDEFINED && + (yyvsp[-3].expression).value.integer > (yyvsp[-1].expression).value.integer) + { + yr_compiler_set_error_extra_info( + compiler, "range lower bound must be greater than upper bound"); + result = ERROR_INVALID_VALUE; + } + fail_if_error(result); } -#line 4172 "grammar.c" +#line 4201 "grammar.c" break; case 120: /* integer_enumeration: primary_expression */ -#line 2116 "grammar.y" +#line 2149 "grammar.y" { int result = ERROR_SUCCESS; @@ -4187,11 +4216,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.integer) = 1; } -#line 4191 "grammar.c" +#line 4220 "grammar.c" break; case 121: /* integer_enumeration: integer_enumeration ',' primary_expression */ -#line 2131 "grammar.y" +#line 2164 "grammar.y" { int result = ERROR_SUCCESS; @@ -4206,38 +4235,38 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.integer) = (yyvsp[-2].integer) + 1; } -#line 4210 "grammar.c" +#line 4239 "grammar.c" break; case 122: /* string_iterator: string_set */ -#line 2150 "grammar.y" +#line 2183 "grammar.y" { fail_if_error(yr_parser_emit_push_const(yyscanner, (yyvsp[0].integer))); fail_if_error(yr_parser_emit(yyscanner, OP_ITER_START_STRING_SET, NULL)); } -#line 4220 "grammar.c" +#line 4249 "grammar.c" break; case 123: /* $@10: %empty */ -#line 2159 "grammar.y" +#line 2192 "grammar.y" { // Push end-of-list marker yr_parser_emit_push_const(yyscanner, YR_UNDEFINED); } -#line 4229 "grammar.c" +#line 4258 "grammar.c" break; case 124: /* string_set: '(' $@10 string_enumeration ')' */ -#line 2164 "grammar.y" +#line 2197 "grammar.y" { (yyval.integer) = (yyvsp[-1].integer); } -#line 4237 "grammar.c" +#line 4266 "grammar.c" break; case 125: /* string_set: "" */ -#line 2168 "grammar.y" +#line 2201 "grammar.y" { fail_if_error(yr_parser_emit_push_const(yyscanner, YR_UNDEFINED)); @@ -4247,23 +4276,23 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.integer) = count; } -#line 4251 "grammar.c" +#line 4280 "grammar.c" break; case 126: /* string_enumeration: string_enumeration_item */ -#line 2181 "grammar.y" +#line 2214 "grammar.y" { (yyval.integer) = (yyvsp[0].integer); } -#line 4257 "grammar.c" +#line 4286 "grammar.c" break; case 127: /* string_enumeration: string_enumeration ',' string_enumeration_item */ -#line 2182 "grammar.y" +#line 2215 "grammar.y" { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } -#line 4263 "grammar.c" +#line 4292 "grammar.c" break; case 128: /* string_enumeration_item: "string identifier" */ -#line 2188 "grammar.y" +#line 2221 "grammar.y" { int count = 0; int result = yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string), &count); @@ -4273,11 +4302,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.integer) = count; } -#line 4277 "grammar.c" +#line 4306 "grammar.c" break; case 129: /* string_enumeration_item: "string identifier with wildcard" */ -#line 2198 "grammar.y" +#line 2231 "grammar.y" { int count = 0; int result = yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string), &count); @@ -4287,20 +4316,40 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.integer) = count; } -#line 4291 "grammar.c" +#line 4320 "grammar.c" break; case 130: /* $@11: %empty */ -#line 2212 "grammar.y" +#line 2245 "grammar.y" { // Push end-of-list marker yr_parser_emit_push_const(yyscanner, YR_UNDEFINED); } -#line 4300 "grammar.c" +#line 4329 "grammar.c" + break; + + case 131: /* rule_set: '(' $@11 rule_enumeration ')' */ +#line 2250 "grammar.y" + { + (yyval.integer) = (yyvsp[-1].integer); + } +#line 4337 "grammar.c" + break; + + case 132: /* rule_enumeration: rule_enumeration_item */ +#line 2257 "grammar.y" + { (yyval.integer) = (yyvsp[0].integer); } +#line 4343 "grammar.c" + break; + + case 133: /* rule_enumeration: rule_enumeration ',' rule_enumeration_item */ +#line 2258 "grammar.y" + { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } +#line 4349 "grammar.c" break; case 134: /* rule_enumeration_item: "identifier" */ -#line 2228 "grammar.y" +#line 2264 "grammar.y" { int result = ERROR_SUCCESS; @@ -4330,13 +4379,16 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yr_free((yyvsp[0].c_string)); fail_if_error(result); + + (yyval.integer) = 1; } -#line 4335 "grammar.c" +#line 4386 "grammar.c" break; case 135: /* rule_enumeration_item: "identifier" '*' */ -#line 2259 "grammar.y" +#line 2297 "grammar.y" { + int count = 0; YR_NAMESPACE* ns = (YR_NAMESPACE*) yr_arena_get_ptr( compiler->arena, YR_NAMESPACES_TABLE, @@ -4348,93 +4400,113 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); ns->name, 1); - int result = yr_parser_emit_pushes_for_rules(yyscanner, (yyvsp[-1].c_string)); + int result = yr_parser_emit_pushes_for_rules(yyscanner, (yyvsp[-1].c_string), &count); yr_free((yyvsp[-1].c_string)); fail_if_error(result); + + (yyval.integer) = count; } -#line 4357 "grammar.c" +#line 4411 "grammar.c" break; case 136: /* for_expression: primary_expression */ -#line 2281 "grammar.y" +#line 2322 "grammar.y" { - if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER) { - if ((yyvsp[0].expression).value.integer == 0) { + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER) + { + if ((yyvsp[0].expression).value.integer == 0) + { yywarning(yyscanner, - "Consider using \"none\" keyword, it is less ambiguous. Please " - "see https://yara.readthedocs.io/en/stable/writingrules.html#sets-of-strings-1 for an explanation."); + "consider using \"none\" keyword, it is less ambiguous."); } - if ((yyvsp[0].expression).value.integer < 0) { + if ((yyvsp[0].expression).value.integer < 0) + { yr_compiler_set_error_extra_info_fmt(compiler, "%lld", (yyvsp[0].expression).value.integer); fail_with_error(ERROR_INVALID_VALUE); } } - if ((yyvsp[0].expression).type == EXPRESSION_TYPE_STRING) { + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_STRING) + { SIZED_STRING* ss = yr_arena_ref_to_ptr(compiler->arena, &(yyvsp[0].expression).value.sized_string_ref); // If the expression is an external string variable we need to get // it some other way. - if (ss != NULL) { + if (ss != NULL) + { yr_compiler_set_error_extra_info_fmt(compiler, "%s", ss->c_string); - } else { + } + else + { yr_compiler_set_error_extra_info(compiler, "string in for_expression is invalid"); } fail_with_error(ERROR_INVALID_VALUE); } - if ((yyvsp[0].expression).type == EXPRESSION_TYPE_REGEXP) { + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_REGEXP) + { yr_compiler_set_error_extra_info(compiler, "regexp in for_expression is invalid"); fail_with_error(ERROR_INVALID_VALUE); } - (yyval.integer) = FOR_EXPRESSION_ANY; + (yyval.expression).value.integer = (yyvsp[0].expression).value.integer; } -#line 4399 "grammar.c" +#line 4460 "grammar.c" break; - case 137: /* for_expression: "" */ -#line 2319 "grammar.y" + case 137: /* for_expression: for_quantifier */ +#line 2367 "grammar.y" { - yr_parser_emit_push_const(yyscanner, YR_UNDEFINED); - (yyval.integer) = FOR_EXPRESSION_ALL; + (yyval.expression).value.integer = (yyvsp[0].expression).value.integer; } -#line 4408 "grammar.c" +#line 4468 "grammar.c" + break; + + case 138: /* for_quantifier: "" */ +#line 2374 "grammar.y" + { + yr_parser_emit_push_const(yyscanner, YR_UNDEFINED); + (yyval.expression).type = EXPRESSION_TYPE_QUANTIFIER; + (yyval.expression).value.integer = FOR_EXPRESSION_ALL; + } +#line 4478 "grammar.c" break; - case 138: /* for_expression: "" */ -#line 2324 "grammar.y" + case 139: /* for_quantifier: "" */ +#line 2380 "grammar.y" { yr_parser_emit_push_const(yyscanner, 1); - (yyval.integer) = FOR_EXPRESSION_ANY; + (yyval.expression).type = EXPRESSION_TYPE_QUANTIFIER; + (yyval.expression).value.integer = FOR_EXPRESSION_ANY; } -#line 4417 "grammar.c" +#line 4488 "grammar.c" break; - case 139: /* for_expression: "" */ -#line 2329 "grammar.y" + case 140: /* for_quantifier: "" */ +#line 2386 "grammar.y" { yr_parser_emit_push_const(yyscanner, 0); - (yyval.integer) = FOR_EXPRESSION_NONE; + (yyval.expression).type = EXPRESSION_TYPE_QUANTIFIER; + (yyval.expression).value.integer = FOR_EXPRESSION_NONE; } -#line 4426 "grammar.c" +#line 4498 "grammar.c" break; - case 140: /* primary_expression: '(' primary_expression ')' */ -#line 2338 "grammar.y" + case 141: /* primary_expression: '(' primary_expression ')' */ +#line 2396 "grammar.y" { (yyval.expression) = (yyvsp[-1].expression); } -#line 4434 "grammar.c" +#line 4506 "grammar.c" break; - case 141: /* primary_expression: "" */ -#line 2342 "grammar.y" + case 142: /* primary_expression: "" */ +#line 2400 "grammar.y" { fail_if_error(yr_parser_emit( yyscanner, OP_FILESIZE, NULL)); @@ -4442,11 +4514,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4446 "grammar.c" +#line 4518 "grammar.c" break; - case 142: /* primary_expression: "" */ -#line 2350 "grammar.y" + case 143: /* primary_expression: "" */ +#line 2408 "grammar.y" { yywarning(yyscanner, "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " @@ -4458,11 +4530,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4462 "grammar.c" +#line 4534 "grammar.c" break; - case 143: /* primary_expression: "integer function" '(' primary_expression ')' */ -#line 2362 "grammar.y" + case 144: /* primary_expression: "integer function" '(' primary_expression ')' */ +#line 2420 "grammar.y" { check_type((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX"); @@ -4476,33 +4548,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4480 "grammar.c" +#line 4552 "grammar.c" break; - case 144: /* primary_expression: "integer number" */ -#line 2376 "grammar.y" + case 145: /* primary_expression: "integer number" */ +#line 2434 "grammar.y" { fail_if_error(yr_parser_emit_push_const(yyscanner, (yyvsp[0].integer))); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = (yyvsp[0].integer); } -#line 4491 "grammar.c" +#line 4563 "grammar.c" break; - case 145: /* primary_expression: "floating point number" */ -#line 2383 "grammar.y" + case 146: /* primary_expression: "floating point number" */ +#line 2441 "grammar.y" { fail_if_error(yr_parser_emit_with_arg_double( yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL)); (yyval.expression).type = EXPRESSION_TYPE_FLOAT; } -#line 4502 "grammar.c" +#line 4574 "grammar.c" break; - case 146: /* primary_expression: "text string" */ -#line 2390 "grammar.y" + case 147: /* primary_expression: "text string" */ +#line 2448 "grammar.y" { YR_ARENA_REF ref; @@ -4527,11 +4599,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_STRING; (yyval.expression).value.sized_string_ref = ref; } -#line 4531 "grammar.c" +#line 4603 "grammar.c" break; - case 147: /* primary_expression: "string count" "" range */ -#line 2415 "grammar.y" + case 148: /* primary_expression: "string count" "" range */ +#line 2473 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[-2].c_string), OP_COUNT_IN, YR_UNDEFINED); @@ -4543,11 +4615,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4547 "grammar.c" +#line 4619 "grammar.c" break; - case 148: /* primary_expression: "string count" */ -#line 2427 "grammar.y" + case 149: /* primary_expression: "string count" */ +#line 2485 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[0].c_string), OP_COUNT, YR_UNDEFINED); @@ -4559,11 +4631,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4563 "grammar.c" +#line 4635 "grammar.c" break; - case 149: /* primary_expression: "string offset" '[' primary_expression ']' */ -#line 2439 "grammar.y" + case 150: /* primary_expression: "string offset" '[' primary_expression ']' */ +#line 2497 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[-3].c_string), OP_OFFSET, YR_UNDEFINED); @@ -4575,11 +4647,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4579 "grammar.c" +#line 4651 "grammar.c" break; - case 150: /* primary_expression: "string offset" */ -#line 2451 "grammar.y" + case 151: /* primary_expression: "string offset" */ +#line 2509 "grammar.y" { int result = yr_parser_emit_push_const(yyscanner, 1); @@ -4594,11 +4666,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4598 "grammar.c" +#line 4670 "grammar.c" break; - case 151: /* primary_expression: "string length" '[' primary_expression ']' */ -#line 2466 "grammar.y" + case 152: /* primary_expression: "string length" '[' primary_expression ']' */ +#line 2524 "grammar.y" { int result = yr_parser_reduce_string_identifier( yyscanner, (yyvsp[-3].c_string), OP_LENGTH, YR_UNDEFINED); @@ -4610,11 +4682,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4614 "grammar.c" +#line 4686 "grammar.c" break; - case 152: /* primary_expression: "string length" */ -#line 2478 "grammar.y" + case 153: /* primary_expression: "string length" */ +#line 2536 "grammar.y" { int result = yr_parser_emit_push_const(yyscanner, 1); @@ -4629,11 +4701,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = YR_UNDEFINED; } -#line 4633 "grammar.c" +#line 4705 "grammar.c" break; - case 153: /* primary_expression: identifier */ -#line 2493 "grammar.y" + case 154: /* primary_expression: identifier */ +#line 2551 "grammar.y" { int result = ERROR_SUCCESS; @@ -4676,11 +4748,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4680 "grammar.c" +#line 4752 "grammar.c" break; - case 154: /* primary_expression: '-' primary_expression */ -#line 2536 "grammar.y" + case 155: /* primary_expression: '-' primary_expression */ +#line 2594 "grammar.y" { int result = ERROR_SUCCESS; @@ -4701,11 +4773,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4705 "grammar.c" +#line 4777 "grammar.c" break; - case 155: /* primary_expression: primary_expression '+' primary_expression */ -#line 2557 "grammar.y" + case 156: /* primary_expression: primary_expression '+' primary_expression */ +#line 2615 "grammar.y" { int result = yr_parser_reduce_operation( yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression)); @@ -4740,11 +4812,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4744 "grammar.c" +#line 4816 "grammar.c" break; - case 156: /* primary_expression: primary_expression '-' primary_expression */ -#line 2592 "grammar.y" + case 157: /* primary_expression: primary_expression '-' primary_expression */ +#line 2650 "grammar.y" { int result = yr_parser_reduce_operation( yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression)); @@ -4779,11 +4851,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4783 "grammar.c" +#line 4855 "grammar.c" break; - case 157: /* primary_expression: primary_expression '*' primary_expression */ -#line 2627 "grammar.y" + case 158: /* primary_expression: primary_expression '*' primary_expression */ +#line 2685 "grammar.y" { int result = yr_parser_reduce_operation( yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression)); @@ -4817,11 +4889,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4821 "grammar.c" +#line 4893 "grammar.c" break; - case 158: /* primary_expression: primary_expression '\\' primary_expression */ -#line 2661 "grammar.y" + case 159: /* primary_expression: primary_expression '\\' primary_expression */ +#line 2719 "grammar.y" { int result = yr_parser_reduce_operation( yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression)); @@ -4846,11 +4918,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4850 "grammar.c" +#line 4922 "grammar.c" break; - case 159: /* primary_expression: primary_expression '%' primary_expression */ -#line 2686 "grammar.y" + case 160: /* primary_expression: primary_expression '%' primary_expression */ +#line 2744 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%"); @@ -4867,11 +4939,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(ERROR_DIVISION_BY_ZERO); } } -#line 4871 "grammar.c" +#line 4943 "grammar.c" break; - case 160: /* primary_expression: primary_expression '^' primary_expression */ -#line 2703 "grammar.y" + case 161: /* primary_expression: primary_expression '^' primary_expression */ +#line 2761 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); @@ -4881,11 +4953,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); } -#line 4885 "grammar.c" +#line 4957 "grammar.c" break; - case 161: /* primary_expression: primary_expression '&' primary_expression */ -#line 2713 "grammar.y" + case 162: /* primary_expression: primary_expression '&' primary_expression */ +#line 2771 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); @@ -4895,11 +4967,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); } -#line 4899 "grammar.c" +#line 4971 "grammar.c" break; - case 162: /* primary_expression: primary_expression '|' primary_expression */ -#line 2723 "grammar.y" + case 163: /* primary_expression: primary_expression '|' primary_expression */ +#line 2781 "grammar.y" { check_type((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|"); check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|"); @@ -4909,11 +4981,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).type = EXPRESSION_TYPE_INTEGER; (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); } -#line 4913 "grammar.c" +#line 4985 "grammar.c" break; - case 163: /* primary_expression: '~' primary_expression */ -#line 2733 "grammar.y" + case 164: /* primary_expression: '~' primary_expression */ +#line 2791 "grammar.y" { check_type((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~"); @@ -4923,11 +4995,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == YR_UNDEFINED) ? YR_UNDEFINED : ~((yyvsp[0].expression).value.integer); } -#line 4927 "grammar.c" +#line 4999 "grammar.c" break; - case 164: /* primary_expression: primary_expression "<<" primary_expression */ -#line 2743 "grammar.y" + case 165: /* primary_expression: primary_expression "<<" primary_expression */ +#line 2801 "grammar.y" { int result; @@ -4947,11 +5019,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4951 "grammar.c" +#line 5023 "grammar.c" break; - case 165: /* primary_expression: primary_expression ">>" primary_expression */ -#line 2763 "grammar.y" + case 166: /* primary_expression: primary_expression ">>" primary_expression */ +#line 2821 "grammar.y" { int result; @@ -4971,19 +5043,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); fail_if_error(result); } -#line 4975 "grammar.c" +#line 5047 "grammar.c" break; - case 166: /* primary_expression: regexp */ -#line 2783 "grammar.y" + case 167: /* primary_expression: regexp */ +#line 2841 "grammar.y" { (yyval.expression) = (yyvsp[0].expression); } -#line 4983 "grammar.c" +#line 5055 "grammar.c" break; -#line 4987 "grammar.c" +#line 5059 "grammar.c" default: break; } @@ -5207,5 +5279,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); return yyresult; } -#line 2788 "grammar.y" +#line 2846 "grammar.y" diff --git a/libyara/grammar.h b/libyara/grammar.h index 9a01192a15..34512a1203 100644 --- a/libyara/grammar.h +++ b/libyara/grammar.h @@ -189,7 +189,7 @@ extern int yara_yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 336 "grammar.y" +#line 341 "grammar.y" YR_EXPRESSION expression; SIZED_STRING* sized_string; diff --git a/libyara/grammar.y b/libyara/grammar.y index c3dc3821f8..e8e0a33cfc 100644 --- a/libyara/grammar.y +++ b/libyara/grammar.y @@ -286,19 +286,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %type integer_set %type integer_enumeration -%type for_expression %type rule_modifier %type rule_modifiers %type string_enumeration %type string_enumeration_item %type string_set %type for_iteration +%type rule_enumeration +%type rule_enumeration_item +%type rule_set %type primary_expression %type boolean_expression %type expression %type identifier %type regexp +%type for_expression +%type for_quantifier + %type arguments %type arguments_list @@ -1687,12 +1692,22 @@ expression } | for_expression _OF_ string_set { + if ($1.type == EXPRESSION_TYPE_INTEGER && $1.value.integer > $3) + { + yywarning(yyscanner, + "expression always false - requesting %lld of %lld.", $1.value.integer, $3); + } yr_parser_emit_with_arg(yyscanner, OP_OF, OF_STRING_SET, NULL, NULL); $$.type = EXPRESSION_TYPE_BOOLEAN; } | for_expression _OF_ rule_set { + if ($1.type == EXPRESSION_TYPE_INTEGER && $1.value.integer > $3) + { + yywarning(yyscanner, + "expression always false - requesting %lld of %lld.", $1.value.integer, $3); + } yr_parser_emit_with_arg(yyscanner, OP_OF, OF_RULE_SET, NULL, NULL); $$.type = EXPRESSION_TYPE_BOOLEAN; @@ -1737,6 +1752,12 @@ expression } | for_expression _OF_ string_set _IN_ range { + if ($1.type == EXPRESSION_TYPE_INTEGER && $1.value.integer > $3) + { + yywarning(yyscanner, + "expression always false - requesting %lld of %lld.", $1.value.integer, $3); + } + yr_parser_emit(yyscanner, OP_OF_FOUND_IN, NULL); $$.type = EXPRESSION_TYPE_BOOLEAN; @@ -2106,6 +2127,18 @@ range result = ERROR_WRONG_TYPE; } + // If we can statically determine lower and upper bounds, ensure + // lower < upper. Check for upper bound here because some things (like + // string count) are EXPRESSION_TYPE_INTEGER. + if ($2.value.integer != YR_UNDEFINED && + $4.value.integer != YR_UNDEFINED && + $2.value.integer > $4.value.integer) + { + yr_compiler_set_error_extra_info( + compiler, "range lower bound must be greater than upper bound"); + result = ERROR_INVALID_VALUE; + } + fail_if_error(result); } ; @@ -2214,12 +2247,15 @@ rule_set yr_parser_emit_push_const(yyscanner, YR_UNDEFINED); } rule_enumeration ')' + { + $$ = $3; + } ; rule_enumeration - : rule_enumeration_item - | rule_enumeration ',' rule_enumeration_item + : rule_enumeration_item { $$ = $1; } + | rule_enumeration ',' rule_enumeration_item { $$ = $1 + $3; } ; @@ -2254,9 +2290,12 @@ rule_enumeration_item yr_free($1); fail_if_error(result); + + $$ = 1; } | _IDENTIFIER_ '*' { + int count = 0; YR_NAMESPACE* ns = (YR_NAMESPACE*) yr_arena_get_ptr( compiler->arena, YR_NAMESPACES_TABLE, @@ -2268,10 +2307,12 @@ rule_enumeration_item ns->name, 1); - int result = yr_parser_emit_pushes_for_rules(yyscanner, $1); + int result = yr_parser_emit_pushes_for_rules(yyscanner, $1, &count); yr_free($1); fail_if_error(result); + + $$ = count; } ; @@ -2279,56 +2320,73 @@ rule_enumeration_item for_expression : primary_expression { - if ($1.type == EXPRESSION_TYPE_INTEGER) { - if ($1.value.integer == 0) { + if ($1.type == EXPRESSION_TYPE_INTEGER) + { + if ($1.value.integer == 0) + { yywarning(yyscanner, - "Consider using \"none\" keyword, it is less ambiguous. Please " - "see https://yara.readthedocs.io/en/stable/writingrules.html#sets-of-strings-1 for an explanation."); + "consider using \"none\" keyword, it is less ambiguous."); } - if ($1.value.integer < 0) { + if ($1.value.integer < 0) + { yr_compiler_set_error_extra_info_fmt(compiler, "%lld", $1.value.integer); fail_with_error(ERROR_INVALID_VALUE); } } - if ($1.type == EXPRESSION_TYPE_STRING) { + if ($1.type == EXPRESSION_TYPE_STRING) + { SIZED_STRING* ss = yr_arena_ref_to_ptr(compiler->arena, &$1.value.sized_string_ref); // If the expression is an external string variable we need to get // it some other way. - if (ss != NULL) { + if (ss != NULL) + { yr_compiler_set_error_extra_info_fmt(compiler, "%s", ss->c_string); - } else { + } + else + { yr_compiler_set_error_extra_info(compiler, "string in for_expression is invalid"); } fail_with_error(ERROR_INVALID_VALUE); } - if ($1.type == EXPRESSION_TYPE_REGEXP) { + if ($1.type == EXPRESSION_TYPE_REGEXP) + { yr_compiler_set_error_extra_info(compiler, "regexp in for_expression is invalid"); fail_with_error(ERROR_INVALID_VALUE); } - $$ = FOR_EXPRESSION_ANY; + $$.value.integer = $1.value.integer; } - | _ALL_ + | for_quantifier { - yr_parser_emit_push_const(yyscanner, YR_UNDEFINED); - $$ = FOR_EXPRESSION_ALL; + $$.value.integer = $1.value.integer; } + ; + +for_quantifier + : _ALL_ + { + yr_parser_emit_push_const(yyscanner, YR_UNDEFINED); + $$.type = EXPRESSION_TYPE_QUANTIFIER; + $$.value.integer = FOR_EXPRESSION_ALL; + } | _ANY_ { yr_parser_emit_push_const(yyscanner, 1); - $$ = FOR_EXPRESSION_ANY; + $$.type = EXPRESSION_TYPE_QUANTIFIER; + $$.value.integer = FOR_EXPRESSION_ANY; } | _NONE_ { yr_parser_emit_push_const(yyscanner, 0); - $$ = FOR_EXPRESSION_NONE; + $$.type = EXPRESSION_TYPE_QUANTIFIER; + $$.value.integer = FOR_EXPRESSION_NONE; } ; diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h index b86a39aa07..15b9e6b7e7 100644 --- a/libyara/include/yara/compiler.h +++ b/libyara/include/yara/compiler.h @@ -42,13 +42,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define YARA_ERROR_LEVEL_WARNING 1 // Expression type constants are powers of two because they are used as flags. -#define EXPRESSION_TYPE_UNKNOWN 0 -#define EXPRESSION_TYPE_BOOLEAN 1 -#define EXPRESSION_TYPE_INTEGER 2 -#define EXPRESSION_TYPE_STRING 4 -#define EXPRESSION_TYPE_REGEXP 8 -#define EXPRESSION_TYPE_OBJECT 16 -#define EXPRESSION_TYPE_FLOAT 32 +#define EXPRESSION_TYPE_UNKNOWN 0 +#define EXPRESSION_TYPE_BOOLEAN 1 +#define EXPRESSION_TYPE_INTEGER 2 +#define EXPRESSION_TYPE_STRING 4 +#define EXPRESSION_TYPE_REGEXP 8 +#define EXPRESSION_TYPE_OBJECT 16 +#define EXPRESSION_TYPE_FLOAT 32 +#define EXPRESSION_TYPE_QUANTIFIER 64 // The compiler uses an arena to store the data it generates during the // compilation. Each buffer in the arena is used for storing a different type diff --git a/libyara/include/yara/parser.h b/libyara/include/yara/parser.h index d6e78e572f..437e64259d 100644 --- a/libyara/include/yara/parser.h +++ b/libyara/include/yara/parser.h @@ -120,7 +120,8 @@ int yr_parser_emit_pushes_for_strings( int yr_parser_emit_pushes_for_rules( yyscan_t yyscanner, - const char* identifier); + const char* identifier, + int *count); int yr_parser_reduce_external( yyscan_t yyscanner, diff --git a/libyara/parser.c b/libyara/parser.c index 09bb420c4a..31b0c5f259 100644 --- a/libyara/parser.c +++ b/libyara/parser.c @@ -237,7 +237,10 @@ int yr_parser_emit_pushes_for_strings( // Emit OP_PUSH_RULE instructions for all rules whose identifier has given // prefix. -int yr_parser_emit_pushes_for_rules(yyscan_t yyscanner, const char* prefix) +int yr_parser_emit_pushes_for_rules( + yyscan_t yyscanner, + const char* prefix, + int* count) { YR_COMPILER* compiler = yyget_extra(yyscanner); @@ -284,6 +287,11 @@ int yr_parser_emit_pushes_for_rules(yyscan_t yyscanner, const char* prefix) rule++; } + if (count != NULL) + { + *count = matching; + } + if (matching == 0) { yr_compiler_set_error_extra_info(compiler, prefix); diff --git a/tests/test-rules.c b/tests/test-rules.c index 37a1cb1466..45d5aef4f8 100644 --- a/tests/test-rules.c +++ b/tests/test-rules.c @@ -536,7 +536,7 @@ static void test_warnings() { assert_warning("rule test { \ strings: \ $a = \"AXSERS\" \ - condition: \ + condition: \ for 0 of ($a*): ($) \ }"); @@ -550,17 +550,62 @@ static void test_warnings() { assert_no_warnings("rule test { \ strings: \ $a = \"AXSERS\" \ - condition: \ + condition: \ for none of ($a*): ($) \ }"); assert_warning("rule test { \ strings: \ $a = \"AXSERS\" \ - condition: \ + condition: \ 1 + -1 of them \ }"); + assert_warning("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + 2 of them \ + }"); + + assert_warning("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + 2 of ($a) \ + }"); + + assert_warning("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + 2 of ($a*) \ + }"); + + assert_warning("rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + 2 of ($a*) in (0..10) \ + }"); + + assert_warning("rule a { \ + condition: \ + true \ + } \ + rule b { \ + condition: \ + 2 of (a) \ + }"); + + assert_warning("rule a { \ + condition: \ + true \ + } \ + rule b { \ + condition: \ + 2 of (a*) \ + }"); YR_DEBUG_FPRINTF(1, stderr, "} // %s()\n", __FUNCTION__); } @@ -2119,6 +2164,24 @@ void test_for() }", NULL); + // Lower bound must be less than upper bound, if it can be determined statically. + assert_error( + "import \"tests\" \ + rule test { \ + condition: \ + for any i in (10..1): (i) \ + }", + ERROR_INVALID_VALUE); + + // If one of the bounds can not be determined statically it isn't an error. + assert_true_rule( + "rule test { \ + strings: \ + $a = \"AXSERS\" \ + condition: \ + true or any of them in (0..filesize-100) \ + }", TEXT_1024_BYTES); + YR_DEBUG_FPRINTF(1, stderr, "} // %s()\n", __FUNCTION__); }