use weakrefs for Scopes instantiation; fix test_rules()

This commit is contained in:
Yacine Elhamer
2023-07-27 15:52:39 +01:00
parent 2efb7f2975
commit 3d812edc4d
3 changed files with 24 additions and 3 deletions

View File

@@ -8,6 +8,8 @@
import json import json
import inspect import inspect
import logging import logging
import weakref
import functools
import contextlib import contextlib
import importlib.util import importlib.util
from typing import NoReturn from typing import NoReturn
@@ -130,6 +132,25 @@ def redirecting_print_to_tqdm(disable_progress):
inspect.builtins.print = old_print # type: ignore inspect.builtins.print = old_print # type: ignore
def weak_lru(maxsize=128, typed=False):
"""
LRU Cache decorator that keeps a weak reference to 'self'
"""
def wrapper(func):
@functools.lru_cache(maxsize, typed)
def _func(_self, *args, **kwargs):
return func(_self(), *args, **kwargs)
@functools.wraps(func)
def inner(self, *args, **kwargs):
return _func(weakref.ref(self), *args, **kwargs)
return inner
return wrapper
def log_unsupported_format_error(): def log_unsupported_format_error():
logger.error("-" * 80) logger.error("-" * 80)
logger.error(" Input file does not appear to be a PE or ELF file.") logger.error(" Input file does not appear to be a PE or ELF file.")

View File

@@ -16,7 +16,7 @@ import collections
from enum import Enum from enum import Enum
from pathlib import Path from pathlib import Path
from capa.helpers import assert_never from capa.helpers import weak_lru, assert_never
try: try:
from functools import lru_cache from functools import lru_cache
@@ -115,7 +115,7 @@ class Scopes:
static: Optional[str] = None static: Optional[str] = None
dynamic: Optional[str] = None dynamic: Optional[str] = None
@lru_cache() # type: ignore @weak_lru()
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
return super().__new__(cls) return super().__new__(cls)

View File

@@ -357,7 +357,7 @@ def test_rules_flavor_filtering():
), ),
] ]
static_rules = capa.rules.RuleSet(rules, rules_filter_func=lambda rule: rule.scopes.static) static_rules = capa.rules.RuleSet(rules.copy(), rules_filter_func=lambda rule: rule.scopes.static)
dynamic_rules = capa.rules.RuleSet(rules, rules_filter_func=lambda rule: rule.scopes.dynamic) dynamic_rules = capa.rules.RuleSet(rules, rules_filter_func=lambda rule: rule.scopes.dynamic)
# only static rule # only static rule