def test_round_robin(): db = Database() db.bugs.update(EXPECTED_BUGS) data = io.StringIO() db.save(data) data.seek(0) db2 = Database() db2.load(data) assert db2.bugs == EXPECTED_BUGS
def main() -> int: """CLI interface for kuroneko scraper.""" argp = argparse.ArgumentParser() argp.add_argument('-l', '--limit', type=int, help='Limit the results to LIMIT bugs') argp.add_argument('-o', '--output', default='-', help='Output JSON file (default: - = stdout)') argp.add_argument('-q', '--quiet', action='store_true', help='Disable status output') argp.add_argument('-X', '--exclude-file', type=argparse.FileType(), help='File to read list of excluded bugs from') args = argp.parse_args() if args.output == '-': output = sys.stdout else: output = open(args.output, 'w') exclude: typing.List[int] = [] if args.exclude_file is not None: for line in args.exclude_file: line = line.strip() if line.startswith('#'): continue exclude.extend(int(x) for x in line.split()) exclude_set = frozenset(exclude) db = Database() for i, bug in enumerate(find_security_bugs(limit=args.limit)): if bug.id in exclude_set: continue packages = sorted(split_version_ranges( find_package_specs(bug.summary))) # skip bugs with no packages if not packages: continue # skip RESO/INVALID bugs if bug.resolution == 'INVALID': continue # skip resolved bugs without specific version ranges resolved = bug.resolution != '' if resolved and not all(p[0] in '<>~=' for p in itertools.chain.from_iterable(packages)): continue db.add_bug(bug=bug.id, packages=packages, summary=bug.summary, severity=get_severity(bug.whiteboard), created=bug.creation_time.split('T', 1)[0], resolved=resolved) if not args.quiet: print(f'Found {i+1} bugs', file=sys.stderr) db.save(output) return 0
def test_version_bad(version): db = Database() with pytest.raises(DatabaseError): db.load(io.BytesIO(JSON_DATA.format(version=version).encode()))
def test_version_good(version): db = Database() db.load(io.BytesIO(JSON_DATA.format(version=version).encode())) assert db.bugs == EXPECTED_BUGS
def test_no_magic(): db = Database() with pytest.raises(DatabaseError): db.load(io.BytesIO(b'{"bugs": []}'))
def test_load_database(): db = Database() db.load( io.StringIO( JSON_DATA.format(version='"{}.{}"'.format(*db.SCHEMA_VERSION)))) assert db.bugs == EXPECTED_BUGS
def main() -> int: """CLI interface for kuroneko scraper.""" colorama.init() argp = argparse.ArgumentParser() db_source = argp.add_mutually_exclusive_group() db_source.add_argument('-d', '--database', type=argparse.FileType('r'), help='Use bug database from specified json file ' '(if not specified, database will be fetched ' 'from --database-url)') db_source.add_argument('--database-url', default=DEFAULT_DB_URL, help=f'Fetch bug database from specified URL ' f'(default: {DEFAULT_DB_URL})') argp.add_argument('--cache-file', help=f'File used to store a cached copy of bug database ' f'(default: {DEFAULT_CACHE_PATH})') argp.add_argument('-q', '--quiet', action='store_true', help='Disable progress messages') args = argp.parse_args() # load the database db = Database() if args.database is not None: if not args.quiet: print(f'Using local database {args.database.name}', file=sys.stderr) else: if not args.quiet: print(f'Using remote database {args.database_url}', file=sys.stderr) if args.cache_file is None: os.makedirs(XDG_CACHE_HOME, exist_ok=True) args.cache_file = DEFAULT_CACHE_PATH args.database = cached_get(args.database_url, args.cache_file) if not args.quiet: if isinstance(args.database, io.BytesIO): print('Database update fetched', file=sys.stderr) else: print('Local cache is up-to-date', file=sys.stderr) db.load(args.database) args.database.close() # initialize pkgcore config = load_config() domain = config.get_default('domain') vdb = domain.repos_raw['vdb'] # do a quick search for vulnerable packages restrict = packages_to_restriction(db) if not args.quiet: print('Searching for vulnerable packages', file=sys.stderr) vulnerable = vdb.match(restrict) # match vulnerable packages to bugs if not args.quiet: print(file=sys.stderr) first_one = True for pkg in vulnerable: for bug_pkg, bug in find_applicable_bugs(pkg, db): if first_one: first_one = False else: print() print_bug(bug, bug_pkg, pkg.cpvstr) return 0