diff --git a/.dielib_commit b/.dielib_commit new file mode 100644 index 0000000..9f0f455 --- /dev/null +++ b/.dielib_commit @@ -0,0 +1 @@ +09df9ccafe48a0531987ad1e605402ed79d4c3f6 \ No newline at end of file diff --git a/cmake/FindDieLibrary.cmake b/cmake/FindDieLibrary.cmake index b4783e5..47ba0b2 100644 --- a/cmake/FindDieLibrary.cmake +++ b/cmake/FindDieLibrary.cmake @@ -65,10 +65,12 @@ list(INSERT CMAKE_MODULE_PATH 0 find_package(Qt6 REQUIRED COMPONENTS Core Qml Concurrent) +file(STRINGS "${ROOT_DIR}/.dielib_commit" DIE_LIBRARY_GIT_TAG) +message(STATUS "Using tag ${DIE_LIBRARY_GIT_TAG} for DieLibrary") FetchContent_Declare( DieLibrary GIT_REPOSITORY "https://github.com/horsicq/die_library" - GIT_TAG 09df9ccafe48a0531987ad1e605402ed79d4c3f6 + GIT_TAG "${DIE_LIBRARY_GIT_TAG}" ) set(DIE_BUILD_AS_STATIC ON CACHE INTERNAL "") diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index f5f4eb6..f65aa8e 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -60,6 +60,7 @@ target_compile_definitions(_die PRIVATE DIE_VERSION="${DIE_VERSION}" DIELIB_VERSION="${DIELIB_VERSION}" + DIELIB_TAG="${DIE_LIBRARY_GIT_TAG}" ) target_link_libraries(_die PRIVATE $ $) diff --git a/python/die/__init__.py b/python/die/__init__.py index 73ab8b2..cc13191 100644 --- a/python/die/__init__.py +++ b/python/die/__init__.py @@ -2,7 +2,7 @@ import pathlib import warnings -from typing import Generator, Optional, Union +from typing import Generator from ._die import __version__ # ty:ignore[unresolved-import] from ._die import DieFlags as _DieFlags # ty:ignore[unresolved-import] @@ -13,9 +13,9 @@ ScanMemoryExA as _ScanMemoryExA, LoadDatabaseA as _LoadDatabaseA, ) -from ._die import die_version, dielib_version # ty:ignore[unresolved-import] +from ._die import die_version, dielib_version, dielib_tag # ty:ignore[unresolved-import] -__all__ = ["die_version", "dielib_version"] +__all__ = ["die_version", "dielib_version", "dielib_tag"] version_major, version_minor, version_patch = map(int, __version__.split(".")) @@ -108,7 +108,7 @@ def iterdir(self): # Initialize database path with smart handling -database_path = _DatabasePath(__path__[0]) / "db" +database_path: pathlib.Path = _DatabasePath(__path__[0]) / "db" """Path to the DIE signature database This path automatically points to the correct database location, @@ -138,8 +138,8 @@ class ScanFlags(enum.IntFlag): def scan_file( - filepath: Union[pathlib.Path, str], flags: ScanFlags, database: Optional[str] = None -) -> Optional[str]: + filepath: pathlib.Path | str, flags: ScanFlags, database: str | None = None +) -> str | None: """ Scan the given file against the signature database, if specified @@ -192,8 +192,8 @@ def __enum_db(root: pathlib.Path) -> Generator[pathlib.Path, None, None]: def scan_memory( - memory: Union[bytes, bytearray], flags: ScanFlags, database: Optional[str] = None -) -> Optional[str]: + memory: bytes | bytearray, flags: ScanFlags, database: str | None = None +) -> str | None: """ Scan the given sequence of bytes against the signature database, if specified @@ -220,11 +220,14 @@ def scan_memory( return res.strip() -def load_database(database: str) -> int: +def load_database(database: str | pathlib.Path) -> int: """ Load a database """ - if not isinstance(database, str): + if isinstance(database, pathlib.Path): + database = str(database) + + elif not isinstance(database, str): raise TypeError return _LoadDatabaseA(database) diff --git a/python/inc/die.hpp b/python/inc/die.hpp index db62ca9..2ab3acf 100644 --- a/python/inc/die.hpp +++ b/python/inc/die.hpp @@ -14,6 +14,10 @@ #define DIE_VERSION "" #endif // DIE_VERSION +#ifndef DIELIB_TAG +#define DIELIB_TAG "" +#endif // DIELIB_TAG + #ifdef __cplusplus namespace DIE { diff --git a/python/src/die.cpp b/python/src/die.cpp index 312590b..9c713ac 100644 --- a/python/src/die.cpp +++ b/python/src/die.cpp @@ -126,6 +126,7 @@ NB_MODULE(_die, m) m.attr("__version__") = "0.5.0"; m.attr("die_version") = DIE_VERSION; m.attr("dielib_version") = DIELIB_VERSION; + m.attr("dielib_tag") = DIELIB_TAG; m.def("ScanFileA", DIE::ScanFileA, "filename"_a, "flags"_a, "database"_a, "Scan a file against known signatures"); diff --git a/python/tests/test_die.py b/python/tests/test_die.py index 8d8b9cc..2f9499d 100644 --- a/python/tests/test_die.py +++ b/python/tests/test_die.py @@ -17,6 +17,8 @@ def test_constants(): assert die.die_version assert isinstance(die.dielib_version, str) assert die.dielib_version + assert isinstance(die.dielib_tag, str) + assert die.dielib_tag # validate die database assert isinstance(die.database_path, die._DatabasePath) @@ -117,9 +119,11 @@ def test_scan_export_format_xml(target_binary: pathlib.Path) -> None: assert xml.Result if platform.system() == "Windows": assert hasattr(xml.Result, "PE64") + assert xml.Result.PE64 assert xml.Result.PE64["filetype"] == "PE64" elif platform.system() == "Linux": assert hasattr(xml.Result, "ELF64") + assert xml.Result.ELF64 assert xml.Result.ELF64["filetype"] == "ELF64" @@ -170,16 +174,18 @@ def test_database_path_backward_compatibility(): # Test 2: database_path should resolve to a valid location with PE/ directory db_path = pathlib.Path(path_new) assert db_path.exists(), f"Database path does not exist: {db_path}" - assert (db_path / 'PE').exists(), f"PE directory not found at {db_path}" + assert (db_path / "PE").exists(), f"PE directory not found at {db_path}" # Test 3: Old usage with /'db' should work through smart path resolution # The smart path should detect the version and handle accordingly with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") - path_old = str(die.database_path / 'db') + path_old = str(die.database_path / "db") # The path should exist in both old and new versions - assert pathlib.Path(path_old).exists(), f"Old usage path doesn't exist: {path_old}" + assert pathlib.Path(path_old).exists(), ( + f"Old usage path doesn't exist: {path_old}" + ) if len(w) > 0: # New fixed version: got deprecation warning @@ -200,13 +206,14 @@ def test_database_path_resolves_correctly(): db_path = pathlib.Path(str(die.database_path)) # Check for PE directory (main signature database) - assert (db_path / 'PE').exists(), f"PE directory not found at {db_path}" + assert (db_path / "PE").exists(), f"PE directory not found at {db_path}" # Check for other expected directories - expected_dirs = ['PE', 'ELF', 'MACH'] + expected_dirs = ["PE", "ELF", "MACH"] for dir_name in expected_dirs: - assert (db_path / dir_name).exists(), \ + assert (db_path / dir_name).exists(), ( f"Expected directory {dir_name} not found at {db_path}" + ) def test_scan_with_explicit_database_path(target_binary: pathlib.Path): @@ -230,7 +237,7 @@ def test_scan_with_explicit_database_path(target_binary: pathlib.Path): res = die.scan_file( target_binary, die.ScanFlags.DEEP_SCAN, - database=str(die.database_path / 'db'), + database=str(die.database_path / "db"), ) assert res assert isinstance(res, str)