On Tue, 27 Dec 2016 13:33:55 -0800 Zac Medico <zmed...@gentoo.org> wrote:
> Fix the binarytree._read_metadata method to return empty strings for > undefined metadata values, in order to fulfill a contract with the > _pkg_str class. This prevents an AttributeError triggered by old > binary packages which have undefined repository metadata, as reported > in bug 603826. > > X-Gentoo-bug: 603826 > X-Gentoo-bug-url: https://bugs.gentoo.org/603826 > --- > pym/portage/dbapi/bintree.py | 31 +++++++++++++++++++++++++------ > pym/portage/versions.py | 8 +++++++- > 2 files changed, 32 insertions(+), 7 deletions(-) > > diff --git a/pym/portage/dbapi/bintree.py > b/pym/portage/dbapi/bintree.py index f483059..3341889 100644 > --- a/pym/portage/dbapi/bintree.py > +++ b/pym/portage/dbapi/bintree.py > @@ -1,4 +1,4 @@ > -# Copyright 1998-2014 Gentoo Foundation > +# Copyright 1998-2016 Gentoo Foundation > # Distributed under the terms of the GNU General Public License v2 > > from __future__ import unicode_literals > @@ -1041,12 +1041,12 @@ class binarytree(object): > noiselevel=-1) > return > metadata = self._read_metadata(full_path, s) > - slot = metadata.get("SLOT") > + invalid_depend = False > try: > self._eval_use_flags(cpv, metadata) > except portage.exception.InvalidDependString: > - slot = None > - if slot is None: > + invalid_depend = True > + if invalid_depend or not metadata.get("SLOT"): > writemsg(_("!!! Invalid binary package: > '%s'\n") % full_path, noiselevel=-1) > return > @@ -1126,6 +1126,21 @@ class binarytree(object): > return cpv > > def _read_metadata(self, filename, st, keys=None): > + """ > + Read metadata from a binary package. The returned > metadata > + dictionary will contain empty strings for any values > that > + are undefined (this is important because the > _pkg_str class > + distinguishes between missing and undefined values). > + > + @param filename: File path of the binary package > + @type filename: string > + @param st: stat result for the binary package > + @type st: os.stat_result > + @param keys: optional list of specific metadata keys > to retrieve > + @type keys: iterable > + @rtype: dict > + @return: package metadata > + """ > if keys is None: > keys = self.dbapi._aux_cache_keys > metadata = self.dbapi._aux_cache_slot_dict() > @@ -1139,10 +1154,14 @@ class binarytree(object): > metadata[k] = _unicode(st.st_size) > else: > v = > binary_metadata.get(_unicode_encode(k)) > - if v is not None: > + if v is None: > + if k == "EAPI": > + metadata[k] = "0" > + else: > + metadata[k] = "" > + else: > v = _unicode_decode(v) > metadata[k] = " > ".join(v.split()) > - metadata.setdefault("EAPI", "0") > return metadata > > def _inject_file(self, pkgindex, cpv, filename): > diff --git a/pym/portage/versions.py b/pym/portage/versions.py > index a028d93..adfb1c3 100644 > --- a/pym/portage/versions.py > +++ b/pym/portage/versions.py > @@ -1,5 +1,5 @@ > # versions.py -- core Portage functionality > -# Copyright 1998-2014 Gentoo Foundation > +# Copyright 1998-2016 Gentoo Foundation > # Distributed under the terms of the GNU General Public License v2 > > from __future__ import unicode_literals > @@ -359,6 +359,12 @@ class _pkg_str(_unicode): > Instances are typically created in dbapi.cp_list() or the > Atom contructor, and propagate from there. Generally, code that > pickles these objects will manually convert them to a plain unicode > object first. + > + Instances of this class will have missing attributes for > metadata that > + has not been passed into the constructor. The missing > attributes are > + used to distinguish missing metadata values from undefined > metadata values. > + For example, the repo attribute will be missing if the > 'repository' key > + is missing from the metadata dictionary. > """ > > def __new__(cls, cpv, metadata=None, settings=None, > eapi=None, LGTM -- Brian Dolbec <dolsen>