Enrique Sánchez has proposed merging ~enriqueesanchz/launchpad:fix-update-cve-exception into launchpad:master.
Commit message: Fix empty delta zip raising an Exception There are some times where the delta zip release from CVEProject/cvelistV5 is empty because there were no changes. We avoid raising an LaunchpadScriptFailure due to that. Default cve references content to url. Requested reviews: Launchpad code reviewers (launchpad-reviewers) For more details, see: https://code.launchpad.net/~enriqueesanchz/launchpad/+git/launchpad/+merge/491899 -- Your team Launchpad code reviewers is requested to review the proposed merge of ~enriqueesanchz/launchpad:fix-update-cve-exception into launchpad:master.
diff --git a/lib/lp/bugs/scripts/cveimport.py b/lib/lp/bugs/scripts/cveimport.py index 66a6dcd..99fe66b 100644 --- a/lib/lp/bugs/scripts/cveimport.py +++ b/lib/lp/bugs/scripts/cveimport.py @@ -374,6 +374,16 @@ class CVEUpdater(LaunchpadCronScript): # extract the outer zip file with zipfile.ZipFile(outer_zip_path) as outer_zf: if delta: + target_dir = os.path.join(temp_dir, "deltaCves") + + # If there are no delta cves, we return an empty dir + if not outer_zf.namelist(): + self.logger.info( + "Zip file is empty: there are no delta changes" + ) + os.mkdir(target_dir) + return target_dir + # for delta, extract deltacves directory members = [ m @@ -381,7 +391,6 @@ class CVEUpdater(LaunchpadCronScript): if m.startswith("deltaCves/") ] outer_zf.extractall(temp_dir, members=members) - target_dir = os.path.join(temp_dir, "deltaCves") else: # for baseline, handle nested zip structure outer_zf.extract("cves.zip", temp_dir) @@ -729,6 +738,9 @@ class CVEUpdater(LaunchpadCronScript): source = "external" # default source content = ref.get("name", "") + if not content: + content = url + # look for existing reference was_there_previously = False for old_ref in old_references: diff --git a/lib/lp/bugs/scripts/tests/test_cveimport.py b/lib/lp/bugs/scripts/tests/test_cveimport.py index f39c7e6..07f4550 100644 --- a/lib/lp/bugs/scripts/tests/test_cveimport.py +++ b/lib/lp/bugs/scripts/tests/test_cveimport.py @@ -4,8 +4,10 @@ import gzip import io import json +import os import shutil import tempfile +import zipfile from datetime import datetime, timezone from pathlib import Path @@ -203,6 +205,20 @@ class TestCVEUpdater(TestCase): self.assertIsNotNone(cve) self.assertEqual("Delta CVE", cve.description) + def test_process_delta_directory_empty(self): + """Test processing an empty directory of delta CVE files.""" + # Create empty test delta directory + delta_dir = Path(self.temp_dir) / "deltaCves" + delta_dir.mkdir() + + # Process the directory using the script infrastructure + updater = self.make_updater([str(delta_dir)]) + processed, errors = updater.process_delta_directory(str(delta_dir)) + + # Verify results + self.assertEqual(0, processed) + self.assertEqual(0, errors) + def test_construct_github_url(self): """Test GitHub URL construction for different scenarios.""" updater = CVEUpdater( @@ -262,3 +278,66 @@ class TestCVEUpdater(TestCase): # Verify the update updated_cve = cveset["2024-0004"] self.assertEqual(new_desc, updated_cve.description) + + def test_extract_github_zip(self): + """Test extract_github_zip for complete releases.""" + updater = self.make_updater() + outer_buffer = io.BytesIO() + + with zipfile.ZipFile(outer_buffer, "w") as outer_zip: + # create inner cves.zip in memory + inner_buffer = io.BytesIO() + with zipfile.ZipFile(inner_buffer, "w") as inner_zip: + inner_zip.writestr("cves/CVE-2025-8941.json", "CVE data") + outer_zip.writestr("cves.zip", inner_buffer.getvalue()) + + target_dir = updater.extract_github_zip(outer_buffer.getvalue()) + self.assertTrue(target_dir.endswith("cves")) + self.assertEqual(os.listdir(target_dir), ["CVE-2025-8941.json"]) + + def test_extract_empty_github_zip(self): + """Test that extract_github_zip for complete releases raises + LaunchpadScriptFailure when the zip is empty. + """ + updater = self.make_updater() + buffer = io.BytesIO() + + # Empty zipfile buffer + with zipfile.ZipFile(buffer, "w"): + pass + + self.assertRaisesWithContent( + LaunchpadScriptFailure, + "Failed to extract ZIP files: \"There is no item named 'cves.zip' " + 'in the archive"', + updater.extract_github_zip, + buffer.getvalue(), + ) + + def test_extract_delta_github_zip(self): + """Test extract_github_zip for delta releases.""" + updater = self.make_updater() + buffer = io.BytesIO() + + with zipfile.ZipFile(buffer, "w") as zf: + zf.writestr("deltaCves/CVE-2025-8941.json", "delta CVE data") + + empty_dir = updater.extract_github_zip(buffer.getvalue(), delta=True) + self.assertTrue(empty_dir.endswith("deltaCves")) + self.assertEqual(os.listdir(empty_dir), ["CVE-2025-8941.json"]) + + def test_extract_empty_delta_github_zip(self): + """Test that extract_github_zip for delta releases returns an empty dir + if the zip is empty. There can be hours when no cves are updated so we + will return an empty dir and will not import cves. + """ + updater = self.make_updater() + buffer = io.BytesIO() + + # Empty zipfile buffer + with zipfile.ZipFile(buffer, "w"): + pass + + empty_dir = updater.extract_github_zip(buffer.getvalue(), delta=True) + self.assertTrue(empty_dir.endswith("deltaCves")) + self.assertEqual(os.listdir(empty_dir), [])
_______________________________________________ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp