From e4eade427c75eba22e569ef13111e3e8442aba00 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Fri, 24 Jul 2020 12:06:56 +0200 Subject: [PATCH] Don't iterate directly over the scans table, as it can change during the iteration. The scans table is accessed by different processes and the iterated dictionary can change it size. --- CHANGELOG.md | 1 + ospd/scan.py | 5 ++++- tests/test_scan_and_result.py | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 585bb799..807759e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fix get_scanner_details(). [#210](https://github.com/greenbone/ospd/pull/210) - Fix thread lib leak using daemon mode for python 3.7. [#272](https://github.com/greenbone/ospd/pull/272) - Fix scan progress in which all hosts are dead or excluded. [#295](https://github.com/greenbone/ospd/pull/295) +- Fix start of parallel queued task. [#304](https://github.com/greenbone/ospd/pull/304) ### Removed - Remove support for resume task. [#266](https://github.com/greenbone/ospd/pull/266) diff --git a/ospd/scan.py b/ospd/scan.py index d9feffca..b78f5073 100644 --- a/ospd/scan.py +++ b/ospd/scan.py @@ -231,7 +231,10 @@ def results_iterator( def ids_iterator(self) -> Iterator[str]: """ Returns an iterator over the collection's scan IDS. """ - return iter(self.scans_table.keys()) + # Do not iterate over the scans_table because it can change + # during iteration, since it is accessed by multiple processes. + scan_id_list = list(self.scans_table) + return iter(scan_id_list) def clean_up_pickled_scan_info(self) -> None: """ Remove files of pickled scan info """ diff --git a/tests/test_scan_and_result.py b/tests/test_scan_and_result.py index d547388c..27b480c5 100644 --- a/tests/test_scan_and_result.py +++ b/tests/test_scan_and_result.py @@ -1309,3 +1309,11 @@ def test_count_queued_scans(self): self.assertEqual(self.daemon.get_count_queued_scans(), 1) self.daemon.start_queued_scans() self.assertEqual(self.daemon.get_count_queued_scans(), 0) + + def test_ids_iterator_dict_modified(self): + self.daemon.scan_collection.scans_table = {'a': 1, 'b': 2} + + for e in self.daemon.scan_collection.ids_iterator(): + self.daemon.scan_collection.scans_table['c'] = 3 + + self.assertEqual(len(self.daemon.scan_collection.scans_table), 3)