[Forensics-changes] [yara] 17/407: Improve scanning speed by matching certain strings only at fixed offsets
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:27:59 UTC 2017
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag v3.3.0
in repository yara.
commit a5a8b51c99a8178f9c1454ec6f48e97f40d41098
Author: Victor Manuel Alvarez <vmalvarez at virustotal.com>
Date: Tue Sep 2 12:50:05 2014 +0200
Improve scanning speed by matching certain strings only at fixed offsets
---
libyara/exec.c | 36 ++-
libyara/grammar.c | 540 ++++++++++++++++++++++--------------------
libyara/grammar.h | 4 +-
libyara/grammar.y | 196 ++++++++-------
libyara/include/yara/exec.h | 8 +
libyara/include/yara/lexer.h | 23 +-
libyara/include/yara/parser.h | 3 +-
libyara/include/yara/types.h | 6 +
libyara/parser.c | 70 +++++-
libyara/scan.c | 4 +
10 files changed, 515 insertions(+), 375 deletions(-)
diff --git a/libyara/exec.c b/libyara/exec.c
index 88f5c19..d7f3344 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -43,14 +43,6 @@ limitations under the License.
#define pop(x) x = stack[--sp]
-#define operation(operator, op1, op2) \
- (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (UNDEFINED) : (op1 operator op2)
-
-
-#define comparison(operator, op1, op2) \
- (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (0) : (op1 operator op2)
-
-
#define function_read(type) \
int64_t read_##type(YR_MEMORY_BLOCK* block, size_t offset) \
{ \
@@ -237,37 +229,37 @@ int yr_execute_code(
case OP_LT:
pop(r2);
pop(r1);
- push(comparison(<, r1, r2));
+ push(COMPARISON(<, r1, r2));
break;
case OP_GT:
pop(r2);
pop(r1);
- push(comparison(>, r1, r2));
+ push(COMPARISON(>, r1, r2));
break;
case OP_LE:
pop(r2);
pop(r1);
- push(comparison(<=, r1, r2));
+ push(COMPARISON(<=, r1, r2));
break;
case OP_GE:
pop(r2);
pop(r1);
- push(comparison(>=, r1, r2));
+ push(COMPARISON(>=, r1, r2));
break;
case OP_EQ:
pop(r2);
pop(r1);
- push(comparison(==, r1, r2));
+ push(COMPARISON(==, r1, r2));
break;
case OP_NEQ:
pop(r2);
pop(r1);
- push(comparison(!=, r1, r2));
+ push(COMPARISON(!=, r1, r2));
break;
case OP_SZ_EQ:
@@ -305,31 +297,31 @@ int yr_execute_code(
case OP_ADD:
pop(r2);
pop(r1);
- push(operation(+, r1, r2));
+ push(OPERATION(+, r1, r2));
break;
case OP_SUB:
pop(r2);
pop(r1);
- push(operation(-, r1, r2));
+ push(OPERATION(-, r1, r2));
break;
case OP_MUL:
pop(r2);
pop(r1);
- push(operation(*, r1, r2));
+ push(OPERATION(*, r1, r2));
break;
case OP_DIV:
pop(r2);
pop(r1);
- push(operation(/, r1, r2));
+ push(OPERATION(/, r1, r2));
break;
case OP_MOD:
pop(r2);
pop(r1);
- push(operation(%, r1, r2));
+ push(OPERATION(%, r1, r2));
break;
case OP_NEG:
@@ -340,19 +332,19 @@ int yr_execute_code(
case OP_SHR:
pop(r2);
pop(r1);
- push(operation(>>, r1, r2));
+ push(OPERATION(>>, r1, r2));
break;
case OP_SHL:
pop(r2);
pop(r1);
- push(operation(<<, r1, r2));
+ push(OPERATION(<<, r1, r2));
break;
case OP_XOR:
pop(r2);
pop(r1);
- push(operation(^, r1, r2));
+ push(OPERATION(^, r1, r2));
break;
case OP_PUSH_RULE:
diff --git a/libyara/grammar.c b/libyara/grammar.c
index a2995f9..98f1105 100644
--- a/libyara/grammar.c
+++ b/libyara/grammar.c
@@ -226,10 +226,10 @@
} \
-#define CHECK_TYPE_WITH_CLEANUP(actual_type, expected_type, op, cleanup) \
- if (actual_type != expected_type) \
+#define CHECK_TYPE_WITH_CLEANUP(expression, expected_type, op, cleanup) \
+ if (expression.type != expected_type) \
{ \
- switch(actual_type) \
+ switch(expression.type) \
{ \
case EXPRESSION_TYPE_INTEGER: \
yr_compiler_set_error_extra_info( \
@@ -246,8 +246,9 @@
YYERROR; \
}
-#define CHECK_TYPE(actual_type, expected_type, op) \
- CHECK_TYPE_WITH_CLEANUP(actual_type, expected_type, op, ) \
+
+#define CHECK_TYPE(expression, expected_type, op) \
+ CHECK_TYPE_WITH_CLEANUP(expression, expected_type, op, ) \
#define MSG(op) "wrong type \"string\" for \"" op "\" operator"
@@ -274,18 +275,18 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 186 "grammar.y"
+#line 187 "grammar.y"
{
+ EXPRESSION expression;
SIZED_STRING* sized_string;
char* c_string;
- int8_t expression_type;
int64_t integer;
YR_STRING* string;
YR_META* meta;
YR_OBJECT* object;
}
/* Line 193 of yacc.c. */
-#line 289 "grammar.c"
+#line 290 "grammar.c"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -298,7 +299,7 @@ typedef union YYSTYPE
/* Line 216 of yacc.c. */
-#line 302 "grammar.c"
+#line 303 "grammar.c"
#ifdef short
# undef short
@@ -632,18 +633,18 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 199, 199, 201, 202, 203, 204, 209, 221, 240,
- 243, 271, 275, 303, 308, 309, 314, 315, 321, 324,
- 342, 355, 392, 393, 398, 414, 427, 440, 457, 458,
- 463, 477, 476, 493, 510, 511, 516, 517, 518, 519,
- 524, 612, 661, 684, 724, 727, 749, 782, 827, 845,
- 854, 863, 878, 892, 905, 920, 934, 969, 933, 1080,
- 1079, 1156, 1162, 1168, 1174, 1182, 1191, 1200, 1209, 1218,
- 1245, 1272, 1299, 1303, 1311, 1312, 1317, 1339, 1351, 1367,
- 1366, 1372, 1381, 1382, 1387, 1392, 1401, 1402, 1406, 1414,
- 1418, 1427, 1439, 1450, 1461, 1472, 1483, 1494, 1505, 1514,
- 1537, 1550, 1563, 1583, 1618, 1627, 1636, 1645, 1654, 1663,
- 1672, 1681, 1690, 1698, 1707, 1716
+ 0, 200, 200, 202, 203, 204, 205, 210, 222, 241,
+ 244, 272, 276, 304, 309, 310, 315, 316, 322, 325,
+ 343, 356, 393, 394, 399, 415, 428, 441, 458, 459,
+ 464, 478, 477, 494, 511, 512, 517, 518, 519, 520,
+ 525, 613, 662, 685, 725, 728, 750, 783, 828, 845,
+ 854, 863, 878, 892, 906, 922, 937, 972, 936, 1083,
+ 1082, 1159, 1165, 1171, 1177, 1185, 1194, 1203, 1212, 1221,
+ 1248, 1275, 1302, 1306, 1314, 1315, 1320, 1342, 1354, 1370,
+ 1369, 1375, 1384, 1385, 1390, 1395, 1404, 1405, 1409, 1417,
+ 1421, 1431, 1444, 1456, 1468, 1480, 1492, 1504, 1516, 1526,
+ 1549, 1564, 1579, 1601, 1638, 1648, 1658, 1668, 1678, 1688,
+ 1698, 1708, 1718, 1728, 1738, 1748
};
#endif
@@ -1448,44 +1449,44 @@ yydestruct (yymsg, yytype, yyvaluep, yyscanner, compiler)
switch (yytype)
{
case 9: /* "_IDENTIFIER_" */
-#line 177 "grammar.y"
+#line 178 "grammar.y"
{ yr_free((yyvaluep->c_string)); };
-#line 1454 "grammar.c"
+#line 1455 "grammar.c"
break;
case 10: /* "_STRING_IDENTIFIER_" */
-#line 178 "grammar.y"
+#line 179 "grammar.y"
{ yr_free((yyvaluep->c_string)); };
-#line 1459 "grammar.c"
+#line 1460 "grammar.c"
break;
case 11: /* "_STRING_COUNT_" */
-#line 179 "grammar.y"
+#line 180 "grammar.y"
{ yr_free((yyvaluep->c_string)); };
-#line 1464 "grammar.c"
+#line 1465 "grammar.c"
break;
case 12: /* "_STRING_OFFSET_" */
-#line 180 "grammar.y"
+#line 181 "grammar.y"
{ yr_free((yyvaluep->c_string)); };
-#line 1469 "grammar.c"
+#line 1470 "grammar.c"
break;
case 13: /* "_STRING_IDENTIFIER_WITH_WILDCARD_" */
-#line 181 "grammar.y"
+#line 182 "grammar.y"
{ yr_free((yyvaluep->c_string)); };
-#line 1474 "grammar.c"
+#line 1475 "grammar.c"
break;
case 15: /* "_TEXT_STRING_" */
-#line 182 "grammar.y"
+#line 183 "grammar.y"
{ yr_free((yyvaluep->sized_string)); };
-#line 1479 "grammar.c"
+#line 1480 "grammar.c"
break;
case 16: /* "_HEX_STRING_" */
-#line 183 "grammar.y"
+#line 184 "grammar.y"
{ yr_free((yyvaluep->sized_string)); };
-#line 1484 "grammar.c"
+#line 1485 "grammar.c"
break;
case 17: /* "_REGEXP_" */
-#line 184 "grammar.y"
+#line 185 "grammar.y"
{ yr_free((yyvaluep->sized_string)); };
-#line 1489 "grammar.c"
+#line 1490 "grammar.c"
break;
default:
@@ -1795,7 +1796,7 @@ yyreduce:
switch (yyn)
{
case 7:
-#line 210 "grammar.y"
+#line 211 "grammar.y"
{
int result = yr_parser_reduce_import(yyscanner, (yyvsp[(2) - (2)].sized_string));
@@ -1806,7 +1807,7 @@ yyreduce:
break;
case 8:
-#line 222 "grammar.y"
+#line 223 "grammar.y"
{
int result = yr_parser_reduce_rule_declaration(
yyscanner,
@@ -1823,14 +1824,14 @@ yyreduce:
break;
case 9:
-#line 240 "grammar.y"
+#line 241 "grammar.y"
{
(yyval.meta) = NULL;
}
break;
case 10:
-#line 244 "grammar.y"
+#line 245 "grammar.y"
{
// Each rule have a list of meta-data info, consisting in a
// sequence of YR_META structures. The last YR_META structure does
@@ -1856,7 +1857,7 @@ yyreduce:
break;
case 11:
-#line 271 "grammar.y"
+#line 272 "grammar.y"
{
(yyval.string) = NULL;
compiler->current_rule_strings = (yyval.string);
@@ -1864,7 +1865,7 @@ yyreduce:
break;
case 12:
-#line 276 "grammar.y"
+#line 277 "grammar.y"
{
// Each rule have a list of strings, consisting in a sequence
// of YR_STRING structures. The last YR_STRING structure does not
@@ -1891,34 +1892,34 @@ yyreduce:
break;
case 14:
-#line 308 "grammar.y"
+#line 309 "grammar.y"
{ (yyval.integer) = 0; }
break;
case 15:
-#line 309 "grammar.y"
+#line 310 "grammar.y"
{ (yyval.integer) = (yyvsp[(1) - (2)].integer) | (yyvsp[(2) - (2)].integer); }
break;
case 16:
-#line 314 "grammar.y"
+#line 315 "grammar.y"
{ (yyval.integer) = RULE_GFLAGS_PRIVATE; }
break;
case 17:
-#line 315 "grammar.y"
+#line 316 "grammar.y"
{ (yyval.integer) = RULE_GFLAGS_GLOBAL; }
break;
case 18:
-#line 321 "grammar.y"
+#line 322 "grammar.y"
{
(yyval.c_string) = NULL;
}
break;
case 19:
-#line 325 "grammar.y"
+#line 326 "grammar.y"
{
// Tags list is represented in the arena as a sequence
// of null-terminated strings, the sequence ends with an
@@ -1935,7 +1936,7 @@ yyreduce:
break;
case 20:
-#line 343 "grammar.y"
+#line 344 "grammar.y"
{
char* identifier;
@@ -1951,7 +1952,7 @@ yyreduce:
break;
case 21:
-#line 356 "grammar.y"
+#line 357 "grammar.y"
{
char* tag_name = (yyvsp[(1) - (2)].c_string);
size_t tag_length = tag_name != NULL ? strlen(tag_name) : 0;
@@ -1986,17 +1987,17 @@ yyreduce:
break;
case 22:
-#line 392 "grammar.y"
+#line 393 "grammar.y"
{ (yyval.meta) = (yyvsp[(1) - (1)].meta); }
break;
case 23:
-#line 393 "grammar.y"
+#line 394 "grammar.y"
{ (yyval.meta) = (yyvsp[(1) - (2)].meta); }
break;
case 24:
-#line 399 "grammar.y"
+#line 400 "grammar.y"
{
SIZED_STRING* sized_string = (yyvsp[(3) - (3)].sized_string);
@@ -2015,7 +2016,7 @@ yyreduce:
break;
case 25:
-#line 415 "grammar.y"
+#line 416 "grammar.y"
{
(yyval.meta) = yr_parser_reduce_meta_declaration(
yyscanner,
@@ -2031,7 +2032,7 @@ yyreduce:
break;
case 26:
-#line 428 "grammar.y"
+#line 429 "grammar.y"
{
(yyval.meta) = yr_parser_reduce_meta_declaration(
yyscanner,
@@ -2047,7 +2048,7 @@ yyreduce:
break;
case 27:
-#line 441 "grammar.y"
+#line 442 "grammar.y"
{
(yyval.meta) = yr_parser_reduce_meta_declaration(
yyscanner,
@@ -2063,17 +2064,17 @@ yyreduce:
break;
case 28:
-#line 457 "grammar.y"
+#line 458 "grammar.y"
{ (yyval.string) = (yyvsp[(1) - (1)].string); }
break;
case 29:
-#line 458 "grammar.y"
+#line 459 "grammar.y"
{ (yyval.string) = (yyvsp[(1) - (2)].string); }
break;
case 30:
-#line 464 "grammar.y"
+#line 465 "grammar.y"
{
(yyval.string) = yr_parser_reduce_string_declaration(
yyscanner,
@@ -2089,14 +2090,14 @@ yyreduce:
break;
case 31:
-#line 477 "grammar.y"
+#line 478 "grammar.y"
{
compiler->error_line = yyget_lineno(yyscanner);
}
break;
case 32:
-#line 481 "grammar.y"
+#line 482 "grammar.y"
{
(yyval.string) = yr_parser_reduce_string_declaration(
yyscanner,
@@ -2112,7 +2113,7 @@ yyreduce:
break;
case 33:
-#line 494 "grammar.y"
+#line 495 "grammar.y"
{
(yyval.string) = yr_parser_reduce_string_declaration(
yyscanner,
@@ -2128,37 +2129,37 @@ yyreduce:
break;
case 34:
-#line 510 "grammar.y"
+#line 511 "grammar.y"
{ (yyval.integer) = 0; }
break;
case 35:
-#line 511 "grammar.y"
+#line 512 "grammar.y"
{ (yyval.integer) = (yyvsp[(1) - (2)].integer) | (yyvsp[(2) - (2)].integer); }
break;
case 36:
-#line 516 "grammar.y"
+#line 517 "grammar.y"
{ (yyval.integer) = STRING_GFLAGS_WIDE; }
break;
case 37:
-#line 517 "grammar.y"
+#line 518 "grammar.y"
{ (yyval.integer) = STRING_GFLAGS_ASCII; }
break;
case 38:
-#line 518 "grammar.y"
+#line 519 "grammar.y"
{ (yyval.integer) = STRING_GFLAGS_NO_CASE; }
break;
case 39:
-#line 519 "grammar.y"
+#line 520 "grammar.y"
{ (yyval.integer) = STRING_GFLAGS_FULL_WORD; }
break;
case 40:
-#line 525 "grammar.y"
+#line 526 "grammar.y"
{
YR_OBJECT* object = NULL;
YR_RULE* rule;
@@ -2249,7 +2250,7 @@ yyreduce:
break;
case 41:
-#line 613 "grammar.y"
+#line 614 "grammar.y"
{
YR_OBJECT* object = (yyvsp[(1) - (3)].object);
YR_OBJECT* field = NULL;
@@ -2301,7 +2302,7 @@ yyreduce:
break;
case 42:
-#line 662 "grammar.y"
+#line 663 "grammar.y"
{
if ((yyvsp[(1) - (4)].object) != NULL && (yyvsp[(1) - (4)].object)->type == OBJECT_TYPE_ARRAY)
{
@@ -2326,7 +2327,7 @@ yyreduce:
break;
case 43:
-#line 685 "grammar.y"
+#line 686 "grammar.y"
{
int args_count;
@@ -2364,18 +2365,18 @@ yyreduce:
break;
case 44:
-#line 724 "grammar.y"
+#line 725 "grammar.y"
{
(yyval.c_string) = yr_strdup("");
}
break;
case 45:
-#line 728 "grammar.y"
+#line 729 "grammar.y"
{
(yyval.c_string) = yr_malloc(MAX_FUNCTION_ARGS + 1);
- switch((yyvsp[(1) - (1)].expression_type))
+ switch((yyvsp[(1) - (1)].expression).type)
{
case EXPRESSION_TYPE_INTEGER:
strlcpy((yyval.c_string), "i", MAX_FUNCTION_ARGS);
@@ -2396,7 +2397,7 @@ yyreduce:
break;
case 46:
-#line 750 "grammar.y"
+#line 751 "grammar.y"
{
if (strlen((yyvsp[(1) - (3)].c_string)) == MAX_FUNCTION_ARGS)
{
@@ -2404,7 +2405,7 @@ yyreduce:
}
else
{
- switch((yyvsp[(3) - (3)].expression_type))
+ switch((yyvsp[(3) - (3)].expression).type)
{
case EXPRESSION_TYPE_INTEGER:
strlcat((yyvsp[(1) - (3)].c_string), "i", MAX_FUNCTION_ARGS);
@@ -2428,7 +2429,7 @@ yyreduce:
break;
case 47:
-#line 783 "grammar.y"
+#line 784 "grammar.y"
{
SIZED_STRING* sized_string = (yyvsp[(1) - (1)].sized_string);
RE* re;
@@ -2467,14 +2468,14 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_REGEXP;
+ (yyval.expression).type = EXPRESSION_TYPE_REGEXP;
}
break;
case 48:
-#line 828 "grammar.y"
+#line 829 "grammar.y"
{
- if ((yyvsp[(1) - (1)].expression_type) == EXPRESSION_TYPE_STRING)
+ if ((yyvsp[(1) - (1)].expression).type == EXPRESSION_TYPE_STRING)
{
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -2484,8 +2485,7 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
}
-
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
@@ -2497,7 +2497,7 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
@@ -2509,15 +2509,15 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 51:
#line 864 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_STRING, "matches");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_REGEXP, "matches");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_STRING, "matches");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_REGEXP, "matches");
if (compiler->last_result == ERROR_SUCCESS)
compiler->last_result = yr_parser_emit(
@@ -2527,15 +2527,15 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 52:
#line 879 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_STRING, "contains");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_STRING, "contains");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_STRING, "contains");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_STRING, "contains");
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -2544,7 +2544,7 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
@@ -2554,52 +2554,55 @@ yyreduce:
int result = yr_parser_reduce_string_identifier(
yyscanner,
(yyvsp[(1) - (1)].c_string),
- OP_STR_FOUND);
+ OP_STR_FOUND,
+ UNDEFINED);
yr_free((yyvsp[(1) - (1)].c_string));
ERROR_IF(result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 54:
-#line 906 "grammar.y"
+#line 907 "grammar.y"
{
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "at");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "at");
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
(yyvsp[(1) - (3)].c_string),
- OP_STR_FOUND_AT);
+ OP_STR_FOUND_AT,
+ (yyvsp[(3) - (3)].expression).value.integer);
yr_free((yyvsp[(1) - (3)].c_string));
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 55:
-#line 921 "grammar.y"
+#line 923 "grammar.y"
{
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
(yyvsp[(1) - (3)].c_string),
- OP_STR_FOUND_IN);
+ OP_STR_FOUND_IN,
+ UNDEFINED);
yr_free((yyvsp[(1) - (3)].c_string));
ERROR_IF(compiler->last_result!= ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 56:
-#line 934 "grammar.y"
+#line 937 "grammar.y"
{
int var_index;
@@ -2637,7 +2640,7 @@ yyreduce:
break;
case 57:
-#line 969 "grammar.y"
+#line 972 "grammar.y"
{
int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
int8_t* addr;
@@ -2675,7 +2678,7 @@ yyreduce:
break;
case 58:
-#line 1004 "grammar.y"
+#line 1007 "grammar.y"
{
int mem_offset;
@@ -2749,12 +2752,12 @@ yyreduce:
compiler->loop_identifier[compiler->loop_depth] = NULL;
yr_free((yyvsp[(3) - (11)].c_string));
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 59:
-#line 1080 "grammar.y"
+#line 1083 "grammar.y"
{
int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
int8_t* addr;
@@ -2787,7 +2790,7 @@ yyreduce:
break;
case 60:
-#line 1110 "grammar.y"
+#line 1113 "grammar.y"
{
int mem_offset;
@@ -2831,107 +2834,107 @@ yyreduce:
yr_parser_emit(yyscanner, OP_LE, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 61:
-#line 1157 "grammar.y"
+#line 1160 "grammar.y"
{
yr_parser_emit(yyscanner, OP_OF, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 62:
-#line 1163 "grammar.y"
+#line 1166 "grammar.y"
{
yr_parser_emit(yyscanner, OP_NOT, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 63:
-#line 1169 "grammar.y"
+#line 1172 "grammar.y"
{
yr_parser_emit(yyscanner, OP_AND, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 64:
-#line 1175 "grammar.y"
+#line 1178 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_BOOLEAN, "or");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_BOOLEAN, "or");
yr_parser_emit(yyscanner, OP_OR, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 65:
-#line 1183 "grammar.y"
+#line 1186 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<");
yr_parser_emit(yyscanner, OP_LT, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 66:
-#line 1192 "grammar.y"
+#line 1195 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">");
yr_parser_emit(yyscanner, OP_GT, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 67:
-#line 1201 "grammar.y"
+#line 1204 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<=");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<=");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<=");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<=");
yr_parser_emit(yyscanner, OP_LE, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 68:
-#line 1210 "grammar.y"
+#line 1213 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">=");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">=");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">=");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">=");
yr_parser_emit(yyscanner, OP_GE, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 69:
-#line 1219 "grammar.y"
+#line 1222 "grammar.y"
{
- if ((yyvsp[(1) - (3)].expression_type) != (yyvsp[(3) - (3)].expression_type))
+ if ((yyvsp[(1) - (3)].expression).type != (yyvsp[(3) - (3)].expression).type)
{
yr_compiler_set_error_extra_info(
compiler, "mismatching types for == operator");
compiler->last_result = ERROR_WRONG_TYPE;
}
- else if ((yyvsp[(1) - (3)].expression_type) == EXPRESSION_TYPE_STRING)
+ else if ((yyvsp[(1) - (3)].expression).type == EXPRESSION_TYPE_STRING)
{
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -2948,20 +2951,20 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 70:
-#line 1246 "grammar.y"
+#line 1249 "grammar.y"
{
- if ((yyvsp[(1) - (3)].expression_type) != (yyvsp[(3) - (3)].expression_type))
+ if ((yyvsp[(1) - (3)].expression).type != (yyvsp[(3) - (3)].expression).type)
{
yr_compiler_set_error_extra_info(
compiler, "mismatching types for == operator");
compiler->last_result = ERROR_WRONG_TYPE;
}
- else if ((yyvsp[(1) - (3)].expression_type) == EXPRESSION_TYPE_STRING)
+ else if ((yyvsp[(1) - (3)].expression).type == EXPRESSION_TYPE_STRING)
{
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -2978,20 +2981,20 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 71:
-#line 1273 "grammar.y"
+#line 1276 "grammar.y"
{
- if ((yyvsp[(1) - (3)].expression_type) != (yyvsp[(3) - (3)].expression_type))
+ if ((yyvsp[(1) - (3)].expression).type != (yyvsp[(3) - (3)].expression).type)
{
yr_compiler_set_error_extra_info(
compiler, "mismatching types for != operator");
compiler->last_result = ERROR_WRONG_TYPE;
}
- else if ((yyvsp[(1) - (3)].expression_type) == EXPRESSION_TYPE_STRING)
+ else if ((yyvsp[(1) - (3)].expression).type == EXPRESSION_TYPE_STRING)
{
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -3008,45 +3011,45 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
break;
case 72:
-#line 1300 "grammar.y"
+#line 1303 "grammar.y"
{
- (yyval.expression_type) = (yyvsp[(1) - (1)].expression_type);
+ (yyval.expression) = (yyvsp[(1) - (1)].expression);
}
break;
case 73:
-#line 1304 "grammar.y"
+#line 1307 "grammar.y"
{
- (yyval.expression_type) = (yyvsp[(2) - (3)].expression_type);
+ (yyval.expression) = (yyvsp[(2) - (3)].expression);
}
break;
case 74:
-#line 1311 "grammar.y"
+#line 1314 "grammar.y"
{ (yyval.integer) = INTEGER_SET_ENUMERATION; }
break;
case 75:
-#line 1312 "grammar.y"
+#line 1315 "grammar.y"
{ (yyval.integer) = INTEGER_SET_RANGE; }
break;
case 76:
-#line 1318 "grammar.y"
+#line 1321 "grammar.y"
{
- if ((yyvsp[(2) - (6)].expression_type) != EXPRESSION_TYPE_INTEGER)
+ if ((yyvsp[(2) - (6)].expression).type != EXPRESSION_TYPE_INTEGER)
{
yr_compiler_set_error_extra_info(
compiler, "wrong type for range's lower bound");
compiler->last_result = ERROR_WRONG_TYPE;
}
- if ((yyvsp[(5) - (6)].expression_type) != EXPRESSION_TYPE_INTEGER)
+ if ((yyvsp[(5) - (6)].expression).type != EXPRESSION_TYPE_INTEGER)
{
yr_compiler_set_error_extra_info(
compiler, "wrong type for range's upper bound");
@@ -3058,9 +3061,9 @@ yyreduce:
break;
case 77:
-#line 1340 "grammar.y"
+#line 1343 "grammar.y"
{
- if ((yyvsp[(1) - (1)].expression_type) != EXPRESSION_TYPE_INTEGER)
+ if ((yyvsp[(1) - (1)].expression).type != EXPRESSION_TYPE_INTEGER)
{
yr_compiler_set_error_extra_info(
compiler, "wrong type for enumeration item");
@@ -3073,9 +3076,9 @@ yyreduce:
break;
case 78:
-#line 1352 "grammar.y"
+#line 1355 "grammar.y"
{
- if ((yyvsp[(3) - (3)].expression_type) != EXPRESSION_TYPE_INTEGER)
+ if ((yyvsp[(3) - (3)].expression).type != EXPRESSION_TYPE_INTEGER)
{
yr_compiler_set_error_extra_info(
compiler, "wrong type for enumeration item");
@@ -3087,7 +3090,7 @@ yyreduce:
break;
case 79:
-#line 1367 "grammar.y"
+#line 1370 "grammar.y"
{
// Push end-of-list marker
yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
@@ -3095,7 +3098,7 @@ yyreduce:
break;
case 81:
-#line 1373 "grammar.y"
+#line 1376 "grammar.y"
{
yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
yr_parser_emit_pushes_for_strings(yyscanner, "$*");
@@ -3103,7 +3106,7 @@ yyreduce:
break;
case 84:
-#line 1388 "grammar.y"
+#line 1391 "grammar.y"
{
yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[(1) - (1)].c_string));
yr_free((yyvsp[(1) - (1)].c_string));
@@ -3111,7 +3114,7 @@ yyreduce:
break;
case 85:
-#line 1393 "grammar.y"
+#line 1396 "grammar.y"
{
yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[(1) - (1)].c_string));
yr_free((yyvsp[(1) - (1)].c_string));
@@ -3119,40 +3122,41 @@ yyreduce:
break;
case 87:
-#line 1403 "grammar.y"
+#line 1406 "grammar.y"
{
yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
}
break;
case 88:
-#line 1407 "grammar.y"
+#line 1410 "grammar.y"
{
yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL);
}
break;
case 89:
-#line 1415 "grammar.y"
+#line 1418 "grammar.y"
{
- (yyval.expression_type) = (yyvsp[(2) - (3)].expression_type);
+ (yyval.expression) = (yyvsp[(2) - (3)].expression);
}
break;
case 90:
-#line 1419 "grammar.y"
+#line 1422 "grammar.y"
{
compiler->last_result = yr_parser_emit(
yyscanner, OP_FILESIZE, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
-
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 91:
-#line 1428 "grammar.y"
+#line 1432 "grammar.y"
{
yywarning(yyscanner,
"Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " "function from PE module instead.");
@@ -3162,108 +3166,116 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 92:
-#line 1440 "grammar.y"
+#line 1445 "grammar.y"
{
- CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "int8");
+ CHECK_TYPE((yyvsp[(3) - (4)].expression), EXPRESSION_TYPE_INTEGER, "int8");
compiler->last_result = yr_parser_emit(
yyscanner, OP_INT8, NULL);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 93:
-#line 1451 "grammar.y"
+#line 1457 "grammar.y"
{
- CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "int16");
+ CHECK_TYPE((yyvsp[(3) - (4)].expression), EXPRESSION_TYPE_INTEGER, "int16");
compiler->last_result = yr_parser_emit(
yyscanner, OP_INT16, NULL);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 94:
-#line 1462 "grammar.y"
+#line 1469 "grammar.y"
{
- CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "int32");
+ CHECK_TYPE((yyvsp[(3) - (4)].expression), EXPRESSION_TYPE_INTEGER, "int32");
compiler->last_result = yr_parser_emit(
yyscanner, OP_INT32, NULL);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 95:
-#line 1473 "grammar.y"
+#line 1481 "grammar.y"
{
- CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "uint8");
+ CHECK_TYPE((yyvsp[(3) - (4)].expression), EXPRESSION_TYPE_INTEGER, "uint8");
compiler->last_result = yr_parser_emit(
yyscanner, OP_UINT8, NULL);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 96:
-#line 1484 "grammar.y"
+#line 1493 "grammar.y"
{
- CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "uint16");
+ CHECK_TYPE((yyvsp[(3) - (4)].expression), EXPRESSION_TYPE_INTEGER, "uint16");
compiler->last_result = yr_parser_emit(
yyscanner, OP_UINT16, NULL);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 97:
-#line 1495 "grammar.y"
+#line 1505 "grammar.y"
{
- CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "uint32");
+ CHECK_TYPE((yyvsp[(3) - (4)].expression), EXPRESSION_TYPE_INTEGER, "uint32");
compiler->last_result = yr_parser_emit(
yyscanner, OP_UINT32, NULL);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 98:
-#line 1506 "grammar.y"
+#line 1517 "grammar.y"
{
compiler->last_result = yr_parser_emit_with_arg(
yyscanner, OP_PUSH, (yyvsp[(1) - (1)].integer), NULL);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = (yyvsp[(1) - (1)].integer);
}
break;
case 99:
-#line 1515 "grammar.y"
+#line 1527 "grammar.y"
{
SIZED_STRING* sized_string = (yyvsp[(1) - (1)].sized_string);
char* string;
@@ -3284,44 +3296,48 @@ yyreduce:
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_STRING;
+ (yyval.expression).type = EXPRESSION_TYPE_STRING;
}
break;
case 100:
-#line 1538 "grammar.y"
+#line 1550 "grammar.y"
{
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
(yyvsp[(1) - (1)].c_string),
- OP_STR_COUNT);
+ OP_STR_COUNT,
+ UNDEFINED);
yr_free((yyvsp[(1) - (1)].c_string));
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 101:
-#line 1551 "grammar.y"
+#line 1565 "grammar.y"
{
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
(yyvsp[(1) - (4)].c_string),
- OP_STR_OFFSET);
+ OP_STR_OFFSET,
+ UNDEFINED);
yr_free((yyvsp[(1) - (4)].c_string));
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 102:
-#line 1564 "grammar.y"
+#line 1580 "grammar.y"
{
compiler->last_result = yr_parser_emit_with_arg(
yyscanner,
@@ -3333,26 +3349,29 @@ yyreduce:
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
(yyvsp[(1) - (1)].c_string),
- OP_STR_OFFSET);
+ OP_STR_OFFSET,
+ UNDEFINED);
yr_free((yyvsp[(1) - (1)].c_string));
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
break;
case 103:
-#line 1584 "grammar.y"
+#line 1602 "grammar.y"
{
if ((yyvsp[(1) - (1)].object) == (YR_OBJECT*) -1) // loop identifier
{
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
}
else if ((yyvsp[(1) - (1)].object) == (YR_OBJECT*) -2) // rule identifier
{
- (yyval.expression_type) = EXPRESSION_TYPE_BOOLEAN;
+ (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
}
else if ((yyvsp[(1) - (1)].object) != NULL)
{
@@ -3362,10 +3381,11 @@ yyreduce:
switch((yyvsp[(1) - (1)].object)->type)
{
case OBJECT_TYPE_INTEGER:
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = UNDEFINED;
break;
case OBJECT_TYPE_STRING:
- (yyval.expression_type) = EXPRESSION_TYPE_STRING;
+ (yyval.expression).type = EXPRESSION_TYPE_STRING;
break;
default:
assert(FALSE);
@@ -3382,146 +3402,158 @@ yyreduce:
break;
case 104:
-#line 1619 "grammar.y"
+#line 1639 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "+");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "+");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "+");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "+");
yr_parser_emit(yyscanner, OP_ADD, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(+, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 105:
-#line 1628 "grammar.y"
+#line 1649 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "-");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "-");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "-");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "-");
yr_parser_emit(yyscanner, OP_SUB, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(-, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 106:
-#line 1637 "grammar.y"
+#line 1659 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "*");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "*");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "*");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "*");
yr_parser_emit(yyscanner, OP_MUL, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(*, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 107:
-#line 1646 "grammar.y"
+#line 1669 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "\\");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "\\");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "\\");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "\\");
yr_parser_emit(yyscanner, OP_DIV, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(/, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 108:
-#line 1655 "grammar.y"
+#line 1679 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "%");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "%");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "%");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "%");
yr_parser_emit(yyscanner, OP_MOD, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(%, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 109:
-#line 1664 "grammar.y"
+#line 1689 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "^");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "^");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
yr_parser_emit(yyscanner, OP_XOR, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(^, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 110:
-#line 1673 "grammar.y"
+#line 1699 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "^");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "^");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
yr_parser_emit(yyscanner, OP_AND, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(&, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 111:
-#line 1682 "grammar.y"
+#line 1709 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "|");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "|");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "|");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "|");
yr_parser_emit(yyscanner, OP_OR, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(|, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 112:
-#line 1691 "grammar.y"
+#line 1719 "grammar.y"
{
- CHECK_TYPE((yyvsp[(2) - (2)].expression_type), EXPRESSION_TYPE_INTEGER, "~");
+ CHECK_TYPE((yyvsp[(2) - (2)].expression), EXPRESSION_TYPE_INTEGER, "~");
yr_parser_emit(yyscanner, OP_NEG, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = ((yyvsp[(2) - (2)].expression).value.integer == UNDEFINED) ?
+ UNDEFINED : (yyvsp[(2) - (2)].expression).value.integer;
}
break;
case 113:
-#line 1699 "grammar.y"
+#line 1729 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<<");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<<");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<<");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<<");
yr_parser_emit(yyscanner, OP_SHL, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(<<, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 114:
-#line 1708 "grammar.y"
+#line 1739 "grammar.y"
{
- CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">>");
- CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">>");
+ CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">>");
+ CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">>");
yr_parser_emit(yyscanner, OP_SHR, NULL);
- (yyval.expression_type) = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
+ (yyval.expression).value.integer = OPERATION(>>, (yyvsp[(1) - (3)].expression).value.integer, (yyvsp[(3) - (3)].expression).value.integer);
}
break;
case 115:
-#line 1717 "grammar.y"
+#line 1749 "grammar.y"
{
- (yyval.expression_type) = (yyvsp[(1) - (1)].expression_type);
+ (yyval.expression) = (yyvsp[(1) - (1)].expression);
}
break;
/* Line 1267 of yacc.c. */
-#line 3525 "grammar.c"
+#line 3557 "grammar.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -3735,6 +3767,6 @@ yyreturn:
}
-#line 1722 "grammar.y"
+#line 1754 "grammar.y"
diff --git a/libyara/grammar.h b/libyara/grammar.h
index 9865021..05c3426 100644
--- a/libyara/grammar.h
+++ b/libyara/grammar.h
@@ -150,11 +150,11 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 186 "grammar.y"
+#line 187 "grammar.y"
{
+ EXPRESSION expression;
SIZED_STRING* sized_string;
char* c_string;
- int8_t expression_type;
int64_t integer;
YR_STRING* string;
YR_META* meta;
diff --git a/libyara/grammar.y b/libyara/grammar.y
index 23391a7..b54e279 100644
--- a/libyara/grammar.y
+++ b/libyara/grammar.y
@@ -55,10 +55,10 @@ limitations under the License.
} \
-#define CHECK_TYPE_WITH_CLEANUP(actual_type, expected_type, op, cleanup) \
- if (actual_type != expected_type) \
+#define CHECK_TYPE_WITH_CLEANUP(expression, expected_type, op, cleanup) \
+ if (expression.type != expected_type) \
{ \
- switch(actual_type) \
+ switch(expression.type) \
{ \
case EXPRESSION_TYPE_INTEGER: \
yr_compiler_set_error_extra_info( \
@@ -75,8 +75,9 @@ limitations under the License.
YYERROR; \
}
-#define CHECK_TYPE(actual_type, expected_type, op) \
- CHECK_TYPE_WITH_CLEANUP(actual_type, expected_type, op, ) \
+
+#define CHECK_TYPE(expression, expected_type, op) \
+ CHECK_TYPE_WITH_CLEANUP(expression, expected_type, op, ) \
#define MSG(op) "wrong type \"string\" for \"" op "\" operator"
@@ -166,10 +167,10 @@ limitations under the License.
%type <object> identifier
-%type <expression_type> primary_expression
-%type <expression_type> boolean_expression
-%type <expression_type> expression
-%type <expression_type> regexp
+%type <expression> primary_expression
+%type <expression> boolean_expression
+%type <expression> expression
+%type <expression> regexp
%type <c_string> arguments_list
@@ -184,9 +185,9 @@ limitations under the License.
%destructor { yr_free($$); } _REGEXP_
%union {
+ EXPRESSION expression;
SIZED_STRING* sized_string;
char* c_string;
- int8_t expression_type;
int64_t integer;
YR_STRING* string;
YR_META* meta;
@@ -728,7 +729,7 @@ arguments_list
{
$$ = yr_malloc(MAX_FUNCTION_ARGS + 1);
- switch($1)
+ switch($1.type)
{
case EXPRESSION_TYPE_INTEGER:
strlcpy($$, "i", MAX_FUNCTION_ARGS);
@@ -754,7 +755,7 @@ arguments_list
}
else
{
- switch($3)
+ switch($3.type)
{
case EXPRESSION_TYPE_INTEGER:
strlcat($1, "i", MAX_FUNCTION_ARGS);
@@ -818,7 +819,7 @@ regexp
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_REGEXP;
+ $$.type = EXPRESSION_TYPE_REGEXP;
}
;
@@ -826,7 +827,7 @@ regexp
boolean_expression
: expression
{
- if ($1 == EXPRESSION_TYPE_STRING)
+ if ($1.type == EXPRESSION_TYPE_STRING)
{
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -836,8 +837,7 @@ boolean_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
}
-
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
;
@@ -849,7 +849,7 @@ expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| _FALSE_
{
@@ -858,7 +858,7 @@ expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _MATCHES_ regexp
{
@@ -873,7 +873,7 @@ expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _CONTAINS_ primary_expression
{
@@ -887,20 +887,21 @@ expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| _STRING_IDENTIFIER_
{
int result = yr_parser_reduce_string_identifier(
yyscanner,
$1,
- OP_STR_FOUND);
+ OP_STR_FOUND,
+ UNDEFINED);
yr_free($1);
ERROR_IF(result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| _STRING_IDENTIFIER_ _AT_ primary_expression
{
@@ -909,26 +910,28 @@ expression
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
$1,
- OP_STR_FOUND_AT);
+ OP_STR_FOUND_AT,
+ $3.value.integer);
yr_free($1);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| _STRING_IDENTIFIER_ _IN_ range
{
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
$1,
- OP_STR_FOUND_IN);
+ OP_STR_FOUND_IN,
+ UNDEFINED);
yr_free($1);
ERROR_IF(compiler->last_result!= ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| _FOR_ for_expression _IDENTIFIER_ _IN_
{
@@ -1074,7 +1077,7 @@ expression
compiler->loop_identifier[compiler->loop_depth] = NULL;
yr_free($3);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| _FOR_ for_expression _OF_ string_set ':'
{
@@ -1150,26 +1153,26 @@ expression
yr_parser_emit(yyscanner, OP_LE, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| for_expression _OF_ string_set
{
yr_parser_emit(yyscanner, OP_OF, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| _NOT_ boolean_expression
{
yr_parser_emit(yyscanner, OP_NOT, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| boolean_expression _AND_ boolean_expression
{
yr_parser_emit(yyscanner, OP_AND, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| boolean_expression _OR_ boolean_expression
{
@@ -1177,7 +1180,7 @@ expression
yr_parser_emit(yyscanner, OP_OR, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _LT_ primary_expression
{
@@ -1186,7 +1189,7 @@ expression
yr_parser_emit(yyscanner, OP_LT, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _GT_ primary_expression
{
@@ -1195,7 +1198,7 @@ expression
yr_parser_emit(yyscanner, OP_GT, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _LE_ primary_expression
{
@@ -1204,7 +1207,7 @@ expression
yr_parser_emit(yyscanner, OP_LE, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _GE_ primary_expression
{
@@ -1213,17 +1216,17 @@ expression
yr_parser_emit(yyscanner, OP_GE, NULL);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _EQ_ primary_expression
{
- if ($1 != $3)
+ if ($1.type != $3.type)
{
yr_compiler_set_error_extra_info(
compiler, "mismatching types for == operator");
compiler->last_result = ERROR_WRONG_TYPE;
}
- else if ($1 == EXPRESSION_TYPE_STRING)
+ else if ($1.type == EXPRESSION_TYPE_STRING)
{
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -1240,17 +1243,17 @@ expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _IS_ primary_expression
{
- if ($1 != $3)
+ if ($1.type != $3.type)
{
yr_compiler_set_error_extra_info(
compiler, "mismatching types for == operator");
compiler->last_result = ERROR_WRONG_TYPE;
}
- else if ($1 == EXPRESSION_TYPE_STRING)
+ else if ($1.type == EXPRESSION_TYPE_STRING)
{
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -1267,17 +1270,17 @@ expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression _NEQ_ primary_expression
{
- if ($1 != $3)
+ if ($1.type != $3.type)
{
yr_compiler_set_error_extra_info(
compiler, "mismatching types for != operator");
compiler->last_result = ERROR_WRONG_TYPE;
}
- else if ($1 == EXPRESSION_TYPE_STRING)
+ else if ($1.type == EXPRESSION_TYPE_STRING)
{
compiler->last_result = yr_parser_emit(
yyscanner,
@@ -1294,7 +1297,7 @@ expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
| primary_expression
{
@@ -1316,14 +1319,14 @@ integer_set
range
: '(' primary_expression '.' '.' primary_expression ')'
{
- if ($2 != EXPRESSION_TYPE_INTEGER)
+ if ($2.type != EXPRESSION_TYPE_INTEGER)
{
yr_compiler_set_error_extra_info(
compiler, "wrong type for range's lower bound");
compiler->last_result = ERROR_WRONG_TYPE;
}
- if ($5 != EXPRESSION_TYPE_INTEGER)
+ if ($5.type != EXPRESSION_TYPE_INTEGER)
{
yr_compiler_set_error_extra_info(
compiler, "wrong type for range's upper bound");
@@ -1338,7 +1341,7 @@ range
integer_enumeration
: primary_expression
{
- if ($1 != EXPRESSION_TYPE_INTEGER)
+ if ($1.type != EXPRESSION_TYPE_INTEGER)
{
yr_compiler_set_error_extra_info(
compiler, "wrong type for enumeration item");
@@ -1350,7 +1353,7 @@ integer_enumeration
}
| integer_enumeration ',' primary_expression
{
- if ($3 != EXPRESSION_TYPE_INTEGER)
+ if ($3.type != EXPRESSION_TYPE_INTEGER)
{
yr_compiler_set_error_extra_info(
compiler, "wrong type for enumeration item");
@@ -1420,9 +1423,10 @@ primary_expression
compiler->last_result = yr_parser_emit(
yyscanner, OP_FILESIZE, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
-
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _ENTRYPOINT_
{
@@ -1434,9 +1438,10 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
- | _INT8_ '(' primary_expression ')'
+ | _INT8_ '(' primary_expression ')'
{
CHECK_TYPE($3, EXPRESSION_TYPE_INTEGER, "int8");
@@ -1445,7 +1450,8 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _INT16_ '(' primary_expression ')'
{
@@ -1456,7 +1462,8 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _INT32_ '(' primary_expression ')'
{
@@ -1467,7 +1474,8 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _UINT8_ '(' primary_expression ')'
{
@@ -1478,7 +1486,8 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _UINT16_ '(' primary_expression ')'
{
@@ -1489,7 +1498,8 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _UINT32_ '(' primary_expression ')'
{
@@ -1500,7 +1510,8 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _NUMBER_
{
@@ -1509,7 +1520,8 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = $1;
}
| _TEXT_STRING_
{
@@ -1532,33 +1544,37 @@ primary_expression
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_STRING;
+ $$.type = EXPRESSION_TYPE_STRING;
}
| _STRING_COUNT_
{
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
$1,
- OP_STR_COUNT);
+ OP_STR_COUNT,
+ UNDEFINED);
yr_free($1);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _STRING_OFFSET_ '[' primary_expression ']'
{
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
$1,
- OP_STR_OFFSET);
+ OP_STR_OFFSET,
+ UNDEFINED);
yr_free($1);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| _STRING_OFFSET_
{
@@ -1572,23 +1588,26 @@ primary_expression
compiler->last_result = yr_parser_reduce_string_identifier(
yyscanner,
$1,
- OP_STR_OFFSET);
+ OP_STR_OFFSET,
+ UNDEFINED);
yr_free($1);
ERROR_IF(compiler->last_result != ERROR_SUCCESS);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
| identifier
{
if ($1 == (YR_OBJECT*) -1) // loop identifier
{
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
}
else if ($1 == (YR_OBJECT*) -2) // rule identifier
{
- $$ = EXPRESSION_TYPE_BOOLEAN;
+ $$.type = EXPRESSION_TYPE_BOOLEAN;
}
else if ($1 != NULL)
{
@@ -1598,10 +1617,11 @@ primary_expression
switch($1->type)
{
case OBJECT_TYPE_INTEGER:
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = UNDEFINED;
break;
case OBJECT_TYPE_STRING:
- $$ = EXPRESSION_TYPE_STRING;
+ $$.type = EXPRESSION_TYPE_STRING;
break;
default:
assert(FALSE);
@@ -1622,7 +1642,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_ADD, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(+, $1.value.integer, $3.value.integer);
}
| primary_expression '-' primary_expression
{
@@ -1631,7 +1652,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_SUB, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(-, $1.value.integer, $3.value.integer);
}
| primary_expression '*' primary_expression
{
@@ -1640,7 +1662,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_MUL, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(*, $1.value.integer, $3.value.integer);
}
| primary_expression '\\' primary_expression
{
@@ -1649,7 +1672,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_DIV, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(/, $1.value.integer, $3.value.integer);
}
| primary_expression '%' primary_expression
{
@@ -1658,7 +1682,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_MOD, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(%, $1.value.integer, $3.value.integer);
}
| primary_expression '^' primary_expression
{
@@ -1667,7 +1692,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_XOR, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(^, $1.value.integer, $3.value.integer);
}
| primary_expression '&' primary_expression
{
@@ -1676,7 +1702,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_AND, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(&, $1.value.integer, $3.value.integer);
}
| primary_expression '|' primary_expression
{
@@ -1685,7 +1712,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_OR, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(|, $1.value.integer, $3.value.integer);
}
| '~' primary_expression
{
@@ -1693,7 +1721,9 @@ primary_expression
yr_parser_emit(yyscanner, OP_NEG, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = ($2.value.integer == UNDEFINED) ?
+ UNDEFINED : $2.value.integer;
}
| primary_expression _SHIFT_LEFT_ primary_expression
{
@@ -1702,7 +1732,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_SHL, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(<<, $1.value.integer, $3.value.integer);
}
| primary_expression _SHIFT_RIGHT_ primary_expression
{
@@ -1711,7 +1742,8 @@ primary_expression
yr_parser_emit(yyscanner, OP_SHR, NULL);
- $$ = EXPRESSION_TYPE_INTEGER;
+ $$.type = EXPRESSION_TYPE_INTEGER;
+ $$.value.integer = OPERATION(>>, $1.value.integer, $3.value.integer);
}
| regexp
{
diff --git a/libyara/include/yara/exec.h b/libyara/include/yara/exec.h
index 7fbe7ac..97b3012 100644
--- a/libyara/include/yara/exec.h
+++ b/libyara/include/yara/exec.h
@@ -85,6 +85,14 @@ limitations under the License.
#define OP_IMPORT 55
+#define OPERATION(operator, op1, op2) \
+ (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (UNDEFINED) : (op1 operator op2)
+
+
+#define COMPARISON(operator, op1, op2) \
+ (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (0) : (op1 operator op2)
+
+
int yr_execute_code(
YR_RULES* rules,
YR_SCAN_CONTEXT* context,
diff --git a/libyara/include/yara/lexer.h b/libyara/include/yara/lexer.h
index b2d708f..fb9bf88 100644
--- a/libyara/include/yara/lexer.h
+++ b/libyara/include/yara/lexer.h
@@ -15,7 +15,7 @@ limitations under the License.
*/
#include <yara/compiler.h>
-#include <grammar.h>
+
#undef yyparse
#undef yylex
@@ -48,9 +48,26 @@ limitations under the License.
typedef void* yyscan_t;
#endif
+#ifndef YY_TYPEDEF_EXPRESSION_T
+#define YY_TYPEDEF_EXPRESSION_T
+
+typedef struct _EXPRESSION
+{
+ int type;
+
+ union {
+ int64_t integer;
+ } value;
+
+} EXPRESSION;
+
+union YYSTYPE;
+
+#endif
+
#define YY_DECL int yylex( \
- YYSTYPE* yylval_param, yyscan_t yyscanner, YR_COMPILER* compiler)
+ union YYSTYPE* yylval_param, yyscan_t yyscanner, YR_COMPILER* compiler)
#define YY_FATAL_ERROR(msg) yara_yyfatal(yyscanner, msg)
@@ -63,7 +80,7 @@ typedef void* yyscan_t;
int yyget_lineno(yyscan_t yyscanner);
int yylex(
- YYSTYPE* yylval_param,
+ union YYSTYPE* yylval_param,
yyscan_t yyscanner,
YR_COMPILER* compiler);
diff --git a/libyara/include/yara/parser.h b/libyara/include/yara/parser.h
index 6625897..a032c98 100644
--- a/libyara/include/yara/parser.h
+++ b/libyara/include/yara/parser.h
@@ -84,7 +84,8 @@ YR_META* yr_parser_reduce_meta_declaration(
int yr_parser_reduce_string_identifier(
yyscan_t yyscanner,
const char* identifier,
- int8_t instruction);
+ int8_t instruction,
+ uint64_t at_offset);
int yr_parser_emit_pushes_for_strings(
diff --git a/libyara/include/yara/types.h b/libyara/include/yara/types.h
index 0e2c284..32c8186 100644
--- a/libyara/include/yara/types.h
+++ b/libyara/include/yara/types.h
@@ -117,6 +117,7 @@ typedef struct _YR_MATCHES
#define STRING_GFLAGS_NULL 0x1000
#define STRING_GFLAGS_CHAIN_PART 0x2000
#define STRING_GFLAGS_CHAIN_TAIL 0x4000
+#define STRING_GFLAGS_FIXED_OFFSET 0x8000
#define STRING_IS_HEX(x) \
@@ -146,6 +147,9 @@ typedef struct _YR_MATCHES
#define STRING_IS_SINGLE_MATCH(x) \
(((x)->g_flags) & STRING_GFLAGS_SINGLE_MATCH)
+#define STRING_IS_FIXED_OFFSET(x) \
+ (((x)->g_flags) & STRING_GFLAGS_FIXED_OFFSET)
+
#define STRING_IS_LITERAL(x) \
(((x)->g_flags) & STRING_GFLAGS_LITERAL)
@@ -183,6 +187,8 @@ typedef struct _YR_STRING
int32_t chain_gap_min;
int32_t chain_gap_max;
+ int64_t fixed_offset;
+
YR_MATCHES matches[MAX_THREADS];
YR_MATCHES unconfirmed_matches[MAX_THREADS];
diff --git a/libyara/parser.c b/libyara/parser.c
index 87e7931..3f8dd5a 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -329,6 +329,7 @@ int _yr_parser_write_string(
(*string)->g_flags = flags;
(*string)->chained_to = NULL;
+ (*string)->fixed_offset = UNDEFINED;
#ifdef PROFILING_ENABLED
(*string)->clock_ticks = 0;
@@ -489,6 +490,14 @@ YR_STRING* yr_parser_reduce_string_declaration(
string_flags |= STRING_GFLAGS_SINGLE_MATCH;
+ // The STRING_GFLAGS_FIXED_OFFSET indicates that the string doesn't
+ // need to be searched all over the file because the user is using the
+ // "at" operator. The string must be searched at a fixed offset in the
+ // file. All strings are marked STRING_GFLAGS_FIXED_OFFSET initially,
+ // and unmarked later if required.
+
+ string_flags |= STRING_GFLAGS_FIXED_OFFSET;
+
if (string_flags & STRING_GFLAGS_HEXADECIMAL ||
string_flags & STRING_GFLAGS_REGEXP)
{
@@ -730,14 +739,15 @@ int yr_parser_reduce_rule_declaration(
int yr_parser_reduce_string_identifier(
yyscan_t yyscanner,
const char* identifier,
- int8_t instruction)
+ int8_t instruction,
+ uint64_t at_offset)
{
YR_STRING* string;
YR_COMPILER* compiler = yyget_extra(yyscanner);
- if (strcmp(identifier, "$") == 0)
+ if (strcmp(identifier, "$") == 0) // is an anonymous string ?
{
- if (compiler->loop_for_of_mem_offset >= 0)
+ if (compiler->loop_for_of_mem_offset >= 0) // inside a loop ?
{
yr_parser_emit_with_arg(
yyscanner,
@@ -747,22 +757,41 @@ int yr_parser_reduce_string_identifier(
yr_parser_emit(yyscanner, instruction, NULL);
- if (instruction != OP_STR_FOUND)
+ string = compiler->current_rule_strings;
+
+ while(!STRING_IS_NULL(string))
{
- string = compiler->current_rule_strings;
+ if (instruction != OP_STR_FOUND)
+ string->g_flags &= ~STRING_GFLAGS_SINGLE_MATCH;
- while(!STRING_IS_NULL(string))
+ if (instruction == OP_STR_FOUND_AT)
{
- string->g_flags &= ~STRING_GFLAGS_SINGLE_MATCH;
- string = yr_arena_next_address(
- compiler->strings_arena,
- string,
- sizeof(YR_STRING));
+ // Avoid overwriting any previous fixed offset
+
+ if (string->fixed_offset == UNDEFINED)
+ string->fixed_offset = at_offset;
+
+ // If a previous fixed offset was different, disable
+ // the STRING_GFLAGS_FIXED_OFFSET flag because we only
+ // have room to store a single fixed offset value
+
+ if (string->fixed_offset != at_offset)
+ string->g_flags &= ~STRING_GFLAGS_FIXED_OFFSET;
+ }
+ else
+ {
+ string->g_flags &= ~STRING_GFLAGS_FIXED_OFFSET;
}
+
+ string = yr_arena_next_address(
+ compiler->strings_arena,
+ string,
+ sizeof(YR_STRING));
}
}
else
{
+ // Anonymous strings not allowed outside of a loop
compiler->last_result = ERROR_MISPLACED_ANONYMOUS_STRING;
}
}
@@ -781,6 +810,25 @@ int yr_parser_reduce_string_identifier(
if (instruction != OP_STR_FOUND)
string->g_flags &= ~STRING_GFLAGS_SINGLE_MATCH;
+ if (instruction == OP_STR_FOUND_AT)
+ {
+ // Avoid overwriting any previous fixed offset
+
+ if (string->fixed_offset == UNDEFINED)
+ string->fixed_offset = at_offset;
+
+ // If a previous fixed offset was different, disable
+ // the STRING_GFLAGS_FIXED_OFFSET flag because we only
+ // have room to store a single fixed offset value
+
+ if (string->fixed_offset != at_offset)
+ string->g_flags &= ~STRING_GFLAGS_FIXED_OFFSET;
+ }
+ else
+ {
+ string->g_flags &= ~STRING_GFLAGS_FIXED_OFFSET;
+ }
+
yr_parser_emit(yyscanner, instruction, NULL);
string->g_flags |= STRING_GFLAGS_REFERENCED;
diff --git a/libyara/scan.c b/libyara/scan.c
index 44ddf5c..abce84c 100644
--- a/libyara/scan.c
+++ b/libyara/scan.c
@@ -858,6 +858,10 @@ int yr_scan_verify_match(
STRING_FOUND(string))
return ERROR_SUCCESS;
+ if (STRING_IS_FIXED_OFFSET(string) &&
+ string->fixed_offset != data_base + offset)
+ return ERROR_SUCCESS;
+
if (STRING_IS_LITERAL(string))
{
FAIL_ON_ERROR(_yr_scan_verify_literal_match(
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git
More information about the forensics-changes
mailing list