[meld/meld-3-16] Debugging bgo#774235. Make error displaying more robust with non-ASCII



commit 4e881ed8b39855c29d6277b121aca34b8e815ee4
Author: Vasily Galkin <galkin-vv ya ru>
Date:   Sun Nov 13 03:58:27 2016 +0300

    Debugging bgo#774235. Make error displaying more robust with non-ASCII
    
    Byte strings that are going to be combined with unicode via + or %
    operators should be explicitly decoded to unicode. Otherwise python
    tries decoding them with ascii-only and raises UnicodeEncodeError on
    bytes >= 0x80.
    This change fixes this problem for bytes returned from functions:
     -GLib.markup_escape_text
     -*Error.strerror

 meld/dirdiff.py     |   17 ++++++++++++-----
 meld/filediff.py    |    2 +-
 meld/patchdialog.py |    2 +-
 3 files changed, 14 insertions(+), 7 deletions(-)
---
diff --git a/meld/dirdiff.py b/meld/dirdiff.py
index ba4ad2a..c8945b5 100644
--- a/meld/dirdiff.py
+++ b/meld/dirdiff.py
@@ -730,7 +730,8 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
                         s = os.lstat(os.path.join(root, e))
                     # Covers certain unreadable symlink cases; see bgo#585895
                     except OSError as err:
-                        error_string = e + err.strerror
+                        error_string = e + err.strerror.decode(
+                            'utf8', 'replace')
                         self.model.add_error(it, error_string, pane)
                         continue
 
@@ -751,7 +752,8 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
                             if err.errno == errno.ENOENT:
                                 error_string = e + ": Dangling symlink"
                             else:
-                                error_string = e + err.strerror
+                                error_string = e + err.strerror.decode(
+                                    'utf8', 'replace')
                             self.model.add_error(it, error_string, pane)
                             differences = True
                     elif stat.S_ISREG(s.st_mode):
@@ -957,12 +959,17 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
                     misc.copytree(src, dst)
                     self.recursively_update(path)
             except (OSError, IOError, shutil.Error) as err:
+                if len(err.args) == 1 and isinstance(err.args[0], unicode):
+                    # str() raises on Exception instance with non-ascii unicode
+                    msg = err.args[0].encode('utf8', 'replace')
+                else:
+                    msg = str(err)
                 misc.error_dialog(
                     _("Error copying file"),
                     _("Couldn't copy %s\nto %s.\n\n%s") % (
-                        GLib.markup_escape_text(src),
-                        GLib.markup_escape_text(dst),
-                        GLib.markup_escape_text(str(err)),
+                        GLib.markup_escape_text(src).decode('utf8', 'replace'),
+                        GLib.markup_escape_text(dst).decode('utf8', 'replace'),
+                        GLib.markup_escape_text(msg).decode('utf8', 'replace'),
                     )
                 )
 
diff --git a/meld/filediff.py b/meld/filediff.py
index 12188af..ab317c5 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -1548,7 +1548,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
             misc.error_dialog(
                 primary=_("Could not save file %s.") % filename,
                 secondary=_("Couldn't save file due to:\n%s") % (
-                    GLib.markup_escape_text(str(err))),
+                    GLib.markup_escape_text(str(err)).decode('utf-8')),
             )
             self.state = melddoc.STATE_SAVING_ERROR
             return
diff --git a/meld/patchdialog.py b/meld/patchdialog.py
index cabaa5f..25b6e75 100644
--- a/meld/patchdialog.py
+++ b/meld/patchdialog.py
@@ -135,7 +135,7 @@ class PatchDialog(gnomeglade.Component):
             error_dialog(
                 primary=_("Could not save file %s.") % filename,
                 secondary=_("Couldn't save file due to:\n%s") % (
-                    GLib.markup_escape_text(str(err))),
+                    GLib.markup_escape_text(str(err)).decode('utf-8')),
             )
 
     def run(self):


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]