From e273391148be628d6094c1f8f2fee1372f6aad1d Mon Sep 17 00:00:00 2001 From: Carl Flottmann Date: Wed, 4 Dec 2024 15:48:03 +1000 Subject: [PATCH] fix: inspector links and file server links are now separate fields --- .../pypi_heuristics/metadata/wheel_absence.py | 19 ++++++++----- .../pypi/test_wheel_absence.py | 27 ++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/macaron/malware_analyzer/pypi_heuristics/metadata/wheel_absence.py b/src/macaron/malware_analyzer/pypi_heuristics/metadata/wheel_absence.py index 9e1b123f3..827fad945 100644 --- a/src/macaron/malware_analyzer/pypi_heuristics/metadata/wheel_absence.py +++ b/src/macaron/malware_analyzer/pypi_heuristics/metadata/wheel_absence.py @@ -67,7 +67,8 @@ def analyze(self, pypi_package_json: PyPIPackageJsonAsset) -> tuple[HeuristicRes logger.debug(error_msg) raise HeuristicAnalyzerValueError(error_msg) - release_files: list[JsonType] = [] + file_server_links: list[JsonType] = [] + inspector_links: list[JsonType] = [] wheel_present: bool = False try: @@ -88,17 +89,23 @@ def analyze(self, pypi_package_json: PyPIPackageJsonAsset) -> tuple[HeuristicRes # use a head request because we don't care about the response contents if send_head_http_raw(inspector_link) is None: - inspector_link = "" + inspector_link = None - release_files.append(release_metadata["url"]) - release_files.append(inspector_link) + file_server_links.append(release_metadata["url"]) + inspector_links.append(inspector_link) except KeyError as error: error_msg = f"The version {version} is not available as a release." logger.debug(error_msg) raise HeuristicAnalyzerValueError(error_msg) from error + detail_info: dict[str, JsonType] = { + "version": version, + "file_server_links": file_server_links, + "inspector_links": inspector_links, + } + if wheel_present: - return HeuristicResult.PASS, {version: release_files} + return HeuristicResult.PASS, detail_info - return HeuristicResult.FAIL, {version: release_files} + return HeuristicResult.FAIL, detail_info diff --git a/tests/malware_analyzer/pypi/test_wheel_absence.py b/tests/malware_analyzer/pypi/test_wheel_absence.py index ed5d42227..79efcf191 100644 --- a/tests/malware_analyzer/pypi/test_wheel_absence.py +++ b/tests/malware_analyzer/pypi/test_wheel_absence.py @@ -71,7 +71,13 @@ def test_analyze_tar_present(mock_send_head_http_raw: MagicMock, pypi_package_js pypi_package_json.package_json = {"info": {"name": "ttttttttest_nester"}} mock_send_head_http_raw.return_value = MagicMock() # assume valid URL for testing purposes - expected_result: tuple[HeuristicResult, dict] = (HeuristicResult.FAIL, {version: [url, inspector_link_expected]}) + expected_detail_info = { + "version": version, + "file_server_links": [url], + "inspector_links": [inspector_link_expected], + } + + expected_result: tuple[HeuristicResult, dict] = (HeuristicResult.FAIL, expected_detail_info) actual_result = analyzer.analyze(pypi_package_json) @@ -124,7 +130,13 @@ def test_analyze_whl_present(mock_send_head_http_raw: MagicMock, pypi_package_js pypi_package_json.package_json = {"info": {"name": "ttttttttest_nester"}} mock_send_head_http_raw.return_value = MagicMock() # assume valid URL for testing purposes - expected_result: tuple[HeuristicResult, dict] = (HeuristicResult.PASS, {version: [url, inspector_link_expected]}) + expected_detail_info = { + "version": version, + "file_server_links": [url], + "inspector_links": [inspector_link_expected], + } + + expected_result: tuple[HeuristicResult, dict] = (HeuristicResult.PASS, expected_detail_info) actual_result = analyzer.analyze(pypi_package_json) @@ -206,10 +218,13 @@ def test_analyze_both_present(mock_send_head_http_raw: MagicMock, pypi_package_j pypi_package_json.package_json = {"info": {"name": "ttttttttest_nester"}} mock_send_head_http_raw.return_value = MagicMock() # assume valid URL for testing purposes - expected_result: tuple[HeuristicResult, dict] = ( - HeuristicResult.PASS, - {version: [wheel_url, wheel_link_expected, tar_url, tar_link_expected]}, - ) + expected_detail_info = { + "version": version, + "file_server_links": [wheel_url, tar_url], + "inspector_links": [wheel_link_expected, tar_link_expected], + } + + expected_result: tuple[HeuristicResult, dict] = (HeuristicResult.PASS, expected_detail_info) actual_result = analyzer.analyze(pypi_package_json)