[Forensics-changes] [yara] 06/11: New upstream version 3.6.1+dfsg

Hilko Bengen bengen at moszumanska.debian.org
Wed Jun 28 07:22:16 UTC 2017


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to branch master
in repository yara.

commit 3c89db4a1c87e9b215e0238cb4738c41a30f6a19
Author: Hilko Bengen <bengen at debian.org>
Date:   Fri Jun 23 22:56:39 2017 +0200

    New upstream version 3.6.1+dfsg
---
 configure.ac                   |   2 +-
 docs/writingrules.rst          | 101 ++++++++++++------------
 libyara/Makefile.am            |   2 +-
 libyara/hex_grammar.c          | 136 ++++++++++++++++++---------------
 libyara/hex_grammar.h          |   4 +-
 libyara/hex_grammar.y          |  14 ++++
 libyara/include/yara/libyara.h |   2 +-
 libyara/include/yara/limits.h  |  20 +++++
 libyara/include/yara/re.h      |   1 +
 libyara/modules/magic.c        |   8 +-
 libyara/modules/pe.c           |  12 +--
 libyara/parser.c               |  12 +--
 libyara/re.c                   |  18 +----
 libyara/re_grammar.c           | 170 ++++++++++++++++++++++-------------------
 libyara/re_grammar.h           |   2 +-
 libyara/re_grammar.y           |  14 ++++
 tests/data/tiny-overlay        | Bin 0 -> 32775 bytes
 tests/test-pe.c                |  16 ++++
 18 files changed, 310 insertions(+), 224 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8f4da59..85cefba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([yara], [3.6.0], [vmalvarez at virustotal.com])
+AC_INIT([yara], [3.6.1], [vmalvarez at virustotal.com])
 
 AC_CONFIG_SRCDIR([yara.c])
 
diff --git a/docs/writingrules.rst b/docs/writingrules.rst
index 1b2c8c8..29396a1 100644
--- a/docs/writingrules.rst
+++ b/docs/writingrules.rst
@@ -12,12 +12,12 @@ YARA, which does absolutely nothing::
            false
     }
 
-Each rule in YARA starts with the keyword rule followed by a rule identifier.
-Identifiers must follow the same lexical conventions of the C programming
-language, they can contain any alphanumeric character and the underscore
-character, but the first character can not be a digit. Rule identifiers are
-case sensitive and cannot exceed 128 characters. The following keywords are
-reserved and cannot be used as an identifier:
+Each rule in YARA starts with the keyword ``rule`` followed by a rule
+identifier. Identifiers must follow the same lexical conventions of the C
+programming language, they can contain any alphanumeric character and the
+underscore character, but the first character can not be a digit. Rule
+identifiers are case sensitive and cannot exceed 128 characters. The following
+keywords are reserved and cannot be used as an identifier:
 
 
 .. list-table:: YARA keywords
@@ -606,9 +606,9 @@ postfix, when attached to a numerical constant, automatically multiplies the
 value of the constant by 1024. The ``MB`` postfix can be used to multiply the
 value by 2^20. Both postfixes can be used only with decimal constants.
 
-The use of ``filesize`` only makes sense when the rule is applied to a file, if
-the rule is applied to a running process it won’t ever match because ``filesize``
-doesn’t make sense in this context.
+The use of ``filesize`` only makes sense when the rule is applied to a file. If
+the rule is applied to a running process it won’t ever match because
+``filesize`` doesn’t make sense in this context.
 
 Executable entry point
 ----------------------
@@ -640,7 +640,7 @@ or simple file infectors. ::
     }
 
 The presence of the ``entrypoint`` variable in a rule implies that only PE or
-ELF files can satisfy that rule. If the file is not a PE or ELF any rule using
+ELF files can satisfy that rule. If the file is not a PE or ELF, any rule using
 this variable evaluates to false.
 
 .. warning:: The ``entrypoint`` variable is deprecated, you should use the
@@ -653,8 +653,8 @@ Accessing data at a given position
 ----------------------------------
 
 There are many situations in which you may want to write conditions that depend
-on data stored at a certain file offset or memory virtual address, depending if
-we are scanning a file or a running process. In those situations you can use
+on data stored at a certain file offset or virtual memory address, depending on
+if we are scanning a file or a running process. In those situations you can use
 one of the following functions to read data from the file at the given offset::
 
     int8(<offset or virtual address>)
@@ -697,7 +697,7 @@ Sets of strings
 There are circumstances in which it is necessary to express that the file should
 contain a certain number strings from a given set. None of the strings in the
 set are required to be present, but at least some of them should be. In these
-situations the operator ``of`` comes in to help. ::
+situations the ``of`` operator can be used. ::
 
     rule OfExample1
     {
@@ -710,10 +710,10 @@ situations the operator ``of`` comes in to help. ::
             2 of ($a,$b,$c)
     }
 
-What this rule says is that at least two of the strings in the set ($a,$b,$c)
-must be present in the file, no matter which. Of course, when using this
-operator, the number before the ``of`` keyword must be equal to or less than
-the number of strings in the set.
+This rule requires that at least two of the strings in the set ($a,$b,$c)
+must be present in the file, but it does not matter which two. Of course, when
+using this operator, the number before the ``of`` keyword must be less than or
+equal to the number of strings in the set.
 
 The elements of the set can be explicitly enumerated like in the previous
 example, or can be specified by using wild cards. For example::
@@ -742,8 +742,8 @@ example, or can be specified by using wild cards. For example::
             3 of ($foo*,$bar1,$bar2)
     }
 
-You can even use ($*) to refer to all the strings in your rule, or write the
-equivalent keyword ``them`` for more legibility. ::
+You can even use ``($*)`` to refer to all the strings in your rule, or write
+the equivalent keyword ``them`` for more legibility. ::
 
     rule OfExample4
     {
@@ -756,9 +756,9 @@ equivalent keyword ``them`` for more legibility. ::
             1 of them // equivalent to 1 of ($*)
     }
 
-In all the above examples the number of strings have been specified by a
+In all the examples above, the number of strings have been specified by a
 numeric constant, but any expression returning a numeric value can be used.
-The keywords any and all can be used as well. ::
+The keywords ``any`` and ``all`` can be used as well. ::
 
     all of them       // all strings in the rule
     any of them       // any string in the rule
@@ -846,7 +846,7 @@ they satisfy a given condition. For example::
             for all i in (1,2,3) : ( @a[i] + 10 == @b[i] )
     }
 
-The previous rule tells that the first three occurrences of $b should be 10
+The previous rule says that the first three occurrences of $b should be 10
 bytes away from the first three occurrences of $a.
 
 The same condition could be written also as::
