1 |
Author: zmedico |
2 |
Date: 2009-08-24 00:29:34 +0000 (Mon, 24 Aug 2009) |
3 |
New Revision: 14133 |
4 |
|
5 |
Modified: |
6 |
main/trunk/pym/portage/dbapi/vartree.py |
7 |
Log: |
8 |
Bug #282306 - Inside dblink._match_contents(), fall back to utf_8 encoding if |
9 |
a path cannot be encoded under the user's chosen encoding. This should |
10 |
fix the traceback shown in bug #281199, comment #26. |
11 |
|
12 |
|
13 |
Modified: main/trunk/pym/portage/dbapi/vartree.py |
14 |
=================================================================== |
15 |
--- main/trunk/pym/portage/dbapi/vartree.py 2009-08-23 16:38:24 UTC (rev 14132) |
16 |
+++ main/trunk/pym/portage/dbapi/vartree.py 2009-08-24 00:29:34 UTC (rev 14133) |
17 |
@@ -2620,23 +2620,65 @@ |
18 |
if the file is not owned by this package. |
19 |
""" |
20 |
|
21 |
- os = _os_merge |
22 |
- |
23 |
filename = _unicode_decode(filename, |
24 |
encoding=_encodings['content'], errors='strict') |
25 |
|
26 |
destroot = _unicode_decode(destroot, |
27 |
encoding=_encodings['content'], errors='strict') |
28 |
|
29 |
+ # The given filename argument might have a different encoding than the |
30 |
+ # the filenames contained in the contents, so use separate wrapped os |
31 |
+ # modules for each. The basename is more likely to contain non-ascii |
32 |
+ # characters than the directory path, so use os_filename_arg for all |
33 |
+ # operations involving the basename of the filename arg. |
34 |
+ os_filename_arg = _os_merge |
35 |
+ os = _os_merge |
36 |
+ |
37 |
+ try: |
38 |
+ _unicode_encode(filename, |
39 |
+ encoding=_encodings['merge'], errors='strict') |
40 |
+ except UnicodeEncodeError: |
41 |
+ # The package appears to have been merged with a |
42 |
+ # different value of sys.getfilesystemencoding(), |
43 |
+ # so fall back to utf_8 if appropriate. |
44 |
+ try: |
45 |
+ _unicode_encode(filename, |
46 |
+ encoding=_encodings['fs'], errors='strict') |
47 |
+ except UnicodeEncodeError: |
48 |
+ pass |
49 |
+ else: |
50 |
+ os_filename_arg = portage.os |
51 |
+ |
52 |
destfile = normalize_path( |
53 |
- os.path.join(destroot, filename.lstrip(os.path.sep))) |
54 |
+ os_filename_arg.path.join(destroot, |
55 |
+ filename.lstrip(os_filename_arg.path.sep))) |
56 |
|
57 |
pkgfiles = self.getcontents() |
58 |
if pkgfiles and destfile in pkgfiles: |
59 |
return destfile |
60 |
if pkgfiles: |
61 |
- basename = os.path.basename(destfile) |
62 |
+ basename = os_filename_arg.path.basename(destfile) |
63 |
if self._contents_basenames is None: |
64 |
+ |
65 |
+ try: |
66 |
+ for x in pkgfiles: |
67 |
+ _unicode_encode(x, |
68 |
+ encoding=_encodings['merge'], |
69 |
+ errors='strict') |
70 |
+ except UnicodeEncodeError: |
71 |
+ # The package appears to have been merged with a |
72 |
+ # different value of sys.getfilesystemencoding(), |
73 |
+ # so fall back to utf_8 if appropriate. |
74 |
+ try: |
75 |
+ for x in pkgfiles: |
76 |
+ _unicode_encode(x, |
77 |
+ encoding=_encodings['fs'], |
78 |
+ errors='strict') |
79 |
+ except UnicodeEncodeError: |
80 |
+ pass |
81 |
+ else: |
82 |
+ os = portage.os |
83 |
+ |
84 |
self._contents_basenames = set( |
85 |
os.path.basename(x) for x in pkgfiles) |
86 |
if basename not in self._contents_basenames: |
87 |
@@ -2647,15 +2689,36 @@ |
88 |
|
89 |
# Use stat rather than lstat since we want to follow |
90 |
# any symlinks to the real parent directory. |
91 |
- parent_path = os.path.dirname(destfile) |
92 |
+ parent_path = os_filename_arg.path.dirname(destfile) |
93 |
try: |
94 |
- parent_stat = os.stat(parent_path) |
95 |
+ parent_stat = os_filename_arg.stat(parent_path) |
96 |
except EnvironmentError, e: |
97 |
if e.errno != errno.ENOENT: |
98 |
raise |
99 |
del e |
100 |
return False |
101 |
if self._contents_inodes is None: |
102 |
+ |
103 |
+ if os is _os_merge: |
104 |
+ try: |
105 |
+ for x in pkgfiles: |
106 |
+ _unicode_encode(x, |
107 |
+ encoding=_encodings['merge'], |
108 |
+ errors='strict') |
109 |
+ except UnicodeEncodeError: |
110 |
+ # The package appears to have been merged with a |
111 |
+ # different value of sys.getfilesystemencoding(), |
112 |
+ # so fall back to utf_8 if appropriate. |
113 |
+ try: |
114 |
+ for x in pkgfiles: |
115 |
+ _unicode_encode(x, |
116 |
+ encoding=_encodings['fs'], |
117 |
+ errors='strict') |
118 |
+ except UnicodeEncodeError: |
119 |
+ pass |
120 |
+ else: |
121 |
+ os = portage.os |
122 |
+ |
123 |
self._contents_inodes = {} |
124 |
parent_paths = set() |
125 |
for x in pkgfiles: |
126 |
@@ -2677,11 +2740,12 @@ |
127 |
self._contents_inodes[inode_key] = p_path_list |
128 |
if p_path not in p_path_list: |
129 |
p_path_list.append(p_path) |
130 |
+ |
131 |
p_path_list = self._contents_inodes.get( |
132 |
(parent_stat.st_dev, parent_stat.st_ino)) |
133 |
if p_path_list: |
134 |
for p_path in p_path_list: |
135 |
- x = os.path.join(p_path, basename) |
136 |
+ x = os_filename_arg.path.join(p_path, basename) |
137 |
if x in pkgfiles: |
138 |
return x |