22
22
from threading import Lock
23
23
from random import randbytes
24
24
from base64 import b64encode
25
+ from itertools import zip_longest
25
26
from tqdm import tqdm
26
27
27
28
@@ -111,9 +112,10 @@ def parse_patterns(patterns_dir: str, include: Optional[list[str]] = None, exclu
111
112
return patterns
112
113
113
114
114
- def hs_compile (db : hyperscan .Database , regex : Union [str | list [str ] | bytes | list [bytes ]]) -> bool :
115
+ def hs_compile (db : hyperscan .Database , regex : Union [str | list [str ] | bytes | list [bytes ]], labels : list [ str ] = None ) -> bool :
115
116
"""Compile one or more hyperscan regexes into the given database."""
116
117
regex_bytes : list [bytes ]
118
+ labels = labels if labels is not None else []
117
119
118
120
if isinstance (regex , str ):
119
121
regex_bytes = [regex .encode ('utf-8' )]
@@ -136,12 +138,12 @@ def hs_compile(db: hyperscan.Database, regex: Union[str | list[str] | bytes | li
136
138
try :
137
139
db .compile (regex_bytes , flags = hyperscan .HS_FLAG_SOM_LEFTMOST | hyperscan .HS_FLAG_UTF8 )
138
140
except hyperscan .error :
139
- LOG .debug ("Failed to compile a rule with 'HS_FLAG_SOM_LEFTMOST' : %s" , str (regex_bytes ))
140
- for regex in regex_bytes :
141
+ LOG .debug ("Failed to compile a rule: %s" , str (regex_bytes ))
142
+ for label , regex in zip_longest ( labels , regex_bytes ) :
141
143
try :
142
144
db .compile ([regex ], flags = hyperscan .HS_FLAG_SOM_LEFTMOST | hyperscan .HS_FLAG_UTF8 )
143
145
except hyperscan .error as err :
144
- LOG .error ("❌ Failed to compile %s with 'leftmost' flag : %s" , str (regex ), err )
146
+ LOG .error ("❌ Failed to compile %s%s : %s" , str (regex ), ' (' + label + ')' if label is not None else '' , err )
145
147
146
148
return False
147
149
@@ -299,7 +301,7 @@ def test_patterns(tests_path: str, include: Optional[list[str]] = None, exclude:
299
301
300
302
found_patterns = True
301
303
302
- if not hs_compile (db , [pattern .regex_string () for pattern in patterns ]):
304
+ if not hs_compile (db , [pattern .regex_string () for pattern in patterns ], labels = [ pattern . type for pattern in patterns ] ):
303
305
if not quiet :
304
306
LOG .error ("❌ hyperscan pattern compilation error in '%s'" , rel_dirpath )
305
307
exit (1 )
@@ -384,7 +386,7 @@ def dry_run_patterns(tests_path: str, extra_directory: str, include: Optional[li
384
386
LOG .error ("❌ Failed to find any patterns in %s" , str (tests_path ))
385
387
return
386
388
387
- if not hs_compile (db , [pattern .regex_string () for pattern in patterns ]):
389
+ if not hs_compile (db , [pattern .regex_string () for pattern in patterns ], labels = [ pattern . type for pattern in patterns ] ):
388
390
if not quiet :
389
391
LOG .error ("❌ hyperscan pattern compilation error in '%s'" , dirpath )
390
392
exit (1 )
@@ -435,7 +437,7 @@ def random_test_patterns(tests_path: str, include: Optional[list[str]], exclude:
435
437
if PATTERNS_FILENAME in filenames :
436
438
patterns .extend (parse_patterns (dirpath , include = include , exclude = exclude ))
437
439
438
- if not hs_compile (db , [pattern .regex_string () for pattern in patterns ]):
440
+ if not hs_compile (db , [pattern .regex_string () for pattern in patterns ], labels = [ pattern . type for pattern in patterns ] ):
439
441
if not quiet :
440
442
LOG .error ("❌ hyperscan pattern compilation error in '%s'" , dirpath )
441
443
exit (1 )
0 commit comments