[python-debian/master 1/2] deb822: Encoding gymnastics for signed files in text mode.

John Wright jsw at google.com
Tue Oct 21 06:38:48 UTC 2014


---
 debian/changelog     |  7 +++++
 lib/debian/deb822.py | 29 +++++++++++++++----
 tests/test_Changes   | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/test_deb822.py | 12 ++++++++
 4 files changed, 120 insertions(+), 6 deletions(-)
 create mode 100644 tests/test_Changes

diff --git a/debian/changelog b/debian/changelog
index 2a64c9f..49caa97 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+python-debian (0.1.25) UNRELEASED; urgency=medium
+
+  * deb822: More encoding gymnastics to support parsing signed files
+    opened in text mode (Closes: #764380).
+
+ -- John Wright <jsw at debian.org>  Mon, 20 Oct 2014 23:36:44 -0700
+
 python-debian (0.1.24) unstable; urgency=medium
 
   * copyright module: make Copyright objects iterable
diff --git a/lib/debian/deb822.py b/lib/debian/deb822.py
index 85bb7bc..0c0748e 100644
--- a/lib/debian/deb822.py
+++ b/lib/debian/deb822.py
@@ -1219,14 +1219,18 @@ class _gpg_multivalued(_multivalued):
             sequence = kwargs.get("sequence", None)
 
         if sequence is not None:
+            # If the input is a unicode object or a file opened in text mode,
+            # we'll need to encode it back to bytes for gpg.  If it's not
+            # actually in the encoding that we guess, then this probably won't
+            # verify correctly, but this is the best we can reasonably manage.
+            # For accurate verification, the file should be opened in binary
+            # mode.
+            encoding = (getattr(sequence, 'encoding', None)
+                        or kwargs.get('encoding', 'utf-8') or 'utf-8')
             if isinstance(sequence, bytes):
                 self.raw_text = sequence
             elif isinstance(sequence, six.string_types):
-                # If the file is really in some other encoding, then this
-                # probably won't verify correctly, but this is the best we
-                # can reasonably manage.  For accurate verification, the
-                # file should be opened in binary mode.
-                self.raw_text = sequence.encode('utf-8')
+                self.raw_text = sequence.encode(encoding)
             elif hasattr(sequence, "items"):
                 # sequence is actually a dict(-like) object, so we don't have
                 # the raw text.
@@ -1234,7 +1238,8 @@ class _gpg_multivalued(_multivalued):
             else:
                 try:
                     gpg_pre_lines, lines, gpg_post_lines = \
-                            self.split_gpg_and_payload(sequence)
+                        self.split_gpg_and_payload(
+                            self._bytes(s, encoding) for s in sequence)
                 except EOFError:
                     # Empty input
                     gpg_pre_lines = lines = gpg_post_lines = []
@@ -1254,6 +1259,18 @@ class _gpg_multivalued(_multivalued):
 
         _multivalued.__init__(self, *args, **kwargs)
 
+    @staticmethod
+    def _bytes(s, encoding):
+        """Converts s to bytes if necessary, using encoding.
+
+        If s is already bytes type, returns it directly.
+        """
+        if isinstance(s, bytes):
+            return s
+        if isinstance(s, six.string_types):
+            return s.encode(encoding)
+        raise TypeError('bytes or unicode/string required')
+
 
 class Dsc(_gpg_multivalued):
     _multivalued_fields = {
diff --git a/tests/test_Changes b/tests/test_Changes
new file mode 100644
index 0000000..3ce6e19
--- /dev/null
+++ b/tests/test_Changes
@@ -0,0 +1,78 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+Format: 1.8
+Date: Wed, 10 Sep 2014 23:18:38 -0700
+Source: python-debian
+Binary: python-debian python3-debian
+Architecture: source all
+Version: 0.1.23
+Distribution: unstable
+Urgency: medium
+Maintainer: Debian python-debian Maintainers <pkg-python-debian-maint at lists.alioth.debian.org>
+Changed-By: John Wright <jsw at debian.org>
+Description:
+ python-debian - Python modules to work with Debian-related data formats
+ python3-debian - Python 3 modules to work with Debian-related data formats
+Closes: 634848 655988 670679 671485 695932 712513 718355 732599 743174 760488
+Changes:
+ python-debian (0.1.23) unstable; urgency=medium
+ .
+   [ Stuart Prescott ]
+   * Add sha512 sums to Release and Sources (Closes: #732599).
+   * Use warnings rather than stderr in PkgRelation (Closes: #712513).
+   * Expose the list of bugs closed by a changelog entry; thanks to Jelmer
+     Vernooi and Stefano Rivera for patches (Closes: #634848).
+   * Add support for .deb with uncompressed data.tar member (Closes: #718355).
+   * Prefer the internal parser rather than apt's TagFile for processing deb822
+     files unless explicitly called to process Packages or Sources files:
+     - prevents paragraph parsing truncating on comments (Closes: #743174).
+     - fix parsing of paragraphs when separated by more whitespace than just a
+       newline (Closes: #655988). (Finally fixing interactions with devscripts'
+       wrap-and-sort!)
+   * Parse foreign architecture (package:any) relationships and also other
+     multi-arch related relationships (Closes: #670679)
+   * Parse build-profiles syntax.
+ .
+   [ John Wright ]
+   * Fix a GPG validation bug.  With some trailing whitespace, the code
+     could be tricked into validating a signature, but using the bogus
+     data after the signed section (Closes: #695932).
+   * Drop support for python2.5.  (This allows us to do fewer import hacks
+     in deb822, and probably other modules as well.)
+   * Add a deb822.RestrictedWrapper class, for exposing read-only access
+     to a Deb822 instance's field values as strings, while restricting
+     write access to some fields, which are exposed via properties.
+   * deb822.Deb822Dict.dump: Add a text_mode parameter for dumping to
+     file(-like) objects that assume text/unicode input.
+   * Add a copyright module, for parsing machine-readable debian/copyright
+     files (Closes: #671485).
+   * Make deb822 tests hermetic with respect to debian-keyring updates
+     (Closes: #760488).
+Checksums-Sha1:
+ 12dfdc516cca4cb97db35d2058b557ce86ab4226 1861 python-debian_0.1.23.dsc
+ ad2363927297a16bd152f08ff268b2af147731d5 288092 python-debian_0.1.23.tar.xz
+ a9808610d3fe406bb66e6bbdd5c69201b669ae13 70630 python-debian_0.1.23_all.deb
+ 61b44f5a2700e399d78a2c8ee795fe25d40cd08d 50384 python3-debian_0.1.23_all.deb
+Checksums-Sha256:
+ e24ef01c4d285c442577b53644211510c10767a58a6e1c8df2aa7c1b1332b00b 1861 python-debian_0.1.23.dsc
+ cb057ba2003fd7738f295b15a1e24f1983ce8bc3725613b4ce80013a55fb0b56 288092 python-debian_0.1.23.tar.xz
+ d55ecce6400a5f8504aa8d8ce76846aab5cebea6003a1e1a240ba1f93e6f88f6 70630 python-debian_0.1.23_all.deb
+ ebed90218dde5f9a5a5d598db3533208a0bf9683b717c2c597ab95377ca0d69b 50384 python3-debian_0.1.23_all.deb
+Files:
+ 7d81d9acc4168890e10a6f4902c53ecc 70630 python optional python-debian_0.1.23_all.deb
+ 2ae2e6469ffb87c8d0ea6582c22bd48b 50384 python optional python3-debian_0.1.23_all.deb
+ b3e9d9f696604ab144d5aed316c808dc 1861 python optional python-debian_0.1.23.dsc
+ f5458e5d1379feaf5a837e7f866b1b7a 288092 python optional python-debian_0.1.23.tar.xz
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+
+iQEcBAEBCgAGBQJUEUIQAAoJEOdiPQlLQO87z2cH/3LroAIC4gDT+ux4K11jwaRX
+swQId21MKCOxDncnNUx+cwPqUi0YuHhOhp8XEsy7/7g1gDSddJJ+2WkpN0PKgLSx
+2lyLtF6BJ+JykAOV3sPz993q5b0+7QJ3/3Fwq2ICzS0bFsLB9XpsRK75uogr6knp
+gfOnEn03cyK5JurRdmmK1w0wVtS7ZyktaGYlknZi7xxwIb+IbVgDebpPxHj3TDzC
+U9QHA5ZVziuNPeVWqgimk8BWJH0ngL+MRc5frAed4M6Zyd+mug1IetJzxaD+mBzm
+W54HlaARddfiVYnXR8FaQVXEYOj76xirQf1jAaLxizwmz4C6zt6YqD2CikmTW7w=
+=jb3+
+-----END PGP SIGNATURE-----
diff --git a/tests/test_deb822.py b/tests/test_deb822.py
index d2c79e1..698366b 100755
--- a/tests/test_deb822.py
+++ b/tests/test_deb822.py
@@ -943,6 +943,18 @@ Description: python modules to work with Debian-related data formats
         self.assertEqual(len(release['SHA512']), 61)
         self.assertEqual(release['SHA512'][0]['size'], '113433')
 
+    def test_changes_binary_mode(self):
+        """Trivial parse test for a signed file in binary mode"""
+        with io.open('test_Changes', 'rb') as f:
+            changes = deb822.Changes(f)
+        self.assertEqual('python-debian', changes['Source'])
+
+    def test_changes_text_mode(self):
+        """Trivial parse test for a signed file in text mode"""
+        with io.open('test_Changes', 'r', encoding='utf-8') as f:
+            changes = deb822.Changes(f)
+        self.assertEqual('python-debian', changes['Source'])
+
 
 class TestPkgRelations(unittest.TestCase):
     # TODO(jsw): Stop overriding this for Python versions that actually include
-- 
1.9.1





More information about the pkg-python-debian-commits mailing list