fix: close file handle in get_file_taste using a with statement

`get_file_taste` opened a file handle with `sample_path.open("rb").read(8)`,
discarding the file object without explicitly closing it. CPython reference-
counting closes it promptly in practice, but other implementations (PyPy,
Jython) and CPython under GC pressure may defer closure. Use a `with` statement
to guarantee the handle is released immediately after reading.
This commit is contained in:
Willi Ballenthin
2026-04-22 17:38:45 +03:00
committed by Willi Ballenthin
parent 1a7d7ca5d6
commit fdd571eaed
3 changed files with 17 additions and 2 deletions
+1
View File
@@ -32,6 +32,7 @@
- fix: loader.py reads entire file for magic byte check @williballenthin #3029
- fix: freeze/__init__.py: logically impossible condition @williballenthin #3030
- fix: EXTENSIONS_ELF never referenced @williballenthin #3031
- fix: close file handle in get_file_taste using a with statement @williballenthin
- fix: correct off-by-one in dynamic analysis call_count debug log (enumerate -> explicit counter) @williballenthin
- fix: correct capa/subscope-rule key in RuleMetadata so is_subscope_rule is no longer always False @williballenthin
- fix: remove unreachable backports.functools_lru_cache fallback and dead dependency @williballenthin
+2 -2
View File
@@ -88,8 +88,8 @@ def hex(n: int) -> str:
def get_file_taste(sample_path: Path) -> bytes:
if not sample_path.exists():
raise IOError(f"sample path {sample_path} does not exist or cannot be accessed")
taste = sample_path.open("rb").read(8)
return taste
with sample_path.open("rb") as f:
return f.read(8)
def is_runtime_ida():
+14
View File
@@ -27,6 +27,7 @@ from capa.helpers import (
EXTENSIONS_BINEXPORT2,
EXTENSIONS_SHELLCODE_32,
EXTENSIONS_SHELLCODE_64,
get_file_taste,
get_format_from_extension,
)
from capa.features.common import (
@@ -166,3 +167,16 @@ def test_get_format_from_extension():
assert get_format_from_extension(Path("sample.BinExport2")) == FORMAT_BINEXPORT2
assert get_format_from_extension(Path("sample.bndb")) == FORMAT_BINJA_DB
assert get_format_from_extension(Path("sample.exe")) == FORMAT_UNKNOWN
def test_get_file_taste_reads_first_bytes(tmp_path):
sample = tmp_path / "sample.bin"
sample.write_bytes(b"\x4d\x5a\x90\x00\x01\x02\x03\x04\xff\xfe")
taste = get_file_taste(sample)
assert taste == b"\x4d\x5a\x90\x00\x01\x02\x03\x04"
assert len(taste) == 8
def test_get_file_taste_missing_file_raises():
with pytest.raises(IOError):
get_file_taste(Path("/nonexistent/path/sample.exe"))