]> git.ipfire.org Git - thirdparty/patchwork.git/commitdiff
pwclient: Fix silent crash on python 2
authorRobin Jarry <robin.jarry@6wind.com>
Tue, 2 May 2017 14:51:51 +0000 (16:51 +0200)
committerStephen Finucane <stephen@that.guru>
Tue, 2 May 2017 20:48:01 +0000 (21:48 +0100)
Replacing sys.stdout and sys.stderr can cause obscure crashes when
trying to write non unicode data. The interpreter is terminated with
SIGINT without any specific error writen on the console.

  rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f964820e8d0},
  {0x559f50, [], SA_RESTORER, 0x7f964820e8d0}, 8) = 0

This happens easily when there is an untrapped exception which should
lead to printing a traceback on stderr.

The only way to prevent UnicodeEncodeErrors is to make sure that one of
the locale-related environment variables (LC_ALL, LANG, LANGUAGE, etc.)
is set. Python will use the correct encoding accordingly.

Add a note about this on `pwclient --help`. Also, display a help message
when an encoding error occurs.

Fixes: 046419a3bf8f ("pwclient: Fix encoding problems")
Signed-off-by: Robin Jarry <robin.jarry@6wind.com>
Signed-off-by: Stephen Finucane <stephen@that.guru>
patchwork/bin/pwclient

index ed0351bf5288056ba95ecf8b7881cbeec46c3c3e..5fcb0844b92307ae736440072b198090e74167e8 100755 (executable)
@@ -41,16 +41,7 @@ except ImportError:
 import shutil
 import re
 import io
-import locale
 
-if sys.version_info.major == 2:
-    # hack to make writing unicode to standard output/error work on Python 2
-    OUT_ENCODING = (sys.stdout.encoding or locale.getpreferredencoding() or
-                    os.getenv('PYTHONIOENCODING', 'utf-8'))
-    sys.stdout = io.open(sys.stdout.fileno(), mode='w',
-                         encoding=OUT_ENCODING, errors='replace')
-    sys.stderr = io.open(sys.stderr.fileno(), mode='w',
-                         encoding=OUT_ENCODING, errors='replace')
 
 # Default Patchwork remote XML-RPC server URL
 # This script will check the PW_XMLRPC_URL environment variable
@@ -461,7 +452,14 @@ def main():
 
     action_parser = argparse.ArgumentParser(
         prog='pwclient',
-        epilog='Use \'pwclient <command> --help\' for more info',
+        formatter_class=argparse.RawTextHelpFormatter,
+        epilog="""Use 'pwclient <command> --help' for more info.
+
+To avoid unicode encode/decode errors, you should export the LANG or LC_ALL
+environment variables according to the configured locales on your system. If
+these variables are already set, make sure that they point to valid and
+installed locales.
+""",
     )
 
     subparsers = action_parser.add_subparsers(
@@ -557,13 +555,9 @@ def main():
         help='''Set patch archived state'''
     )
     update_parser.set_defaults(subcmd='update')
-    list_parser = subparsers.add_parser("list",
-                                        # aliases=['search'],
-                                        parents=[filter_parser],
-                                        help='''List patches, using the optional filters specified
-        below and an optional substring to search for patches
-        by name'''
-                                        )
+    list_parser = subparsers.add_parser(
+        'list', parents=[filter_parser],
+        help='List patches using optional filters')
     list_parser.set_defaults(subcmd='list')
     search_parser = subparsers.add_parser("search",
                                           parents=[filter_parser],
@@ -822,4 +816,11 @@ def main():
 
 
 if __name__ == "__main__":
-    main()
+    try:
+        main()
+    except (UnicodeEncodeError, UnicodeDecodeError) as e:
+        import traceback
+        traceback.print_exc()
+        sys.stderr.write('Try exporting the LANG or LC_ALL env vars. See '
+                         'pwclient --help for more details.\n')
+        sys.exit(1)