Skip to content

Commit 556e37f

Browse files
lirshindalmanlshindelman
andauthored
fix: threading (#290)
Co-authored-by: lshindelman <lshindelman@paloaltonetworks.com>
1 parent b84459a commit 556e37f

File tree

1 file changed

+7
-29
lines changed

1 file changed

+7
-29
lines changed

detect_secrets/settings.py

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import contextlib
2-
import threading
32
from contextlib import contextmanager
43
from copy import deepcopy
54
from functools import lru_cache
@@ -14,15 +13,6 @@
1413
from .util.importlib import import_file_as_module
1514

1615

17-
# Lock to protect transient_settings from concurrent access.
18-
# On macOS, checkov's ParallelRunner uses ThreadPoolExecutor,
19-
# so all scanners share the same process and global state. Without this lock,
20-
# concurrent calls to transient_settings() can corrupt the LRU-cached singletons
21-
# (get_settings, get_plugins, get_mapping_from_secret_type_to_class), causing
22-
# the secrets scanner to silently produce 0 findings.
23-
_settings_lock = threading.Lock()
24-
25-
2616
@lru_cache(maxsize=1)
2717
def get_settings() -> 'Settings':
2818
"""
@@ -87,33 +77,21 @@ def default_settings() -> Generator['Settings', None, None]:
8777

8878
@contextmanager
8979
def transient_settings(config: Dict[str, Any]) -> Generator['Settings', None, None]:
90-
"""Allows the customizability of non-global settings per invocation.
91-
92-
Protected by _settings_lock to prevent race conditions when
93-
multiple threads call this concurrently (e.g., IAC + SECRETS scanners
94-
running in parallel via ThreadPoolExecutor on macOS).
95-
"""
96-
with _settings_lock:
97-
original_settings = get_settings().json()
80+
"""Allows the customizability of non-global settings per invocation."""
81+
original_settings = get_settings().json()
9882

83+
cache_bust()
84+
try:
85+
yield configure_settings_from_baseline(config)
86+
finally:
9987
cache_bust()
100-
try:
101-
yield configure_settings_from_baseline(config)
102-
finally:
103-
cache_bust()
104-
configure_settings_from_baseline(original_settings)
88+
configure_settings_from_baseline(original_settings)
10589

10690

10791
def cache_bust() -> None:
10892
get_plugins.cache_clear()
10993

11094
get_filters.cache_clear()
111-
112-
# BCE-56937: Clear the plugin-type mapping cache to prevent stale mappings
113-
# built from empty settings during a race window.
114-
from .core.plugins.util import get_mapping_from_secret_type_to_class
115-
get_mapping_from_secret_type_to_class.cache_clear()
116-
11795
for path in get_settings().filters:
11896
# Need to also clear the individual caches (e.g. cached regex patterns).
11997
parts = urlparse(path)

0 commit comments

Comments
 (0)