diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 07884e6cae..5f03b32970 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -41,6 +41,15 @@ All notable changes to the **Prowler SDK** are documented in this file. --- +--- + +## [v5.12.4] (Prowler UNRELEASED) + +### Fixed +- Fix file extension parsing for compliance reports [(#8791)](https://github.com/prowler-cloud/prowler/pull/8791) + +--- + ## [v5.12.1] (Prowler v5.12.1) ### Fixed diff --git a/prowler/lib/outputs/compliance/compliance_output.py b/prowler/lib/outputs/compliance/compliance_output.py index d3b855521e..f4f84561f4 100644 --- a/prowler/lib/outputs/compliance/compliance_output.py +++ b/prowler/lib/outputs/compliance/compliance_output.py @@ -42,7 +42,10 @@ class ComplianceOutput(Output): self._from_cli = from_cli if not file_extension and file_path: - self._file_extension = "".join(Path(file_path).suffixes) + # Compliance reports are always CSV, so just use the last suffix + # e.g., "cis_5.0_aws.csv" should have extension ".csv", not ".0_aws.csv" + path_obj = Path(file_path) + self._file_extension = path_obj.suffix if path_obj.suffix else "" if file_extension: self._file_extension = file_extension self.file_path = f"{file_path}{self.file_extension}" diff --git a/tests/lib/outputs/compliance/compliance_test.py b/tests/lib/outputs/compliance/compliance_test.py index 839e5518ec..bb6a7e4089 100644 --- a/tests/lib/outputs/compliance/compliance_test.py +++ b/tests/lib/outputs/compliance/compliance_test.py @@ -391,3 +391,54 @@ class TestCompliance: assert get_check_compliance(finding, "github", bulk_checks_metadata) == { "CIS-1.0": ["1.1.11"], } + + +class TestComplianceOutput: + """Test ComplianceOutput file extension parsing fix.""" + + def test_compliance_output_file_extension_with_dots(self): + """Test that ComplianceOutput correctly parses file extensions when framework names contain dots.""" + from prowler.lib.outputs.compliance.generic.generic import GenericCompliance + + compliance = Compliance( + Framework="CIS", + Version="5.0", + Provider="AWS", + Name="CIS Amazon Web Services Foundations Benchmark v5.0", + Description="Test compliance framework", + Requirements=[], + ) + + # Test with problematic file path that contains dots in framework name + # This simulates the real scenario from Prowler App S3 integration + problematic_file_path = "output/compliance/prowler-output-123456789012-20250101120000_cis_5.0_aws.csv" + + # Create GenericCompliance object with file_path (no explicit file_extension) + compliance_output = GenericCompliance( + findings=[], compliance=compliance, file_path=problematic_file_path + ) + + assert compliance_output.file_extension == ".csv" + assert compliance_output.file_extension != ".0_aws.csv" + + def test_compliance_output_file_extension_explicit(self): + """Test that ComplianceOutput uses explicit file_extension when provided.""" + from prowler.lib.outputs.compliance.generic.generic import GenericCompliance + + compliance = Compliance( + Framework="CIS", + Version="5.0", + Provider="AWS", + Name="CIS Amazon Web Services Foundations Benchmark v5.0", + Description="Test compliance framework", + Requirements=[], + ) + + compliance_output = GenericCompliance( + findings=[], + compliance=compliance, + file_path="output/compliance/test", + file_extension=".csv", + ) + + assert compliance_output.file_extension == ".csv"