@@ -909,15 +909,16 @@ define the rule being invoked before the one that will make the invocation.
 More about rules
 ================
 
-There are some aspects of YARA rules that have not been covered yet, but still
-are very important. They are: global rules, private rules, tags and metadata.
+There are some aspects of YARA rules that have not been covered yet, but are
+still very important. These are: global rules, private rules, tags and
+metadata.
 
 Global rules
 ------------
 
 Global rules give you the possibility of imposing restrictions in all your
 rules at once. For example, suppose that you want all your rules ignoring
-those files that exceed a certain size limit, you could go rule by rule doing
+those files that exceed a certain size limit, you could go rule by rule making
 the required modifications to their conditions, or just write a global rule
 like this one::
 
@@ -940,7 +941,7 @@ at all may seem sterile at first glance, but when mixed with the possibility
 offered by YARA of referencing one rule from another (see
 :ref:`referencing-rules`) they become useful. Private rules can serve as
 building blocks for other rules, and at the same time prevent cluttering
-YARA's output with irrelevant information. For declaring a rule as private
+YARA's output with irrelevant information. To delcare a rule as private
 just add the keyword ``private`` before the rule declaration. ::
 
     private rule PrivateRuleExample
@@ -974,7 +975,7 @@ Tags must follow the same lexical convention of rule identifiers, therefore
 only alphanumeric characters and underscores are allowed, and the tag cannot
 start with a digit. They are also case sensitive.
 
-When using YARA you can output only those rules that are tagged with the tag
+When using YARA you can output only those rules which are tagged with the tag
 or tags that you provide.
 
 
@@ -1002,7 +1003,7 @@ identifier/value pairs like in the following example::
     }
 
 As can be seen in the example, metadata identifiers are always followed by
-an equal sign and the value assigned to them. The assigned values can be
+an equals sign and the value assigned to them. The assigned values can be
 strings, integers, or one of the boolean values true or false. Note that
 identifier/value pairs defined in the metadata section can not be used in
 the condition section, their only purpose is to store additional information
@@ -1015,8 +1016,8 @@ Using modules
 
 Modules are extensions to YARA's core functionality. Some modules like
 the :ref:`PE module <pe-module>` and the :ref:`Cuckoo module <cuckoo-module>`
-are officially distributed with YARA and some of them can be created by
-third-parties or even by yourself as described in :ref:`writing-modules`.
+are officially distributed with YARA and additional ones can be created by
+third-parties or even yourself as described in :ref:`writing-modules`.
 
 The first step to using a module is importing it with the ``import`` statement.
 These statements must be placed outside any rule definition and followed by
@@ -1027,7 +1028,7 @@ the module name enclosed in double-quotes. Like this::
     import "cuckoo"
 
 After importing the module you can make use of its features, always using
-``<module name>.`` as a prefix to any variable, or function exported by the
+``<module name>.`` as a prefix to any variable or function exported by the
 module. For example::
 
     pe.entry_point == 0x1000
@@ -1049,18 +1050,18 @@ the rule to keep its meaningfulness. Take a look at this rule::
           $a and pe.entry_point == 0x1000
     }
 
-If the scanned file is not a PE you wouldn't expect this rule matching the file,
-even if it contains the string, because **both** conditions (the presence of the
-string and the right value for the entry point) must be satisfied. However, if the
-condition is changed to::
+If the scanned file is not a PE you wouldn't expect this rule to match the file,
+even if it contains the string, because **both** conditions (the presence of
+the string and the right value for the entry point) must be satisfied. However,
+if the condition is changed to::
 
     $a or pe.entry_point == 0x1000
 
-You would expect the rule matching in this case if the file contains the string,
-even if it isn't a PE file. That's exactly how YARA behaves. The logic is simple:
-any arithmetic, comparison, or boolean operation will result in an undefined value
-if one of its operands is undefined, except for *OR* operations where an undefined
-operand is interpreted as a False.
+You would expect the rule to match in this case if the file contains the string,
+even if it isn't a PE file. That's exactly how YARA behaves. The logic is
+simple: any arithmetic, comparison, or boolean operation will result in an
+undefined value if one of its operands is undefined, except for *OR* operations
+where an undefined operand is interpreted as a False.
 
 
 External variables
@@ -1089,9 +1090,9 @@ For example::
            bool_ext_var or filesize < int_ext_var
     }
 
-External variables of type string can be used with operators ``contains`` and
-``matches``. The ``contains`` operator returns true if the string contains the
-specified substring. The operator ``matches`` returns true if the string
+External variables of type string can be used with the operators: ``contains``
+and ``matches``. The ``contains`` operator returns true if the string contains
+the specified substring. The ``matches`` operator returns true if the string
 matches the given regular expression. ::
 
 
@@ -1130,9 +1131,9 @@ providing the ``externals`` parameter to the appropriate method in
 Including files
 ===============
 
-In order to allow you a more flexible organization of your rules files,
+In order to allow for more flexible organization of your rules files,
 YARA provides the ``include`` directive. This directive works in a similar way
-to the *#include* pre-processor directive in your C programs, which inserts the
+to the *#include* pre-processor directive in C programs, which inserts the
 content of the specified source file into the current file during compilation.
 The following example will include the content of *other.yar* into the current
 file::
@@ -1140,19 +1141,19 @@ file::
     include "other.yar"
 
 The base path when searching for a file in an ``include`` directive will be the
-directory where the current file resides. For that reason, the file *other.yar*
+directory where the current file resides. For this reason, the file *other.yar*
 in the previous example should be located in the same directory of the current
-file. However you can also specify relative paths like these ones::
+file. However, you can also specify relative paths like these::
 
     include "./includes/other.yar"
     include "../includes/other.yar"
 
-And you can also use absolute paths::
+Or use absolute paths::
 
     include "/home/plusvic/yara/includes/other.yar"
 
-In Windows both slashes and backslashes are accepted, and don’t forget to write
-the drive letter::
+In Windows, both forward and back slashes are accepted, but don’t forget to
+write the drive letter::
 
     include "c:/yara/includes/other.yar"
     include "c:\\yara\\includes\\other.yar"
diff --git a/libyara/Makefile.am b/libyara/Makefile.am
index 0be3138..6c747ec 100644
--- a/libyara/Makefile.am
+++ b/libyara/Makefile.am
@@ -82,7 +82,7 @@ yarainclude_HEADERS = \
 
 lib_LTLIBRARIES = libyara.la
 
-libyara_la_LDFLAGS = -version-number 3:6:0
+libyara_la_LDFLAGS = -version-number 3:6:1
 
 libyara_la_SOURCES = \
   $(MODULES) \
