mirror of
https://github.com/mandiant/capa.git
synced 2026-07-28 22:50:59 -07:00
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.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
cb3376d9e2
commit
243e6408b0
@@ -11,6 +11,7 @@
|
||||
-
|
||||
|
||||
### Bug Fixes
|
||||
- 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
@@ -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():
|
||||
|
||||
+21
-1
@@ -14,10 +14,13 @@
|
||||
|
||||
|
||||
import codecs
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
import capa.helpers
|
||||
from capa.helpers import get_format_from_extension
|
||||
from capa.helpers import get_file_taste, get_format_from_extension
|
||||
from capa.features.common import (
|
||||
FORMAT_ELF,
|
||||
FORMAT_SC32,
|
||||
@@ -101,3 +104,20 @@ 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():
|
||||
with tempfile.NamedTemporaryFile(delete=False) as tmp:
|
||||
tmp.write(b"\x4d\x5a\x90\x00\x01\x02\x03\x04\xff\xfe")
|
||||
tmp_path = Path(tmp.name)
|
||||
try:
|
||||
taste = get_file_taste(tmp_path)
|
||||
assert taste == b"\x4d\x5a\x90\x00\x01\x02\x03\x04"
|
||||
assert len(taste) == 8
|
||||
finally:
|
||||
tmp_path.unlink()
|
||||
|
||||
|
||||
def test_get_file_taste_missing_file_raises():
|
||||
with pytest.raises(IOError):
|
||||
get_file_taste(Path("/nonexistent/path/sample.exe"))
|
||||
|
||||
Reference in New Issue
Block a user