def test_basic_selector(maven_vertx_cve): """Test VersionSelector().pick_winner().""" candidates = [ PackageNameCandidate('io.vertx:testtools', Decimal('10.0')), PackageNameCandidate('io.vertx:vertx-core', Decimal('5.0')) ] selector = VersionSelector(maven_vertx_cve, candidates, 'java') winner = selector.pick_winner() assert winner assert winner.package == 'io.vertx:vertx-core'
def test_package_name_candidate_bad(): """Test PackageNameCandidate() with invalid input.""" with pytest.raises(ValueError): PackageNameCandidate(None, Decimal('1.0')) with pytest.raises(ValueError): PackageNameCandidate('', Decimal('1.0')) with pytest.raises(ValueError): PackageNameCandidate('package-a', None) # extra element ("UI") in the cpe2pkg output line candidate = PackageNameCandidate.from_cpe2pkg_output( '1.0268737 javascript:JQuery UI', 'javascript') assert candidate.package == 'JQuery'
def test_basic_selector_none_versions(unsupported_cve_none_versions): """Test VersionSelector().pick_winner() with "None" versions.""" candidates = [ PackageNameCandidate('io.vertx:testtools', Decimal('10.0')), ] selector = VersionSelector(unsupported_cve_none_versions, candidates, 'java') winner = selector.pick_winner() # don't throw TypeError here assert not winner
def test_package_name_candidate(): """Test PackageNameCandidate().""" c1 = PackageNameCandidate.from_cpe2pkg_output('10.0 python:package-a', 'python') assert c1.package == 'package-a' assert c1.score == Decimal('10.0') assert str(c1) == 'PackageNameCandidate(package-a, 10.0)' assert c1 == c1 c2 = PackageNameCandidate.from_cpe2pkg_output('9.0 python:package-b', 'python') assert c1 > c2 assert c2 < c1 assert c1 != c2 c3 = PackageNameCandidate.from_cpe2pkg_output('9.0 gid:package-c', 'java') assert c3.package == 'gid:package-c'
def _run_cpe2pkg(self, vendor, product): """Run cpe2pkg tool. :param vendor: list[str], a list of vendor strings :param product: list[str], a list of product strings :return: list[PackageNameCandidate], a list of package name candidates """ query_str = build_cpe2pkg_query(vendor, product) output = run_cpe2pkg(query_str, self.pkgfile_path, self.cpe2pkg_path) return [ PackageNameCandidate.from_cpe2pkg_output(x, self.ecosystem) for x in output if x ]
def run(): """Run CVEjob.""" feed_dir = Config.feed_dir feed_names = Config.feed_names date_range = Config.date_range cherrypicked_cve_id = Config.cve_id cherrypicked_year = None if cherrypicked_cve_id: cherrypicked_year = cherrypicked_cve_id.split(sep='-')[1] if int(cherrypicked_year) < 2002: # all CVEs prior to 2002 are stored in 2002 feed cherrypicked_year = 2002 if date_range: date_range = parse_date_range(Config.date_range) feed_names = range(date_range[0].year, date_range[1].year + 1) if cherrypicked_cve_id: # optimization check if int(cherrypicked_year) not in feed_names: logger.info( "[{picked_cve_id}] does not belong to the given feed range:" " {date_range}".format(picked_cve_id=cherrypicked_cve_id, date_range=date_range)) return # prune the feed names as it is not necessary to iterate over all of them feed_names = [cherrypicked_year] if not feed_names: if cherrypicked_cve_id: feed_names = [cherrypicked_year] else: feed_names = ['modified'] with FeedManager(n_workers=multiprocessing.cpu_count()) as feed_manager: feeds = feed_manager.fetch_feeds(feed_names=feed_names, data_dir=feed_dir, update=True) collection = feed_manager.collect(feeds) collection = _filter_collection(collection, date_range, cherrypicked_cve_id) if not collection: # collection is empty logger.info("Collection is empty.".format( picked_cve_id=cherrypicked_cve_id, )) return logger.debug("Number of CVE Documents in the collection: {}".format( collection.count())) if Config.package_name and Config.cve_id: # user knows the package name, so we don't have to guess ;) doc = [x for x in collection][0] # Collection doesn't support indexing affected, safe = NVDVersions(doc, Config.package_name, Config.ecosystem).run() victims_output = VictimsYamlOutput(ecosystem=Config.ecosystem, cve_doc=doc, winner=PackageNameCandidate( Config.package_name, Decimal('1.0')), candidates=[], affected=affected, fixedin=safe) _log_results(victims_output) victims_output.write() sys.exit(0) for doc in collection: cve_id = doc.cve.id_ try: if not validate_cve(doc): logger.debug( "[{cve_id}] was filtered out by input checks".format( cve_id=cve_id)) continue pkgfile_path = get_pkgfile_path(Config.pkgfile_dir, Config.ecosystem) identifier = get_identifier_cls()(doc, Config.ecosystem, pkgfile_path) candidates = identifier.identify() if not candidates: logger.info( "[{cve_id}] no package name candidates found".format( cve_id=cve_id)) continue selector = VersionSelector(doc, candidates, Config.ecosystem) winner = selector.pick_winner() if not winner: logger.info( "[{cve_id}] no package name found".format(cve_id=cve_id)) continue affected, safe = NVDVersions(doc, winner.package, Config.ecosystem).run() victims_output = VictimsYamlOutput(ecosystem=Config.ecosystem, cve_doc=doc, winner=winner, candidates=candidates, affected=affected, fixedin=safe) _log_results(victims_output) victims_output.write() except Exception as exc: logger.warning( "[{cve_id}] Unexpected exception occurred: {exc}".format( cve_id=cve_id, exc=exc), exc_info=True)