diff --git a/libyara/hex_grammar.c b/libyara/hex_grammar.c
index a6cfbf0..48f550a 100644
--- a/libyara/hex_grammar.c
+++ b/libyara/hex_grammar.c
@@ -93,6 +93,13 @@
 #define mark_as_not_fast_regexp() \
     ((RE_AST*) yyget_extra(yyscanner))->flags &= ~RE_FLAGS_FAST_REGEXP
 
+#define incr_ast_levels() \
+    if (((RE_AST*) yyget_extra(yyscanner))->levels++ > RE_MAX_AST_LEVELS) \
+    { \
+      lex_env->last_error_code = ERROR_INVALID_HEX_STRING; \
+      YYABORT; \
+    }
+
 #define ERROR_IF(x, error) \
     if (x) \
     { \
@@ -107,7 +114,7 @@
     } \
 
 
-#line 111 "hex_grammar.c" /* yacc.c:339  */
+#line 118 "hex_grammar.c" /* yacc.c:339  */
 
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -157,12 +164,12 @@ extern int hex_yydebug;
 
 union YYSTYPE
 {
-#line 78 "hex_grammar.y" /* yacc.c:355  */
+#line 85 "hex_grammar.y" /* yacc.c:355  */
 
   int64_t integer;
   RE_NODE *re_node;
 
-#line 166 "hex_grammar.c" /* yacc.c:355  */
+#line 173 "hex_grammar.c" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -178,7 +185,7 @@ int hex_yyparse (void *yyscanner, HEX_LEX_ENVIRONMENT *lex_env);
 
 /* Copy the second part of user declarations.  */
 
-#line 182 "hex_grammar.c" /* yacc.c:358  */
+#line 189 "hex_grammar.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -476,9 +483,9 @@ static const yytype_uint8 yytranslate[] =
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   105,   105,   114,   118,   127,   189,   193,   206,   210,
-     219,   233,   232,   245,   268,   300,   322,   342,   346,   360,
-     368
+       0,   112,   112,   121,   125,   136,   200,   204,   219,   223,
+     232,   246,   245,   258,   281,   313,   335,   355,   359,   374,
+     382
 };
 #endif
 
