diff options
Diffstat (limited to 'pym/portage/dbapi/vartree.py')
-rw-r--r-- | pym/portage/dbapi/vartree.py | 100 |
1 files changed, 76 insertions, 24 deletions
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 10e48fc19..b42e1c6ea 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -40,6 +40,7 @@ from portage import os from portage import _merge_encoding from portage import _os_merge from portage import _selinux_merge +from portage import _unicode_decode from portage import _unicode_encode from portage.cache.mappings import slot_dict_class @@ -3292,30 +3293,81 @@ class dblink(object): max_dblnk = dblnk self._installed_instance = max_dblnk - myfilelist = [] - mylinklist = [] - paths_with_newlines = [] - srcroot_len = len(srcroot) - def onerror(e): - raise - for parent, dirs, files in os.walk(srcroot, onerror=onerror): - parent = portage._unicode_decode(parent, encoding=_merge_encoding) - for f in files: - f = portage._unicode_decode(f, encoding=_merge_encoding) - file_path = os.path.join(parent, f) - relative_path = file_path[srcroot_len:] - - if "\n" in relative_path: - paths_with_newlines.append(relative_path) - - file_mode = os.lstat(file_path).st_mode - if stat.S_ISREG(file_mode): - myfilelist.append(relative_path) - elif stat.S_ISLNK(file_mode): - # Note: os.walk puts symlinks to directories in the "dirs" - # list and it does not traverse them since that could lead - # to an infinite recursion loop. - mylinklist.append(relative_path) + # We check for unicode encoding issues after src_install. However, + # the check must be repeated here for binary packages (it's + # inexpensive since we call os.walk() here anyway). + unicode_errors = [] + + while True: + + unicode_error = False + + myfilelist = [] + mylinklist = [] + paths_with_newlines = [] + srcroot_len = len(srcroot) + def onerror(e): + raise + for parent, dirs, files in os.walk(srcroot, onerror=onerror): + try: + parent = _unicode_decode(parent, + encoding=_merge_encoding, errors='strict') + except UnicodeDecodeError: + new_parent = _unicode_decode(parent, + encoding=_merge_encoding, errors='replace') + new_parent = _unicode_encode(new_parent, + encoding=_merge_encoding, errors='backslashreplace') + new_parent = _unicode_decode(new_parent, + encoding=_merge_encoding, errors='replace') + os.rename(parent, new_parent) + unicode_error = True + unicode_errors.append(new_parent[srcroot_len:]) + break + + for fname in files: + try: + fname = _unicode_decode(fname, + encoding=_merge_encoding, errors='strict') + except UnicodeDecodeError: + fpath = portage._os.path.join( + parent.encode(_merge_encoding), fname) + new_fname = _unicode_decode(fname, + encoding=_merge_encoding, errors='replace') + new_fname = _unicode_encode(new_fname, + encoding=_merge_encoding, errors='backslashreplace') + new_fname = _unicode_decode(new_fname, + encoding=_merge_encoding, errors='replace') + new_fpath = os.path.join(parent, new_fname) + os.rename(fpath, new_fpath) + unicode_error = True + unicode_errors.append(new_fpath[srcroot_len:]) + fname = new_fname + fpath = new_fpath + else: + fpath = os.path.join(parent, fname) + + relative_path = fpath[srcroot_len:] + + if "\n" in relative_path: + paths_with_newlines.append(relative_path) + + file_mode = os.lstat(fpath).st_mode + if stat.S_ISREG(file_mode): + myfilelist.append(relative_path) + elif stat.S_ISLNK(file_mode): + # Note: os.walk puts symlinks to directories in the "dirs" + # list and it does not traverse them since that could lead + # to an infinite recursion loop. + mylinklist.append(relative_path) + + if unicode_error: + break + + if not unicode_error: + break + + if unicode_errors: + eerror(portage._merge_unicode_error(unicode_errors)) if paths_with_newlines: msg = [] |