We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
sigmac - invalid value in STATE filter
In specification it states that there are three statuses:
* stable
*  test
* experimental 
https://github.com/SigmaHQ/sigma/wiki/Specification#status-optional

Problem arises when  using sigmac with filter option and trying to filter out status **test**, because in filter options it states that status is one of these values: experimental, testing, stable.
Specification says **test**, but filter looks for status **testing**.
```
--filter FILTER, -f FILTER
                        Define comma-separated filters that must match (AND-
                        linked) to rule to be processed. Valid filters:
                        level<=x, level>=x, level=x, status=y, logsource=z,
                        tag=t. x is one of: low, medium, high, critical. y is
                        one of: experimental, testing, stable. z is a word
                        appearing in an arbitrary log source attribute. t is a
                        tag that must appear in the rules tag list, case-
                        insensitive matching. Multiple log source
                        specifications are AND linked.
                        

```

sigma-master\tools\sigma\filter.py
`line 27: STATES = ["experimental", "testing", "stable"] `

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tools/sigma/filter.py`
Content:
```
1 # Sigma parser
2 # Copyright 2016-2018 Thomas Patzke, Florian Roth
3 
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Lesser General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Lesser General Public License for more details.
13 
14 # You should have received a copy of the GNU Lesser General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 # Rule Filtering
18 import datetime
19 class SigmaRuleFilter:
20     """Filter for Sigma rules with conditions"""
21     LEVELS = {
22             "low"      : 0,
23             "medium"   : 1,
24             "high"     : 2,
25             "critical" : 3
26             }
27     STATES = ["experimental", "testing", "stable"]
28 
29     def __init__(self, expr):
30         self.minlevel      = None
31         self.maxlevel      = None
32         self.status        = None
33         self.tlp           = None
34         self.target        = None
35         self.logsources    = list()
36         self.notlogsources = list()
37         self.tags          = list()
38         self.nottags       = list()
39         self.inlastday     = None
40         self.condition     = list()
41         self.notcondition  = list()
42 
43         for cond in [c.replace(" ", "") for c in expr.split(",")]:
44             if cond.startswith("level<="):
45                 try:
46                     level = cond[cond.index("=") + 1:]
47                     self.maxlevel = self.LEVELS[level]
48                 except KeyError as e:
49                     raise SigmaRuleFilterParseException("Unknown level '%s' in condition '%s'" % (level, cond)) from e
50             elif cond.startswith("level>="):
51                 try:
52                     level = cond[cond.index("=") + 1:]
53                     self.minlevel = self.LEVELS[level]
54                 except KeyError as e:
55                     raise SigmaRuleFilterParseException("Unknown level '%s' in condition '%s'" % (level, cond)) from e
56             elif cond.startswith("level="):
57                 try:
58                     level = cond[cond.index("=") + 1:]
59                     self.minlevel = self.LEVELS[level]
60                     self.maxlevel = self.minlevel
61                 except KeyError as e:
62                     raise SigmaRuleFilterParseException("Unknown level '%s' in condition '%s'" % (level, cond)) from e
63             elif cond.startswith("status="):
64                 self.status = cond[cond.index("=") + 1:]
65                 if self.status not in self.STATES:
66                     raise SigmaRuleFilterParseException("Unknown status '%s' in condition '%s'" % (self.status, cond))
67             elif cond.startswith("tlp="):
68                 self.tlp = cond[cond.index("=") + 1:].upper()  #tlp is always uppercase
69             elif cond.startswith("target="):
70                 self.target = cond[cond.index("=") + 1:].lower() # lower to make caseinsensitive
71             elif cond.startswith("logsource="):
72                 self.logsources.append(cond[cond.index("=") + 1:])
73             elif cond.startswith("logsource!="):
74                 self.notlogsources.append(cond[cond.index("=") + 1:])
75             elif cond.startswith("tag="):
76                 self.tags.append(cond[cond.index("=") + 1:].lower())
77             elif cond.startswith("tag!="):
78                 self.nottags.append(cond[cond.index("=") + 1:].lower())
79             elif cond.startswith("condition="):
80                 self.condition.append(cond[cond.index("=") + 1:].lower())
81             elif cond.startswith("condition!="):
82                 self.notcondition.append(cond[cond.index("=") + 1:].lower())
83             elif cond.startswith("inlastday="):
84                 nbday = cond[cond.index("=") + 1:]
85                 try:
86                     self.inlastday = int(nbday)
87                 except ValueError as e:
88                     raise SigmaRuleFilterParseException("Unknown number '%s' in condition '%s'" % (nbday, cond)) from e
89             else:
90                 raise SigmaRuleFilterParseException("Unknown condition '%s'" % cond)
91 
92     def match(self, yamldoc):
93         """Match filter conditions against rule"""
94         # Levels
95         if self.minlevel is not None or self.maxlevel is not None:
96             try:
97                 level = self.LEVELS[yamldoc['level']]
98             except KeyError:    # missing or invalid level
99                 return False    # User wants level restriction, but it's not possible here
100 
101             # Minimum level
102             if self.minlevel is not None:
103                 if level < self.minlevel:
104                     return False
105             # Maximum level
106             if self.maxlevel is not None:
107                 if level > self.maxlevel:
108                     return False
109 
110         # Status
111         if self.status is not None:
112             try:
113                 status = yamldoc['status']
114             except KeyError:    # missing status
115                 return False    # User wants status restriction, but it's not possible here
116             if status != self.status:
117                 return False
118 
119         # Tlp
120         if self.tlp is not None:
121             try:
122                 tlp = yamldoc['tlp']
123             except KeyError:    # missing tlp
124                 tlp = "WHITE"    # tlp is WHITE by default
125             if tlp != self.tlp:
126                 return False
127 
128         #Target
129         if self.target:
130             try:
131                 targets = [ target.lower() for target in yamldoc['target']]
132             except (KeyError, AttributeError):    # no target set
133                 return False
134             if self.target not in targets:
135                 return False
136 
137         # Log Sources
138         if self.logsources:
139             try:
140                 logsources = { value for key, value in yamldoc['logsource'].items() }
141             except (KeyError, AttributeError):    # no log source set
142                 return False    # User wants status restriction, but it's not possible here
143 
144             for logsrc in self.logsources:
145                 if logsrc not in logsources:
146                     return False
147 
148         # NOT Log Sources
149         if self.notlogsources:
150             try:
151                 notlogsources = { value for key, value in yamldoc['logsource'].items() }
152             except (KeyError, AttributeError):    # no log source set
153                 return False    # User wants status restriction, but it's not possible here
154 
155             for logsrc in self.notlogsources:
156                 if logsrc  in notlogsources:
157                     return False
158 
159         # Tags
160         if self.tags:
161             try:
162                 tags = [ tag.lower() for tag in yamldoc['tags']]
163             except (KeyError, AttributeError):    # no tags set
164                 return False
165 
166             for tag in self.tags:
167                 if tag not in tags:
168                     return False
169         # NOT Tags
170         if self.nottags:
171             try:
172                 nottags = [ tag.lower() for tag in yamldoc['tags']]
173             except (KeyError, AttributeError):    # no tags set
174                 return False
175 
176             for tag in self.nottags:
177                 if tag in nottags:
178                     return False
179 
180         # date in the last N days
181         if self.inlastday:
182            try:
183                date_str = yamldoc['date']
184            except KeyError:    # missing date
185                return False    # User wants date time restriction, but it's not possible here
186 
187            try:
188                modified_str = yamldoc['modified']
189            except KeyError:    # no update
190                modified_str = None
191            if modified_str:
192                date_str = modified_str
193 
194            date_object = datetime.datetime.strptime(date_str, '%Y/%m/%d')
195            today_objet = datetime.datetime.now()
196            delta       = today_objet - date_object
197            if delta.days > self.inlastday:
198                 return False
199 
200         if self.condition:
201             try:
202                 conditions = yamldoc['detection']['condition']
203                 if isinstance(conditions,list):                         # sone time conditions are list even with only 1 line
204                     s_condition = ' '.join(conditions)
205                 else:
206                     s_condition = conditions
207             except KeyError:    # missing condition
208                 return False    # User wants condition restriction, but it's not possible here
209             for val in self.condition:
210                 if not val in s_condition:
211                     return False
212 
213         if self.notcondition:
214             try:
215                 conditions = yamldoc['detection']['condition']
216                 if isinstance(conditions,list):                         # sone time conditions are list even with only 1 line
217                     s_condition = ' '.join(conditions)
218                 else:
219                     s_condition = conditions
220             except KeyError:    # missing condition
221                 return False    # User wants condition restriction, but it's not possible here
222             for val in self.notcondition:
223                 if val in s_condition:
224                     return False
225 
226         # all tests passed
227         return True
228 
229 class SigmaRuleFilterParseException(Exception):
230     pass
231
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/tools/sigma/filter.py b/tools/sigma/filter.py
--- a/tools/sigma/filter.py
+++ b/tools/sigma/filter.py
@@ -24,7 +24,9 @@
             "high"     : 2,
             "critical" : 3
             }