@@ -1017,45 +1024,45 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, void *yyscanner, H
   switch (yytype)
     {
           case 16: /* tokens  */
-#line 94 "hex_grammar.y" /* yacc.c:1257  */
+#line 101 "hex_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1023 "hex_grammar.c" /* yacc.c:1257  */
+#line 1030 "hex_grammar.c" /* yacc.c:1257  */
         break;
 
     case 17: /* token_sequence  */
-#line 95 "hex_grammar.y" /* yacc.c:1257  */
+#line 102 "hex_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1029 "hex_grammar.c" /* yacc.c:1257  */
+#line 1036 "hex_grammar.c" /* yacc.c:1257  */
         break;
 
     case 18: /* token_or_range  */
-#line 96 "hex_grammar.y" /* yacc.c:1257  */
+#line 103 "hex_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1035 "hex_grammar.c" /* yacc.c:1257  */
+#line 1042 "hex_grammar.c" /* yacc.c:1257  */
         break;
 
     case 19: /* token  */
-#line 97 "hex_grammar.y" /* yacc.c:1257  */
+#line 104 "hex_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1041 "hex_grammar.c" /* yacc.c:1257  */
+#line 1048 "hex_grammar.c" /* yacc.c:1257  */
         break;
 
     case 21: /* range  */
-#line 100 "hex_grammar.y" /* yacc.c:1257  */
+#line 107 "hex_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1047 "hex_grammar.c" /* yacc.c:1257  */
+#line 1054 "hex_grammar.c" /* yacc.c:1257  */
         break;
 
     case 22: /* alternatives  */
-#line 99 "hex_grammar.y" /* yacc.c:1257  */
+#line 106 "hex_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1053 "hex_grammar.c" /* yacc.c:1257  */
+#line 1060 "hex_grammar.c" /* yacc.c:1257  */
         break;
 
     case 23: /* byte  */
-#line 98 "hex_grammar.y" /* yacc.c:1257  */
+#line 105 "hex_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1059 "hex_grammar.c" /* yacc.c:1257  */
+#line 1066 "hex_grammar.c" /* yacc.c:1257  */
         break;
 
 
@@ -1321,25 +1328,27 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 106 "hex_grammar.y" /* yacc.c:1646  */
+#line 113 "hex_grammar.y" /* yacc.c:1661  */
     {
         RE_AST* re_ast = yyget_extra(yyscanner);
         re_ast->root_node = (yyvsp[-1].re_node);
       }
-#line 1330 "hex_grammar.c" /* yacc.c:1646  */
+#line 1337 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 3:
-#line 115 "hex_grammar.y" /* yacc.c:1646  */
+#line 122 "hex_grammar.y" /* yacc.c:1661  */
     {
         (yyval.re_node) = (yyvsp[0].re_node);
       }
-#line 1338 "hex_grammar.c" /* yacc.c:1646  */
+#line 1345 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 4:
-#line 119 "hex_grammar.y" /* yacc.c:1646  */
+#line 126 "hex_grammar.y" /* yacc.c:1661  */
     {
+        incr_ast_levels();
+
         (yyval.re_node) = yr_re_node_create(RE_NODE_CONCAT, (yyvsp[-1].re_node), (yyvsp[0].re_node));
 
         DESTROY_NODE_IF((yyval.re_node) == NULL, (yyvsp[-1].re_node));
@@ -1347,16 +1356,18 @@ yyreduce:
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1351 "hex_grammar.c" /* yacc.c:1646  */
+#line 1360 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 5:
-#line 128 "hex_grammar.y" /* yacc.c:1646  */
+#line 137 "hex_grammar.y" /* yacc.c:1661  */
     {
         RE_NODE* new_concat;
         RE_NODE* leftmost_concat = NULL;
         RE_NODE* leftmost_node = (yyvsp[-1].re_node);
 
+        incr_ast_levels();
+
         (yyval.re_node) = NULL;
 
         /*
@@ -1409,20 +1420,22 @@ yyreduce:
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1413 "hex_grammar.c" /* yacc.c:1646  */
+#line 1424 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 6:
-#line 190 "hex_grammar.y" /* yacc.c:1646  */
+#line 201 "hex_grammar.y" /* yacc.c:1661  */
     {
         (yyval.re_node) = (yyvsp[0].re_node);
       }
-#line 1421 "hex_grammar.c" /* yacc.c:1646  */
+#line 1432 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 7:
-#line 194 "hex_grammar.y" /* yacc.c:1646  */
+#line 205 "hex_grammar.y" /* yacc.c:1661  */
     {
+        incr_ast_levels();
+
         (yyval.re_node) = yr_re_node_create(RE_NODE_CONCAT, (yyvsp[-1].re_node), (yyvsp[0].re_node));
 
         DESTROY_NODE_IF((yyval.re_node) == NULL, (yyvsp[-1].re_node));
@@ -1430,28 +1443,28 @@ yyreduce:
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1434 "hex_grammar.c" /* yacc.c:1646  */
+#line 1447 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 8:
-#line 207 "hex_grammar.y" /* yacc.c:1646  */
+#line 220 "hex_grammar.y" /* yacc.c:1661  */
     {
         (yyval.re_node) = (yyvsp[0].re_node);
       }
-#line 1442 "hex_grammar.c" /* yacc.c:1646  */
+#line 1455 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 9:
-#line 211 "hex_grammar.y" /* yacc.c:1646  */
+#line 224 "hex_grammar.y" /* yacc.c:1661  */
     {
         (yyval.re_node) = (yyvsp[0].re_node);
         (yyval.re_node)->greedy = FALSE;
       }
-#line 1451 "hex_grammar.c" /* yacc.c:1646  */
+#line 1464 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 10:
-#line 220 "hex_grammar.y" /* yacc.c:1646  */
+#line 233 "hex_grammar.y" /* yacc.c:1661  */
     {
         lex_env->token_count++;
 
@@ -1464,28 +1477,28 @@ yyreduce:
 
         (yyval.re_node) = (yyvsp[0].re_node);
       }
-#line 1468 "hex_grammar.c" /* yacc.c:1646  */
+#line 1481 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 11:
-#line 233 "hex_grammar.y" /* yacc.c:1646  */
+#line 246 "hex_grammar.y" /* yacc.c:1661  */
     {
         lex_env->inside_or++;
       }
-#line 1476 "hex_grammar.c" /* yacc.c:1646  */
+#line 1489 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 12:
-#line 237 "hex_grammar.y" /* yacc.c:1646  */
+#line 250 "hex_grammar.y" /* yacc.c:1661  */
     {
         (yyval.re_node) = (yyvsp[-1].re_node);
         lex_env->inside_or--;
       }
-#line 1485 "hex_grammar.c" /* yacc.c:1646  */
+#line 1498 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 13:
-#line 246 "hex_grammar.y" /* yacc.c:1646  */
+#line 259 "hex_grammar.y" /* yacc.c:1661  */
     {
         if ((yyvsp[-1].integer) <= 0)
         {
@@ -1508,11 +1521,11 @@ yyreduce:
         (yyval.re_node)->start = (int) (yyvsp[-1].integer);
         (yyval.re_node)->end = (int) (yyvsp[-1].integer);
       }
-#line 1512 "hex_grammar.c" /* yacc.c:1646  */
+#line 1525 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 14:
-#line 269 "hex_grammar.y" /* yacc.c:1646  */
+#line 282 "hex_grammar.y" /* yacc.c:1661  */
     {
         if (lex_env->inside_or &&
             ((yyvsp[-3].integer) > STRING_CHAINING_THRESHOLD ||
@@ -1544,11 +1557,11 @@ yyreduce:
         (yyval.re_node)->start = (int) (yyvsp[-3].integer);
         (yyval.re_node)->end = (int) (yyvsp[-1].integer);
       }
-#line 1548 "hex_grammar.c" /* yacc.c:1646  */
+#line 1561 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 15:
-#line 301 "hex_grammar.y" /* yacc.c:1646  */
+#line 314 "hex_grammar.y" /* yacc.c:1661  */
     {
         if (lex_env->inside_or)
         {
@@ -1570,11 +1583,11 @@ yyreduce:
         (yyval.re_node)->start = (int) (yyvsp[-2].integer);
         (yyval.re_node)->end = INT_MAX;
       }
-#line 1574 "hex_grammar.c" /* yacc.c:1646  */
+#line 1587 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 16:
-#line 323 "hex_grammar.y" /* yacc.c:1646  */
+#line 336 "hex_grammar.y" /* yacc.c:1661  */
     {
         if (lex_env->inside_or)
         {
@@ -1590,21 +1603,22 @@ yyreduce:
         (yyval.re_node)->start = 0;
         (yyval.re_node)->end = INT_MAX;
       }
-#line 1594 "hex_grammar.c" /* yacc.c:1646  */
+#line 1607 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 17:
-#line 343 "hex_grammar.y" /* yacc.c:1646  */
+#line 356 "hex_grammar.y" /* yacc.c:1661  */
     {
           (yyval.re_node) = (yyvsp[0].re_node);
       }
-#line 1602 "hex_grammar.c" /* yacc.c:1646  */
+#line 1615 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 18:
-#line 347 "hex_grammar.y" /* yacc.c:1646  */
+#line 360 "hex_grammar.y" /* yacc.c:1661  */
     {
         mark_as_not_fast_regexp();
+        incr_ast_levels();
 
         (yyval.re_node) = yr_re_node_create(RE_NODE_ALT, (yyvsp[-2].re_node), (yyvsp[0].re_node));
 
@@ -1613,11 +1627,11 @@ yyreduce:
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1617 "hex_grammar.c" /* yacc.c:1646  */
+#line 1631 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 19:
-#line 361 "hex_grammar.y" /* yacc.c:1646  */
+#line 375 "hex_grammar.y" /* yacc.c:1661  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_LITERAL, NULL, NULL);
 
@@ -1625,11 +1639,11 @@ yyreduce:
 
         (yyval.re_node)->value = (int) (yyvsp[0].integer);
       }
-#line 1629 "hex_grammar.c" /* yacc.c:1646  */
+#line 1643 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
   case 20:
-#line 369 "hex_grammar.y" /* yacc.c:1646  */
+#line 383 "hex_grammar.y" /* yacc.c:1661  */
     {
         uint8_t mask = (uint8_t) ((yyvsp[0].integer) >> 8);
 
@@ -1649,11 +1663,11 @@ yyreduce:
           (yyval.re_node)->mask = mask;
         }
       }
-#line 1653 "hex_grammar.c" /* yacc.c:1646  */
+#line 1667 "hex_grammar.c" /* yacc.c:1661  */
     break;
 
 
-#line 1657 "hex_grammar.c" /* yacc.c:1646  */
+#line 1671 "hex_grammar.c" /* yacc.c:1661  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1881,5 +1895,5 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 390 "hex_grammar.y" /* yacc.c:1906  */
+#line 404 "hex_grammar.y" /* yacc.c:1906  */
 
diff --git a/libyara/hex_grammar.h b/libyara/hex_grammar.h
index 31e7fe2..d37c164 100644
--- a/libyara/hex_grammar.h
+++ b/libyara/hex_grammar.h
@@ -60,12 +60,12 @@ extern int hex_yydebug;
 
 union YYSTYPE
 {
-#line 78 "hex_grammar.y" /* yacc.c:1909  */
+#line 85 "hex_grammar.y" /* yacc.c:1915  */
 
   int64_t integer;
   RE_NODE *re_node;
 
-#line 69 "hex_grammar.h" /* yacc.c:1909  */
+#line 69 "hex_grammar.h" /* yacc.c:1915  */
 };
 
 typedef union YYSTYPE YYSTYPE;
diff --git a/libyara/hex_grammar.y b/libyara/hex_grammar.y
index f42e0b1..bf907e9 100644
--- a/libyara/hex_grammar.y
+++ b/libyara/hex_grammar.y
@@ -51,6 +51,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define mark_as_not_fast_regexp() \
     ((RE_AST*) yyget_extra(yyscanner))->flags &= ~RE_FLAGS_FAST_REGEXP
 
+#define incr_ast_levels() \
+    if (((RE_AST*) yyget_extra(yyscanner))->levels++ > RE_MAX_AST_LEVELS) \
+    { \
+      lex_env->last_error_code = ERROR_INVALID_HEX_STRING; \
+      YYABORT; \
+    }
+
 #define ERROR_IF(x, error) \
     if (x) \
     { \
@@ -117,6 +124,8 @@ tokens
       }
     | token token
       {
+        incr_ast_levels();
+
         $$ = yr_re_node_create(RE_NODE_CONCAT, $1, $2);
 
         DESTROY_NODE_IF($$ == NULL, $1);
@@ -130,6 +139,8 @@ tokens
         RE_NODE* leftmost_concat = NULL;
         RE_NODE* leftmost_node = $2;
 
+        incr_ast_levels();
+
         $$ = NULL;
 
         /*
@@ -192,6 +203,8 @@ token_sequence
       }
     | token_sequence token_or_range
       {
+        incr_ast_levels();
+
         $$ = yr_re_node_create(RE_NODE_CONCAT, $1, $2);
 
         DESTROY_NODE_IF($$ == NULL, $1);
@@ -346,6 +359,7 @@ alternatives
     | alternatives '|' tokens
       {
         mark_as_not_fast_regexp();
+        incr_ast_levels();
 
         $$ = yr_re_node_create(RE_NODE_ALT, $1, $3);
 
diff --git a/libyara/include/yara/libyara.h b/libyara/include/yara/libyara.h
index 1da61e5..c0b2d00 100644
--- a/libyara/include/yara/libyara.h
+++ b/libyara/include/yara/libyara.h
@@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define YR_MAJOR_VERSION   3
 #define YR_MINOR_VERSION   6
-#define YR_MICRO_VERSION   0
+#define YR_MICRO_VERSION   1
 
 #define version_str(s) _version_str(s)
 #define _version_str(s) #s
diff --git a/libyara/include/yara/limits.h b/libyara/include/yara/limits.h
index af30d55..ae4d1ac 100644
--- a/libyara/include/yara/limits.h
+++ b/libyara/include/yara/limits.h
@@ -65,4 +65,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define LEX_BUF_SIZE                    8192
 
 
+// Maximum allowed split ID, also limiting the number of split instructions
+// allowed in a regular expression. This number can't be increased
+// over 255 without changing RE_SPLIT_ID_TYPE.
+#define RE_MAX_SPLIT_ID                 128
+
+// Maximum stack size for regexp evaluation
+#define RE_MAX_STACK                    1024
+
+// Maximum code size for a compiled regexp
+#define RE_MAX_CODE_SIZE                32768
+
+// Maximum input size scanned by yr_re_exec
+#define RE_SCAN_LIMIT                   4096
+
+// Maximum number of fibers
+#define RE_MAX_FIBERS                   1024
+
+// Maximum number of levels in regexp's AST
+#define RE_MAX_AST_LEVELS               2000
+
 #endif
diff --git a/libyara/include/yara/re.h b/libyara/include/yara/re.h
index b421e9b..ebdb1fd 100644
--- a/libyara/include/yara/re.h
+++ b/libyara/include/yara/re.h
@@ -136,6 +136,7 @@ struct RE_NODE
 struct RE_AST
 {
   uint32_t flags;
+  uint16_t levels;
   RE_NODE* root_node;
 };
 
diff --git a/libyara/modules/magic.c b/libyara/modules/magic.c
index d0a14fa..cf5a2df 100644
--- a/libyara/modules/magic.c
+++ b/libyara/modules/magic.c
@@ -120,7 +120,9 @@ end_declarations;
 int module_initialize(
     YR_MODULE* module)
 {
-  for (int i = 0; i < MAX_THREADS; i++)
+  int i;
+
+  for (i = 0; i < MAX_THREADS; i++)
     magic_cookie[i] = NULL;
 
   return ERROR_SUCCESS;
@@ -130,7 +132,9 @@ int module_initialize(
 int module_finalize(
     YR_MODULE* module)
 {
-  for (int i = 0; i < MAX_THREADS; i++)
+  int i;
+
+  for (i = 0; i < MAX_THREADS; i++)
     if (magic_cookie[i] != NULL)
       magic_close(magic_cookie[i]);
 
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index 16c467e..93719c0 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -1421,16 +1421,18 @@ void pe_parse_header(
     section++;
   }
 
-  // An overlay is data appended to a PE file. Its location is RawData + RawOffset of the last
-  // section on the physical file
+  // An overlay is data appended to a PE file. Its location is at
+  // RawData + RawOffset of the last section on the physical file
   last_section_end = highest_sec_siz + highest_sec_ofs;
 
-  // This way "overlay" is set to UNDEFINED for files that do not have an overlay section
+  // "overlay.offset" is set to UNDEFINED for files that do not have an overlay
   if (last_section_end && (pe->data_size > last_section_end))
-  {
     set_integer(last_section_end, pe->object, "overlay.offset");
+
+  // "overlay.size" is zero for well formed PE files that don not have an
+  // overlay and UNDEFINED for malformed PE files or non-PE files.
+  if (last_section_end && (pe->data_size >= last_section_end))
     set_integer(pe->data_size - last_section_end, pe->object, "overlay.size");
-  }
 }
 
 //
diff --git a/libyara/parser.c b/libyara/parser.c
index f20df7d..7e68457 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -118,8 +118,10 @@ int yr_parser_emit_with_arg_reloc(
   int64_t* ptr = NULL;
   int result;
 
-  DECLARE_REFERENCE(void*, argument) a;
-  a.argument = argument;
+  DECLARE_REFERENCE(void*, ptr) arg;
+
+  memset(&arg, 0, sizeof(arg));
+  arg.ptr = argument;
 
   result = yr_arena_write_data(
       yyget_extra(yyscanner)->code_arena,
@@ -130,8 +132,8 @@ int yr_parser_emit_with_arg_reloc(
   if (result == ERROR_SUCCESS)
     result = yr_arena_write_data(
         yyget_extra(yyscanner)->code_arena,
-        &a,
-        sizeof(int64_t),
+        &arg,
+        sizeof(arg),
         (void**) &ptr);
 
   if (result == ERROR_SUCCESS)
@@ -142,7 +144,7 @@ int yr_parser_emit_with_arg_reloc(
         EOL);
 
   if (argument_address != NULL)
-    *argument_address = (void*)ptr;
+    *argument_address = (void*) ptr;
 
   return result;
 }
diff --git a/libyara/re.c b/libyara/re.c
index de20324..959979b 100644
--- a/libyara/re.c
+++ b/libyara/re.c
@@ -52,23 +52,6 @@ order to avoid confusion with operating system threads.
 #include <yara/re_lexer.h>
 #include <yara/hex_lexer.h>
 
-// Maximum allowed split ID, also limiting the number of split instructions
-// allowed in a regular expression. This number can't be increased
-// over 255 without changing RE_SPLIT_ID_TYPE.
-#define RE_MAX_SPLIT_ID     128
-
-// Maximum stack size for regexp evaluation
-#define RE_MAX_STACK      1024
-
-// Maximum code size for a compiled regexp
-#define RE_MAX_CODE_SIZE  32768
-
-// Maximum input size scanned by yr_re_exec
-#define RE_SCAN_LIMIT     4096
-
-// Maximum number of fibers
-#define RE_MAX_FIBERS     1024
-
 
 #define EMIT_BACKWARDS                  0x01
 #define EMIT_DONT_SET_FORWARDS_CODE     0x02
@@ -268,6 +251,7 @@ int yr_re_ast_create(
     return ERROR_INSUFFICIENT_MEMORY;
 
   (*re_ast)->flags = 0;
+  (*re_ast)->levels = 0;
   (*re_ast)->root_node = NULL;
 
   return ERROR_SUCCESS;
diff --git a/libyara/re_grammar.c b/libyara/re_grammar.c
index 4122c7d..51839f6 100644
--- a/libyara/re_grammar.c
+++ b/libyara/re_grammar.c
@@ -88,6 +88,14 @@
 #define mark_as_not_fast_regexp() \
     ((RE_AST*) yyget_extra(yyscanner))->flags &= ~RE_FLAGS_FAST_REGEXP
 
+#define incr_ast_levels() \
+    if (((RE_AST*) yyget_extra(yyscanner))->levels++ > RE_MAX_AST_LEVELS) \
+    { \
+      lex_env->last_error_code = ERROR_INVALID_REGULAR_EXPRESSION; \
+      YYABORT; \
+    }
+
+
 #define ERROR_IF(x, error) \
     if (x) \
     { \
@@ -102,7 +110,7 @@
     } \
 
 
-#line 106 "re_grammar.c" /* yacc.c:339  */
+#line 114 "re_grammar.c" /* yacc.c:339  */
 
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -170,14 +178,14 @@ extern int re_yydebug;
 
 union YYSTYPE
 {
-#line 73 "re_grammar.y" /* yacc.c:355  */
+#line 81 "re_grammar.y" /* yacc.c:355  */
 
   int integer;
   uint32_t range;
   RE_NODE* re_node;
   uint8_t* class_vector;
 
-#line 181 "re_grammar.c" /* yacc.c:355  */
+#line 189 "re_grammar.c" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -193,7 +201,7 @@ int re_yyparse (void *yyscanner, RE_LEX_ENVIRONMENT *lex_env);
 
 /* Copy the second part of user declarations.  */
 
-#line 197 "re_grammar.c" /* yacc.c:358  */
+#line 205 "re_grammar.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -491,10 +499,10 @@ static const yytype_uint8 yytranslate[] =
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   104,   104,   109,   113,   117,   128,   146,   150,   161,
-     175,   191,   205,   221,   244,   268,   290,   313,   317,   323,
-     329,   335,   344,   348,   354,   362,   368,   374,   380,   386,
-     392,   398
+       0,   112,   112,   117,   121,   125,   137,   156,   160,   173,
+     187,   203,   217,   233,   256,   280,   302,   325,   329,   335,
+     341,   347,   356,   362,   368,   376,   382,   388,   394,   400,
+     406,   412
 };
 #endif
 
@@ -1039,33 +1047,33 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, void *yyscanner, R
   switch (yytype)
     {
           case 6: /* _CLASS_  */
-#line 96 "re_grammar.y" /* yacc.c:1257  */
+#line 104 "re_grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).class_vector)); }
-#line 1045 "re_grammar.c" /* yacc.c:1257  */
+#line 1053 "re_grammar.c" /* yacc.c:1257  */
         break;
 
     case 26: /* alternative  */
-#line 97 "re_grammar.y" /* yacc.c:1257  */
+#line 105 "re_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1051 "re_grammar.c" /* yacc.c:1257  */
+#line 1059 "re_grammar.c" /* yacc.c:1257  */
         break;
 
     case 27: /* concatenation  */
-#line 98 "re_grammar.y" /* yacc.c:1257  */
+#line 106 "re_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1057 "re_grammar.c" /* yacc.c:1257  */
+#line 1065 "re_grammar.c" /* yacc.c:1257  */
         break;
 
     case 28: /* repeat  */
-#line 99 "re_grammar.y" /* yacc.c:1257  */
+#line 107 "re_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1063 "re_grammar.c" /* yacc.c:1257  */
+#line 1071 "re_grammar.c" /* yacc.c:1257  */
         break;
 
     case 29: /* single  */
-#line 100 "re_grammar.y" /* yacc.c:1257  */
+#line 108 "re_grammar.y" /* yacc.c:1257  */
       { yr_re_node_destroy(((*yyvaluep).re_node)); }
-#line 1069 "re_grammar.c" /* yacc.c:1257  */
+#line 1077 "re_grammar.c" /* yacc.c:1257  */
         break;
 
 
@@ -1331,26 +1339,27 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 105 "re_grammar.y" /* yacc.c:1646  */
+#line 113 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast = yyget_extra(yyscanner);
         re_ast->root_node = (yyvsp[0].re_node);
       }
-#line 1340 "re_grammar.c" /* yacc.c:1646  */
+#line 1348 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 4:
-#line 114 "re_grammar.y" /* yacc.c:1646  */
+#line 122 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = (yyvsp[0].re_node);
       }
-#line 1348 "re_grammar.c" /* yacc.c:1646  */
+#line 1356 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 5:
-#line 118 "re_grammar.y" /* yacc.c:1646  */
+#line 126 "re_grammar.y" /* yacc.c:1646  */
     {
         mark_as_not_fast_regexp();
+        incr_ast_levels();
 
         (yyval.re_node) = yr_re_node_create(RE_NODE_ALT, (yyvsp[-2].re_node), (yyvsp[0].re_node));
 
@@ -1359,15 +1368,16 @@ yyreduce:
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1363 "re_grammar.c" /* yacc.c:1646  */
+#line 1372 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 6:
-#line 129 "re_grammar.y" /* yacc.c:1646  */
+#line 138 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_NODE* node;
 
         mark_as_not_fast_regexp();
+        incr_ast_levels();
 
         node = yr_re_node_create(RE_NODE_EMPTY, NULL, NULL);
 
@@ -1378,31 +1388,33 @@ yyreduce:
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1382 "re_grammar.c" /* yacc.c:1646  */
+#line 1392 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 7:
-#line 147 "re_grammar.y" /* yacc.c:1646  */
+#line 157 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = (yyvsp[0].re_node);
       }
-#line 1390 "re_grammar.c" /* yacc.c:1646  */
+#line 1400 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 8:
-#line 151 "re_grammar.y" /* yacc.c:1646  */
+#line 161 "re_grammar.y" /* yacc.c:1646  */
     {
+        incr_ast_levels();
+
         (yyval.re_node) = yr_re_node_create(RE_NODE_CONCAT, (yyvsp[-1].re_node), (yyvsp[0].re_node));
 
         DESTROY_NODE_IF((yyval.re_node) == NULL, (yyvsp[-1].re_node));
         DESTROY_NODE_IF((yyval.re_node) == NULL, (yyvsp[0].re_node));
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1402 "re_grammar.c" /* yacc.c:1646  */
+#line 1414 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 9:
-#line 162 "re_grammar.y" /* yacc.c:1646  */
+#line 174 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast;
 
@@ -1416,11 +1428,11 @@ yyreduce:
         DESTROY_NODE_IF((yyval.re_node) == NULL, (yyvsp[-1].re_node));
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1420 "re_grammar.c" /* yacc.c:1646  */
+#line 1432 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 10:
-#line 176 "re_grammar.y" /* yacc.c:1646  */
+#line 188 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast;
 
@@ -1436,11 +1448,11 @@ yyreduce:
 
         (yyval.re_node)->greedy = FALSE;
       }
-#line 1440 "re_grammar.c" /* yacc.c:1646  */
+#line 1452 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 11:
-#line 192 "re_grammar.y" /* yacc.c:1646  */
+#line 204 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast;
 
@@ -1454,11 +1466,11 @@ yyreduce:
         DESTROY_NODE_IF((yyval.re_node) == NULL, (yyvsp[-1].re_node));
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1458 "re_grammar.c" /* yacc.c:1646  */
+#line 1470 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 12:
-#line 206 "re_grammar.y" /* yacc.c:1646  */
+#line 218 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast;
 
@@ -1474,11 +1486,11 @@ yyreduce:
 
         (yyval.re_node)->greedy = FALSE;
       }
-#line 1478 "re_grammar.c" /* yacc.c:1646  */
+#line 1490 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 13:
-#line 222 "re_grammar.y" /* yacc.c:1646  */
+#line 234 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast = yyget_extra(yyscanner);
         re_ast->flags |= RE_FLAGS_GREEDY;
@@ -1501,11 +1513,11 @@ yyreduce:
         (yyval.re_node)->start = 0;
         (yyval.re_node)->end = 1;
       }
-#line 1505 "re_grammar.c" /* yacc.c:1646  */
+#line 1517 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 14:
-#line 245 "re_grammar.y" /* yacc.c:1646  */
+#line 257 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast = yyget_extra(yyscanner);
         re_ast->flags |= RE_FLAGS_UNGREEDY;
@@ -1529,11 +1541,11 @@ yyreduce:
         (yyval.re_node)->end = 1;
         (yyval.re_node)->greedy = FALSE;
       }
-#line 1533 "re_grammar.c" /* yacc.c:1646  */
+#line 1545 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 15:
-#line 269 "re_grammar.y" /* yacc.c:1646  */
+#line 281 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast = yyget_extra(yyscanner);
         re_ast->flags |= RE_FLAGS_GREEDY;
@@ -1555,11 +1567,11 @@ yyreduce:
         (yyval.re_node)->start = (yyvsp[0].range) & 0xFFFF;;
         (yyval.re_node)->end = (yyvsp[0].range) >> 16;;
       }
-#line 1559 "re_grammar.c" /* yacc.c:1646  */
+#line 1571 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 16:
-#line 291 "re_grammar.y" /* yacc.c:1646  */
+#line 303 "re_grammar.y" /* yacc.c:1646  */
     {
         RE_AST* re_ast = yyget_extra(yyscanner);
         re_ast->flags |= RE_FLAGS_UNGREEDY;
@@ -1582,77 +1594,79 @@ yyreduce:
         (yyval.re_node)->end = (yyvsp[-1].range) >> 16;;
         (yyval.re_node)->greedy = FALSE;
       }
-#line 1586 "re_grammar.c" /* yacc.c:1646  */
+#line 1598 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 17:
-#line 314 "re_grammar.y" /* yacc.c:1646  */
+#line 326 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = (yyvsp[0].re_node);
       }
-#line 1594 "re_grammar.c" /* yacc.c:1646  */
+#line 1606 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 18:
-#line 318 "re_grammar.y" /* yacc.c:1646  */
+#line 330 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_WORD_BOUNDARY, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1604 "re_grammar.c" /* yacc.c:1646  */
+#line 1616 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 19:
-#line 324 "re_grammar.y" /* yacc.c:1646  */
+#line 336 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_NON_WORD_BOUNDARY, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1614 "re_grammar.c" /* yacc.c:1646  */
+#line 1626 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 20:
-#line 330 "re_grammar.y" /* yacc.c:1646  */
+#line 342 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_ANCHOR_START, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1624 "re_grammar.c" /* yacc.c:1646  */
+#line 1636 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 21:
-#line 336 "re_grammar.y" /* yacc.c:1646  */
+#line 348 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_ANCHOR_END, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1634 "re_grammar.c" /* yacc.c:1646  */
+#line 1646 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 22:
-#line 345 "re_grammar.y" /* yacc.c:1646  */
+#line 357 "re_grammar.y" /* yacc.c:1646  */
     {
+        incr_ast_levels();
+
         (yyval.re_node) = (yyvsp[-1].re_node);
       }
-#line 1642 "re_grammar.c" /* yacc.c:1646  */
+#line 1656 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 23:
-#line 349 "re_grammar.y" /* yacc.c:1646  */
+#line 363 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_ANY, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1652 "re_grammar.c" /* yacc.c:1646  */
+#line 1666 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 24:
-#line 355 "re_grammar.y" /* yacc.c:1646  */
+#line 369 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_LITERAL, NULL, NULL);
 
@@ -1660,71 +1674,71 @@ yyreduce:
 
         (yyval.re_node)->value = (yyvsp[0].integer);
       }
-#line 1664 "re_grammar.c" /* yacc.c:1646  */
+#line 1678 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 25:
-#line 363 "re_grammar.y" /* yacc.c:1646  */
+#line 377 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_WORD_CHAR, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1674 "re_grammar.c" /* yacc.c:1646  */
+#line 1688 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 26:
-#line 369 "re_grammar.y" /* yacc.c:1646  */
+#line 383 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_NON_WORD_CHAR, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1684 "re_grammar.c" /* yacc.c:1646  */
+#line 1698 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 27:
-#line 375 "re_grammar.y" /* yacc.c:1646  */
+#line 389 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_SPACE, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1694 "re_grammar.c" /* yacc.c:1646  */
+#line 1708 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 28:
-#line 381 "re_grammar.y" /* yacc.c:1646  */
+#line 395 "re_grammar.y" /* yacc.c:1646  */
     {
          (yyval.re_node) = yr_re_node_create(RE_NODE_NON_SPACE, NULL, NULL);
 
          ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1704 "re_grammar.c" /* yacc.c:1646  */
+#line 1718 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 29:
-#line 387 "re_grammar.y" /* yacc.c:1646  */
+#line 401 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_DIGIT, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1714 "re_grammar.c" /* yacc.c:1646  */
+#line 1728 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 30:
-#line 393 "re_grammar.y" /* yacc.c:1646  */
+#line 407 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_NON_DIGIT, NULL, NULL);
 
         ERROR_IF((yyval.re_node) == NULL, ERROR_INSUFFICIENT_MEMORY);
       }
-#line 1724 "re_grammar.c" /* yacc.c:1646  */
+#line 1738 "re_grammar.c" /* yacc.c:1646  */
     break;
 
   case 31:
-#line 399 "re_grammar.y" /* yacc.c:1646  */
+#line 413 "re_grammar.y" /* yacc.c:1646  */
     {
         (yyval.re_node) = yr_re_node_create(RE_NODE_CLASS, NULL, NULL);
 
@@ -1732,11 +1746,11 @@ yyreduce:
 
         (yyval.re_node)->class_vector = (yyvsp[0].class_vector);
       }
-#line 1736 "re_grammar.c" /* yacc.c:1646  */
+#line 1750 "re_grammar.c" /* yacc.c:1646  */
     break;
 
 
-#line 1740 "re_grammar.c" /* yacc.c:1646  */
+#line 1754 "re_grammar.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1964,5 +1978,5 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 407 "re_grammar.y" /* yacc.c:1906  */
+#line 421 "re_grammar.y" /* yacc.c:1906  */
 
diff --git a/libyara/re_grammar.h b/libyara/re_grammar.h
index c673bd1..8ba1c56 100644
--- a/libyara/re_grammar.h
+++ b/libyara/re_grammar.h
@@ -78,7 +78,7 @@ extern int re_yydebug;
 
 union YYSTYPE
 {
-#line 73 "re_grammar.y" /* yacc.c:1909  */
+#line 81 "re_grammar.y" /* yacc.c:1909  */
 
   int integer;
   uint32_t range;
diff --git a/libyara/re_grammar.y b/libyara/re_grammar.y
index 9a22b44..9e88d24 100644
--- a/libyara/re_grammar.y
+++ b/libyara/re_grammar.y
@@ -46,6 +46,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define mark_as_not_fast_regexp() \
     ((RE_AST*) yyget_extra(yyscanner))->flags &= ~RE_FLAGS_FAST_REGEXP
 
+#define incr_ast_levels() \
+    if (((RE_AST*) yyget_extra(yyscanner))->levels++ > RE_MAX_AST_LEVELS) \
+    { \
+      lex_env->last_error_code = ERROR_INVALID_REGULAR_EXPRESSION; \
+      YYABORT; \
+    }
+
+
 #define ERROR_IF(x, error) \
     if (x) \
     { \
@@ -117,6 +125,7 @@ alternative
     | alternative '|' concatenation
       {
         mark_as_not_fast_regexp();
+        incr_ast_levels();
 
         $$ = yr_re_node_create(RE_NODE_ALT, $1, $3);
 
@@ -130,6 +139,7 @@ alternative
         RE_NODE* node;
 
         mark_as_not_fast_regexp();
+        incr_ast_levels();
 
         node = yr_re_node_create(RE_NODE_EMPTY, NULL, NULL);
 
@@ -149,6 +159,8 @@ concatenation
       }
     | concatenation repeat
       {
+        incr_ast_levels();
+
         $$ = yr_re_node_create(RE_NODE_CONCAT, $1, $2);
 
         DESTROY_NODE_IF($$ == NULL, $1);
@@ -343,6 +355,8 @@ repeat
 single
     : '(' alternative ')'
       {
+        incr_ast_levels();
+
         $$ = $2;
       }
     | '.'
diff --git a/tests/data/tiny-overlay b/tests/data/tiny-overlay
new file mode 100644
index 0000000..25fc362
Binary files /dev/null and b/tests/data/tiny-overlay differ
diff --git a/tests/test-pe.c b/tests/test-pe.c
index 0cad10a..04873ed 100644
--- a/tests/test-pe.c
+++ b/tests/test-pe.c
@@ -127,6 +127,22 @@ int main(int argc, char** argv)
       }",
       "tests/data/tiny");
 
+  assert_true_rule_file(
+      "import \"pe\" \
+      rule test { \
+        condition: \
+          pe.overlay.offset == 0x8000 and pe.overlay.size == 7 \
+      }",
+      "tests/data/tiny-overlay");
+
+  assert_true_rule_file(
+      "import \"pe\" \
+      rule test { \
+        condition: \
+         pe.overlay.size == 0 \
+      }",
+      "tests/data/tiny");
+
   assert_false_rule_file(
       "import \"pe\" \
       rule test { \

-- 
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