def generate_intersects_from_pkg_node(self, pkg_node, tag=None): arch = pkg_node.get("arch") if arch is not None: arch = str(arch.strip()).split() if not arch or "*" in arch: arch = None vuln = list(pkg_node.findall("vulnerable")) if not vuln: return None elif len(vuln) > 1: vuln_list = [self.generate_restrict_from_range(x) for x in vuln] vuln = packages.OrRestriction(*vuln_list) else: vuln_list = [self.generate_restrict_from_range(vuln[0])] vuln = vuln_list[0] if arch is not None: vuln = packages.AndRestriction( vuln, packages.PackageRestriction( "keywords", values.ContainmentMatch(all=False, *arch))) invuln = (pkg_node.findall("unaffected")) if not invuln: # wrap it. return packages.KeyedAndRestriction(vuln, tag=tag) invuln_list = [ self.generate_restrict_from_range(x, negate=True) for x in invuln ] invuln = [x for x in invuln_list if x not in vuln_list] if not invuln: if tag is None: return packages.KeyedAndRestriction(vuln, tag=tag) return packages.KeyedAndRestriction(vuln, tag=tag) return packages.KeyedAndRestriction(vuln, tag=tag, *invuln)
def parse_target(restriction, repo, installed_repos, return_none=False): """Use :obj:`parserestrict.parse_match` to produce a list of matches. This matches the restriction against a repo. If multiple pkgs match and a simple package name was provided, then the restriction is applied against installed repos. If multiple matches still exist then pkgs from the 'virtual' category are skipped. If multiple pkgs still match the restriction, AmbiguousQuery is raised otherwise the matched atom is returned. On the other hand, if a globbed match was specified, all repo matches are returned. :param restriction: string to convert. :param repo: :obj:`pkgcore.repository.prototype.tree` instance to search in. :param installed_repos: :obj:`pkgcore.config.domain.all_installed_repos` instance to search in. :param return_none: indicates if no matches raises or returns C{None} :return: a list of matches or C{None}. """ key_matches = {x.unversioned_atom for x in repo.itermatch(restriction)} if not key_matches: if return_none: return None raise NoMatches(restriction) elif len(key_matches) > 1: if any(isinstance(r, restricts.PackageDep) for r in iflatten_instance([restriction])): if len(restriction) > 1: # drop repo specific restrictions, ebuild repos don't match installed pkgs restriction = restriction.remove_restriction( restriction_types=(restricts.RepositoryDep,)) # find installed package matches matches = {x.unversioned_atom for x in installed_repos.itermatch(restriction)} # try removing stub pkgs if there are multiple installed matches or none at all skip_categories = {'acct-group', 'acct-user', 'virtual'} if not matches: matches = {x for x in key_matches if x.category not in skip_categories} elif len(matches) > 1: matches = {x for x in matches if x.category not in skip_categories} if len(matches) == 1: p = matches.pop() # TODO: collapse redundant restrictions? return [packages.KeyedAndRestriction(restriction, p, key=p.key)] raise AmbiguousQuery(restriction, sorted(key_matches)) else: # if a glob was specified then just return every match return key_matches if isinstance(restriction, atom): # atom is guaranteed to be fine, since it's cat/pkg return [restriction] return [packages.KeyedAndRestriction(restriction, key=key_matches.pop().key)]
def __iter__(self): for glsa, matches in find_vulnerable_repo_pkgs(self.glsa_src, self.vdb, grouped=True, arch=self.arch): yield packages.KeyedAndRestriction(glsa[0], restriction.Negate(glsa[1]))
def insert_blockers(self, stack, choices, blocks): # level blockers. was_livefs = choices.current_pkg.repo.livefs for x in blocks: if not was_livefs: self._ensure_livefs_is_loaded(x) rewrote_blocker = self.generate_mangled_blocker(choices, x) l = self.state.add_blocker(choices, rewrote_blocker, key=x.key) if l: # blocker caught something. yay. self._dprint("%s blocker %s hit %s for atom %s pkg %s", (stack[-1].mode, x, l, stack[-1].atom, choices.current_pkg)) if x.weak_blocker: # note that we use the top frame of the stacks' dbs; this # is to allow us to upgrade as needed. # For this to match, it's *only* possible if the blocker is resolved # since the limiter is already in place. result = self._rec_add_atom( packages.KeyedAndRestriction(restriction.Negate(x), _atom.atom(x.key), key=x.key), stack, stack[0].dbs) if not result: # ok, inserted a new version. did it take care of the conflict? # it /may/ not have, via filling a different slot... result = self.state.match_atom(x) if not result: # ignore the blocker, we resolved past it. continue return x, l return None
def parse_atom(restriction, repo, livefs_repos, return_none=False): """Use :obj:`parserestrict.parse_match` to produce a single atom. This matches the restriction against a repo. If multiple pkgs match, then the restriction is applied against installed repos skipping pkgs from the 'virtual' category. If multiple pkgs still match the restriction, AmbiguousQuery is raised otherwise the matched atom is returned. :param restriction: string to convert. :param repo: :obj:`pkgcore.repository.prototype.tree` instance to search in. :param livefs_repos: :obj:`pkgcore.config.domain.all_livefs_repos` instance to search in. :param return_none: indicates if no matches raises or returns C{None} :return: an atom or C{None}. """ key_matches = set(x.key for x in repo.itermatch(restriction)) if not key_matches: raise NoMatches(restriction) elif len(key_matches) > 1: installed_matches = set(x.key for x in livefs_repos.itermatch(restriction) if x.category != 'virtual') if len(installed_matches) == 1: restriction = atom(installed_matches.pop()) else: raise AmbiguousQuery(restriction, sorted(key_matches)) if isinstance(restriction, atom): # atom is guaranteed to be fine, since it's cat/pkg return restriction return packages.KeyedAndRestriction(restriction, key=key_matches.pop())
def add_atoms(self, restricts, **kwds): restricts = [ packages.KeyedAndRestriction(self._vdb_restriction, x, key=x.key) for x in restricts ] return self.overriding_resolver_kls.add_atoms( self, restricts, **kwds)
def parse_target(restriction, repo, livefs_repos, return_none=False): """Use :obj:`parserestrict.parse_match` to produce a list of matches. This matches the restriction against a repo. If multiple pkgs match and a simple package name was provided, then the restriction is applied against installed repos. If multiple matches still exist then pkgs from the 'virtual' category are skipped. If multiple pkgs still match the restriction, AmbiguousQuery is raised otherwise the matched atom is returned. On the other hand, if a globbed match was specified, all repo matches are returned. :param restriction: string to convert. :param repo: :obj:`pkgcore.repository.prototype.tree` instance to search in. :param livefs_repos: :obj:`pkgcore.config.domain.all_livefs_repos` instance to search in. :param return_none: indicates if no matches raises or returns C{None} :return: a list of matches or C{None}. """ key_matches = {x.key for x in repo.itermatch(restriction)} if not key_matches: if return_none: return None raise NoMatches(restriction) elif len(key_matches) > 1: if any( isinstance(r, restricts.PackageDep) for r in iflatten_instance([restriction])): if len(restriction) > 1: # drop repo specific restrictions, ebuild repos will not match installed (vdb) repo restriction = restriction.remove_restriction( restriction_types=(restricts.RepositoryDep, )) # check for installed package matches installed_matches = { x.key for x in livefs_repos.itermatch(restriction) } if len(installed_matches) > 1: # try removing virtuals if there are multiple matches installed_matches = { x for x in installed_matches if not x.startswith('virtual/') } if len(installed_matches) == 1: return [atom(installed_matches.pop())] raise AmbiguousQuery(restriction, sorted(key_matches)) else: # if a glob was specified then just return every match return [atom(x) for x in key_matches] if isinstance(restriction, atom): # atom is guaranteed to be fine, since it's cat/pkg return [restriction] return [packages.KeyedAndRestriction(restriction, key=key_matches.pop())]
def pkg_grouped_iter(self, sorter=None): """yield GLSA restrictions grouped by package key :param sorter: must be either None, or a comparison function """ if sorter is None: sorter = iter pkgs = {} pkgatoms = {} for glsa, pkg, pkgatom, vuln in self.iter_vulnerabilities(): pkgatoms[pkg] = pkgatom pkgs.setdefault(pkg, []).append(vuln) for pkgname in sorter(pkgs): yield packages.KeyedAndRestriction( pkgatoms[pkgname], packages.OrRestriction(*pkgs[pkgname]), key=pkgname)
def parse_target(restriction, repo, livefs_repos, return_none=False): """Use :obj:`parserestrict.parse_match` to produce a list of matches. This matches the restriction against a repo. If multiple pkgs match and a simple package name was provided, then the restriction is applied against installed repos skipping pkgs from the 'virtual' category. If multiple pkgs still match the restriction, AmbiguousQuery is raised otherwise the matched atom is returned. On the other hand, if a globbed match was specified, all repo matches are returned. :param restriction: string to convert. :param repo: :obj:`pkgcore.repository.prototype.tree` instance to search in. :param livefs_repos: :obj:`pkgcore.config.domain.all_livefs_repos` instance to search in. :param return_none: indicates if no matches raises or returns C{None} :return: a list of matches or C{None}. """ key_matches = set(x.key for x in repo.itermatch(restriction)) if not key_matches: if return_none: return None else: raise NoMatches(restriction) elif len(key_matches) > 1: if isinstance(restriction, restricts.PackageDep): # check for installed package name matches installed_matches = set( x.key for x in livefs_repos.itermatch(restriction) if x.category != 'virtual') if len(installed_matches) == 1: return [atom(installed_matches.pop())] else: raise AmbiguousQuery(restriction, sorted(key_matches)) else: # if a glob was specified then just return every match return [atom(x) for x in key_matches] if isinstance(restriction, atom): # atom is guaranteed to be fine, since it's cat/pkg return [restriction] return [packages.KeyedAndRestriction(restriction, key=key_matches.pop())]
def __iter__(self): for glsa, catpkg, pkgatom, vuln in self.iter_vulnerabilities(): yield packages.KeyedAndRestriction(pkgatom, vuln, key=catpkg, tag="GLSA vulnerable:")