← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad-buildd:shell-escape-bytes into launchpad-buildd:master

 

Colin Watson has proposed merging ~cjwatson/launchpad-buildd:shell-escape-bytes into launchpad-buildd:master.

Commit message:
Handle bytes in shell_escape

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad-buildd/+git/launchpad-buildd/+merge/391239

This fixes recipe builds on Python 3.  To avoid locale-dependent problems, we have to specifically encode the author_name parameter to UTF-8, but that caused shlex.quote to fail.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad-buildd:shell-escape-bytes into launchpad-buildd:master.
diff --git a/debian/changelog b/debian/changelog
index 6ce7857..537966c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
 launchpad-buildd (192) UNRELEASED; urgency=medium
 
   * Update Maintainer to launchpad-dev.
+  * Handle bytes in shell_escape, fixing recipe builds on Python 3.
 
  -- Colin Watson <cjwatson@xxxxxxxxxx>  Tue, 22 Sep 2020 01:03:24 +0100
 
diff --git a/lpbuildd/tests/test_util.py b/lpbuildd/tests/test_util.py
index 5ca9ad4..3eb92f9 100644
--- a/lpbuildd/tests/test_util.py
+++ b/lpbuildd/tests/test_util.py
@@ -23,6 +23,11 @@ class TestShellEscape(TestCase):
     def test_single_quotes(self):
         self.assertEqual("'shell'\"'\"'s great'", shell_escape("shell's great"))
 
+    def test_bytes(self):
+        self.assertEqual(
+            u"'\N{SNOWMAN}'".encode("UTF-8"),
+            shell_escape(u"\N{SNOWMAN}".encode("UTF-8")))
+
 
 class TestGetArchBits(TestCase):
 
diff --git a/lpbuildd/util.py b/lpbuildd/util.py
index 052da2c..28b16ab 100644
--- a/lpbuildd/util.py
+++ b/lpbuildd/util.py
@@ -5,10 +5,21 @@ __metaclass__ = type
 
 import os
 try:
-    from shlex import quote as shell_escape
+    from shlex import quote
 except ImportError:
-    from pipes import quote as shell_escape
+    from pipes import quote
 import subprocess
+import sys
+
+
+def shell_escape(s):
+    # It's sometimes necessary to pass arguments as bytes to avoid
+    # locale-dependent problems, but Python 3's shlex.quote doesn't like
+    # that, so work around it.
+    if sys.version_info[0] >= 3 and isinstance(s, bytes):
+        return quote(s.decode("UTF-8")).encode("UTF-8")
+    else:
+        return quote(s)
 
 
 def get_arch_bits(arch):