-    STATES = ["experimental", "testing", "stable"]
+    STATES = ["experimental",
+              "test",
+              "stable"]
 
     def __init__(self, expr):
         self.minlevel      = None

{"golden_diff": "diff --git a/tools/sigma/filter.py b/tools/sigma/filter.py\n--- a/tools/sigma/filter.py\n+++ b/tools/sigma/filter.py\n@@ -24,7 +24,9 @@\n             \"high\"     : 2,\n             \"critical\" : 3\n             }\n-    STATES = [\"experimental\", \"testing\", \"stable\"]\n+    STATES = [\"experimental\",\n+              \"test\",\n+              \"stable\"]\n \n     def __init__(self, expr):\n         self.minlevel      = None\n", "issue": "sigmac - invalid value in STATE filter\nIn specification it states that there are three statuses:\r\n* stable\r\n*  test\r\n* experimental \r\nhttps://github.com/SigmaHQ/sigma/wiki/Specification#status-optional\r\n\r\nProblem arises when  using sigmac with filter option and trying to filter out status **test**, because in filter options it states that status is one of these values: experimental, testing, stable.\r\nSpecification says **test**, but filter looks for status **testing**.\r\n```\r\n--filter FILTER, -f FILTER\r\n                        Define comma-separated filters that must match (AND-\r\n                        linked) to rule to be processed. Valid filters:\r\n                        level<=x, level>=x, level=x, status=y, logsource=z,\r\n                        tag=t. x is one of: low, medium, high, critical. y is\r\n                        one of: experimental, testing, stable. z is a word\r\n                        appearing in an arbitrary log source attribute. t is a\r\n                        tag that must appear in the rules tag list, case-\r\n                        insensitive matching. Multiple log source\r\n                        specifications are AND linked.\r\n                        \r\n\r\n```\r\n\r\nsigma-master\\tools\\sigma\\filter.py\r\n`line 27: STATES = [\"experimental\", \"testing\", \"stable\"] `\n", "before_files": [{"content": "# Sigma parser\n# Copyright 2016-2018 Thomas Patzke, Florian Roth\n\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser General Public License for more details.\n\n# You should have received a copy of the GNU Lesser General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n# Rule Filtering\nimport datetime\nclass SigmaRuleFilter:\n    \"\"\"Filter for Sigma rules with conditions\"\"\"\n    LEVELS = {\n            \"low\"      : 0,\n            \"medium\"   : 1,\n            \"high\"     : 2,\n            \"critical\" : 3\n            }\n    STATES = [\"experimental\", \"testing\", \"stable\"]\n\n    def __init__(self, expr):\n        self.minlevel      = None\n        self.maxlevel      = None\n        self.status        = None\n        self.tlp           = None\n        self.target        = None\n        self.logsources    = list()\n        self.notlogsources = list()\n        self.tags          = list()\n        self.nottags       = list()\n        self.inlastday     = None\n        self.condition     = list()\n        self.notcondition  = list()\n\n        for cond in [c.replace(\" \", \"\") for c in expr.split(\",\")]:\n            if cond.startswith(\"level<=\"):\n                try:\n                    level = cond[cond.index(\"=\") + 1:]\n                    self.maxlevel = self.LEVELS[level]\n                except KeyError as e:\n                    raise SigmaRuleFilterParseException(\"Unknown level '%s' in condition '%s'\" % (level, cond)) from e\n            elif cond.startswith(\"level>=\"):\n                try:\n                    level = cond[cond.index(\"=\") + 1:]\n                    self.minlevel = self.LEVELS[level]\n                except KeyError as e:\n                    raise SigmaRuleFilterParseException(\"Unknown level '%s' in condition '%s'\" % (level, cond)) from e\n            elif cond.startswith(\"level=\"):\n                try:\n                    level = cond[cond.index(\"=\") + 1:]\n                    self.minlevel = self.LEVELS[level]\n                    self.maxlevel = self.minlevel\n                except KeyError as e:\n                    raise SigmaRuleFilterParseException(\"Unknown level '%s' in condition '%s'\" % (level, cond)) from e\n            elif cond.startswith(\"status=\"):\n                self.status = cond[cond.index(\"=\") + 1:]\n                if self.status not in self.STATES:\n                    raise SigmaRuleFilterParseException(\"Unknown status '%s' in condition '%s'\" % (self.status, cond))\n            elif cond.startswith(\"tlp=\"):\n                self.tlp = cond[cond.index(\"=\") + 1:].upper()  #tlp is always uppercase\n            elif cond.startswith(\"target=\"):\n                self.target = cond[cond.index(\"=\") + 1:].lower() # lower to make caseinsensitive\n            elif cond.startswith(\"logsource=\"):\n                self.logsources.append(cond[cond.index(\"=\") + 1:])\n            elif cond.startswith(\"logsource!=\"):\n                self.notlogsources.append(cond[cond.index(\"=\") + 1:])\n            elif cond.startswith(\"tag=\"):\n                self.tags.append(cond[cond.index(\"=\") + 1:].lower())\n            elif cond.startswith(\"tag!=\"):\n                self.nottags.append(cond[cond.index(\"=\") + 1:].lower())\n            elif cond.startswith(\"condition=\"):\n                self.condition.append(cond[cond.index(\"=\") + 1:].lower())\n            elif cond.startswith(\"condition!=\"):\n                self.notcondition.append(cond[cond.index(\"=\") + 1:].lower())\n            elif cond.startswith(\"inlastday=\"):\n                nbday = cond[cond.index(\"=\") + 1:]\n                try:\n                    self.inlastday = int(nbday)\n                except ValueError as e:\n                    raise SigmaRuleFilterParseException(\"Unknown number '%s' in condition '%s'\" % (nbday, cond)) from e\n            else:\n                raise SigmaRuleFilterParseException(\"Unknown condition '%s'\" % cond)\n\n    def match(self, yamldoc):\n        \"\"\"Match filter conditions against rule\"\"\"\n        # Levels\n        if self.minlevel is not None or self.maxlevel is not None:\n            try:\n                level = self.LEVELS[yamldoc['level']]\n            except KeyError:    # missing or invalid level\n                return False    # User wants level restriction, but it's not possible here\n\n            # Minimum level\n            if self.minlevel is not None:\n                if level < self.minlevel:\n                    return False\n            # Maximum level\n            if self.maxlevel is not None:\n                if level > self.maxlevel:\n                    return False\n\n        # Status\n        if self.status is not None:\n            try:\n                status = yamldoc['status']\n            except KeyError:    # missing status\n                return False    # User wants status restriction, but it's not possible here\n            if status != self.status:\n                return False\n\n        # Tlp\n        if self.tlp is not None:\n            try:\n                tlp = yamldoc['tlp']\n            except KeyError:    # missing tlp\n                tlp = \"WHITE\"    # tlp is WHITE by default\n            if tlp != self.tlp:\n                return False\n\n        #Target\n        if self.target:\n            try:\n                targets = [ target.lower() for target in yamldoc['target']]\n            except (KeyError, AttributeError):    # no target set\n                return False\n            if self.target not in targets:\n                return False\n\n        # Log Sources\n        if self.logsources:\n            try:\n                logsources = { value for key, value in yamldoc['logsource'].items() }\n            except (KeyError, AttributeError):    # no log source set\n                return False    # User wants status restriction, but it's not possible here\n\n            for logsrc in self.logsources:\n                if logsrc not in logsources:\n                    return False\n\n        # NOT Log Sources\n        if self.notlogsources:\n            try:\n                notlogsources = { value for key, value in yamldoc['logsource'].items() }\n            except (KeyError, AttributeError):    # no log source set\n                return False    # User wants status restriction, but it's not possible here\n\n            for logsrc in self.notlogsources:\n                if logsrc  in notlogsources:\n                    return False\n\n        # Tags\n        if self.tags:\n            try:\n                tags = [ tag.lower() for tag in yamldoc['tags']]\n            except (KeyError, AttributeError):    # no tags set\n                return False\n\n            for tag in self.tags:\n                if tag not in tags:\n                    return False\n        # NOT Tags\n        if self.nottags:\n            try:\n                nottags = [ tag.lower() for tag in yamldoc['tags']]\n            except (KeyError, AttributeError):    # no tags set\n                return False\n\n            for tag in self.nottags:\n                if tag in nottags:\n                    return False\n\n        # date in the last N days\n        if self.inlastday:\n           try:\n               date_str = yamldoc['date']\n           except KeyError:    # missing date\n               return False    # User wants date time restriction, but it's not possible here\n\n           try:\n               modified_str = yamldoc['modified']\n           except KeyError:    # no update\n               modified_str = None\n           if modified_str:\n               date_str = modified_str\n\n           date_object = datetime.datetime.strptime(date_str, '%Y/%m/%d')\n           today_objet = datetime.datetime.now()\n           delta       = today_objet - date_object\n           if delta.days > self.inlastday:\n                return False\n\n        if self.condition:\n            try:\n                conditions = yamldoc['detection']['condition']\n                if isinstance(conditions,list):                         # sone time conditions are list even with only 1 line\n                    s_condition = ' '.join(conditions)\n                else:\n                    s_condition = conditions\n            except KeyError:    # missing condition\n                return False    # User wants condition restriction, but it's not possible here\n            for val in self.condition:\n                if not val in s_condition:\n                    return False\n\n        if self.notcondition:\n            try:\n                conditions = yamldoc['detection']['condition']\n                if isinstance(conditions,list):                         # sone time conditions are list even with only 1 line\n                    s_condition = ' '.join(conditions)\n                else:\n                    s_condition = conditions\n            except KeyError:    # missing condition\n                return False    # User wants condition restriction, but it's not possible here\n            for val in self.notcondition:\n                if val in s_condition:\n                    return False\n\n        # all tests passed\n        return True\n\nclass SigmaRuleFilterParseException(Exception):\n    pass\n", "path": "tools/sigma/filter.py"}], "after_files": [{"content": "# Sigma parser\n# Copyright 2016-2018 Thomas Patzke, Florian Roth\n\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser General Public License for more details.\n\n# You should have received a copy of the GNU Lesser General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n# Rule Filtering\nimport datetime\nclass SigmaRuleFilter:\n    \"\"\"Filter for Sigma rules with conditions\"\"\"\n    LEVELS = {\n            \"low\"      : 0,\n            \"medium\"   : 1,\n            \"high\"     : 2,\n            \"critical\" : 3\n            }\n    STATES = [\"experimental\",\n              \"test\",\n              \"stable\"]\n\n    def __init__(self, expr):\n        self.minlevel      = None\n        self.maxlevel      = None\n        self.status        = None\n        self.tlp           = None\n        self.target        = None\n        self.logsources    = list()\n        self.notlogsources = list()\n        self.tags          = list()\n        self.nottags       = list()\n        self.inlastday     = None\n        self.condition     = list()\n        self.notcondition  = list()\n\n        for cond in [c.replace(\" \", \"\") for c in expr.split(\",\")]:\n            if cond.startswith(\"level<=\"):\n                try:\n                    level = cond[cond.index(\"=\") + 1:]\n                    self.maxlevel = self.LEVELS[level]\n                except KeyError as e:\n                    raise SigmaRuleFilterParseException(\"Unknown level '%s' in condition '%s'\" % (level, cond)) from e\n            elif cond.startswith(\"level>=\"):\n                try:\n                    level = cond[cond.index(\"=\") + 1:]\n                    self.minlevel = self.LEVELS[level]\n                except KeyError as e:\n                    raise SigmaRuleFilterParseException(\"Unknown level '%s' in condition '%s'\" % (level, cond)) from e\n            elif cond.startswith(\"level=\"):\n                try:\n                    level = cond[cond.index(\"=\") + 1:]\n                    self.minlevel = self.LEVELS[level]\n                    self.maxlevel = self.minlevel\n                except KeyError as e:\n                    raise SigmaRuleFilterParseException(\"Unknown level '%s' in condition '%s'\" % (level, cond)) from e\n            elif cond.startswith(\"status=\"):\n                self.status = cond[cond.index(\"=\") + 1:]\n                if self.status not in self.STATES:\n                    raise SigmaRuleFilterParseException(\"Unknown status '%s' in condition '%s'\" % (self.status, cond))\n            elif cond.startswith(\"tlp=\"):\n                self.tlp = cond[cond.index(\"=\") + 1:].upper()  #tlp is always uppercase\n            elif cond.startswith(\"target=\"):\n                self.target = cond[cond.index(\"=\") + 1:].lower() # lower to make caseinsensitive\n            elif cond.startswith(\"logsource=\"):\n                self.logsources.append(cond[cond.index(\"=\") + 1:])\n            elif cond.startswith(\"logsource!=\"):\n                self.notlogsources.append(cond[cond.index(\"=\") + 1:])\n            elif cond.startswith(\"tag=\"):\n                self.tags.append(cond[cond.index(\"=\") + 1:].lower())\n            elif cond.startswith(\"tag!=\"):\n                self.nottags.append(cond[cond.index(\"=\") + 1:].lower())\n            elif cond.startswith(\"condition=\"):\n                self.condition.append(cond[cond.index(\"=\") + 1:].lower())\n            elif cond.startswith(\"condition!=\"):\n                self.notcondition.append(cond[cond.index(\"=\") + 1:].lower())\n            elif cond.startswith(\"inlastday=\"):\n                nbday = cond[cond.index(\"=\") + 1:]\n                try:\n                    self.inlastday = int(nbday)\n                except ValueError as e:\n                    raise SigmaRuleFilterParseException(\"Unknown number '%s' in condition '%s'\" % (nbday, cond)) from e\n            else:\n                raise SigmaRuleFilterParseException(\"Unknown condition '%s'\" % cond)\n\n    def match(self, yamldoc):\n        \"\"\"Match filter conditions against rule\"\"\"\n        # Levels\n        if self.minlevel is not None or self.maxlevel is not None:\n            try:\n                level = self.LEVELS[yamldoc['level']]\n            except KeyError:    # missing or invalid level\n                return False    # User wants level restriction, but it's not possible here\n\n            # Minimum level\n            if self.minlevel is not None:\n                if level < self.minlevel:\n                    return False\n            # Maximum level\n            if self.maxlevel is not None:\n                if level > self.maxlevel:\n                    return False\n\n        # Status\n        if self.status is not None:\n            try:\n                status = yamldoc['status']\n            except KeyError:    # missing status\n                return False    # User wants status restriction, but it's not possible here\n            if status != self.status:\n                return False\n\n        # Tlp\n        if self.tlp is not None:\n            try:\n                tlp = yamldoc['tlp']\n            except KeyError:    # missing tlp\n                tlp = \"WHITE\"    # tlp is WHITE by default\n            if tlp != self.tlp:\n                return False\n\n        #Target\n        if self.target:\n            try:\n                targets = [ target.lower() for target in yamldoc['target']]\n            except (KeyError, AttributeError):    # no target set\n                return False\n            if self.target not in targets:\n                return False\n\n        # Log Sources\n        if self.logsources:\n            try:\n                logsources = { value for key, value in yamldoc['logsource'].items() }\n            except (KeyError, AttributeError):    # no log source set\n                return False    # User wants status restriction, but it's not possible here\n\n            for logsrc in self.logsources:\n                if logsrc not in logsources:\n                    return False\n\n        # NOT Log Sources\n        if self.notlogsources:\n            try:\n                notlogsources = { value for key, value in yamldoc['logsource'].items() }\n            except (KeyError, AttributeError):    # no log source set\n                return False    # User wants status restriction, but it's not possible here\n\n            for logsrc in self.notlogsources:\n                if logsrc  in notlogsources:\n                    return False\n\n        # Tags\n        if self.tags:\n            try:\n                tags = [ tag.lower() for tag in yamldoc['tags']]\n            except (KeyError, AttributeError):    # no tags set\n                return False\n\n            for tag in self.tags:\n                if tag not in tags:\n                    return False\n        # NOT Tags\n        if self.nottags:\n            try:\n                nottags = [ tag.lower() for tag in yamldoc['tags']]\n            except (KeyError, AttributeError):    # no tags set\n                return False\n\n            for tag in self.nottags:\n                if tag in nottags:\n                    return False\n\n        # date in the last N days\n        if self.inlastday:\n           try:\n               date_str = yamldoc['date']\n           except KeyError:    # missing date\n               return False    # User wants date time restriction, but it's not possible here\n\n           try:\n               modified_str = yamldoc['modified']\n           except KeyError:    # no update\n               modified_str = None\n           if modified_str:\n               date_str = modified_str\n\n           date_object = datetime.datetime.strptime(date_str, '%Y/%m/%d')\n           today_objet = datetime.datetime.now()\n           delta       = today_objet - date_object\n           if delta.days > self.inlastday:\n                return False\n\n        if self.condition:\n            try:\n                conditions = yamldoc['detection']['condition']\n                if isinstance(conditions,list):                         # sone time conditions are list even with only 1 line\n                    s_condition = ' '.join(conditions)\n                else:\n                    s_condition = conditions\n            except KeyError:    # missing condition\n                return False    # User wants condition restriction, but it's not possible here\n            for val in self.condition:\n                if not val in s_condition:\n                    return False\n\n        if self.notcondition:\n            try:\n                conditions = yamldoc['detection']['condition']\n                if isinstance(conditions,list):                         # sone time conditions are list even with only 1 line\n                    s_condition = ' '.join(conditions)\n                else:\n                    s_condition = conditions\n            except KeyError:    # missing condition\n                return False    # User wants condition restriction, but it's not possible here\n            for val in self.notcondition:\n                if val in s_condition:\n                    return False\n\n        # all tests passed\n        return True\n\nclass SigmaRuleFilterParseException(Exception):\n    pass\n", "path": "tools/sigma/filter.py"}]}