1 |
Fix the binarytree._read_metadata method to return empty strings for |
2 |
undefined metadata values, in order to fulfill a contract with the |
3 |
_pkg_str class. This prevents an AttributeError triggered by old |
4 |
binary packages which have undefined repository metadata, as reported |
5 |
in bug 603826. |
6 |
|
7 |
X-Gentoo-bug: 603826 |
8 |
X-Gentoo-bug-url: https://bugs.gentoo.org/603826 |
9 |
--- |
10 |
pym/portage/dbapi/bintree.py | 31 +++++++++++++++++++++++++------ |
11 |
pym/portage/versions.py | 8 +++++++- |
12 |
2 files changed, 32 insertions(+), 7 deletions(-) |
13 |
|
14 |
diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py |
15 |
index f483059..3341889 100644 |
16 |
--- a/pym/portage/dbapi/bintree.py |
17 |
+++ b/pym/portage/dbapi/bintree.py |
18 |
@@ -1,4 +1,4 @@ |
19 |
-# Copyright 1998-2014 Gentoo Foundation |
20 |
+# Copyright 1998-2016 Gentoo Foundation |
21 |
# Distributed under the terms of the GNU General Public License v2 |
22 |
|
23 |
from __future__ import unicode_literals |
24 |
@@ -1041,12 +1041,12 @@ class binarytree(object): |
25 |
noiselevel=-1) |
26 |
return |
27 |
metadata = self._read_metadata(full_path, s) |
28 |
- slot = metadata.get("SLOT") |
29 |
+ invalid_depend = False |
30 |
try: |
31 |
self._eval_use_flags(cpv, metadata) |
32 |
except portage.exception.InvalidDependString: |
33 |
- slot = None |
34 |
- if slot is None: |
35 |
+ invalid_depend = True |
36 |
+ if invalid_depend or not metadata.get("SLOT"): |
37 |
writemsg(_("!!! Invalid binary package: '%s'\n") % full_path, |
38 |
noiselevel=-1) |
39 |
return |
40 |
@@ -1126,6 +1126,21 @@ class binarytree(object): |
41 |
return cpv |
42 |
|
43 |
def _read_metadata(self, filename, st, keys=None): |
44 |
+ """ |
45 |
+ Read metadata from a binary package. The returned metadata |
46 |
+ dictionary will contain empty strings for any values that |
47 |
+ are undefined (this is important because the _pkg_str class |
48 |
+ distinguishes between missing and undefined values). |
49 |
+ |
50 |
+ @param filename: File path of the binary package |
51 |
+ @type filename: string |
52 |
+ @param st: stat result for the binary package |
53 |
+ @type st: os.stat_result |
54 |
+ @param keys: optional list of specific metadata keys to retrieve |
55 |
+ @type keys: iterable |
56 |
+ @rtype: dict |
57 |
+ @return: package metadata |
58 |
+ """ |
59 |
if keys is None: |
60 |
keys = self.dbapi._aux_cache_keys |
61 |
metadata = self.dbapi._aux_cache_slot_dict() |
62 |
@@ -1139,10 +1154,14 @@ class binarytree(object): |
63 |
metadata[k] = _unicode(st.st_size) |
64 |
else: |
65 |
v = binary_metadata.get(_unicode_encode(k)) |
66 |
- if v is not None: |
67 |
+ if v is None: |
68 |
+ if k == "EAPI": |
69 |
+ metadata[k] = "0" |
70 |
+ else: |
71 |
+ metadata[k] = "" |
72 |
+ else: |
73 |
v = _unicode_decode(v) |
74 |
metadata[k] = " ".join(v.split()) |
75 |
- metadata.setdefault("EAPI", "0") |
76 |
return metadata |
77 |
|
78 |
def _inject_file(self, pkgindex, cpv, filename): |
79 |
diff --git a/pym/portage/versions.py b/pym/portage/versions.py |
80 |
index a028d93..adfb1c3 100644 |
81 |
--- a/pym/portage/versions.py |
82 |
+++ b/pym/portage/versions.py |
83 |
@@ -1,5 +1,5 @@ |
84 |
# versions.py -- core Portage functionality |
85 |
-# Copyright 1998-2014 Gentoo Foundation |
86 |
+# Copyright 1998-2016 Gentoo Foundation |
87 |
# Distributed under the terms of the GNU General Public License v2 |
88 |
|
89 |
from __future__ import unicode_literals |
90 |
@@ -359,6 +359,12 @@ class _pkg_str(_unicode): |
91 |
Instances are typically created in dbapi.cp_list() or the Atom contructor, |
92 |
and propagate from there. Generally, code that pickles these objects will |
93 |
manually convert them to a plain unicode object first. |
94 |
+ |
95 |
+ Instances of this class will have missing attributes for metadata that |
96 |
+ has not been passed into the constructor. The missing attributes are |
97 |
+ used to distinguish missing metadata values from undefined metadata values. |
98 |
+ For example, the repo attribute will be missing if the 'repository' key |
99 |
+ is missing from the metadata dictionary. |
100 |
""" |
101 |
|
102 |
def __new__(cls, cpv, metadata=None, settings=None, eapi=None, |
103 |
-- |
104 |
2.7.4 |