parseManifest2: handle space in name, bug 450736
authorZac Medico <zmedico@gentoo.org>
Tue, 8 Jan 2013 00:56:12 +0000 (16:56 -0800)
committerZac Medico <zmedico@gentoo.org>
Tue, 8 Jan 2013 00:56:12 +0000 (16:56 -0800)
pym/portage/manifest.py

index a75c63a691c79acb8e2a9f10633ba1b263bdf2be..18ec5aa27abba6c3b35719e067f84a0f2056ed23 100644 (file)
@@ -1,8 +1,9 @@
-# Copyright 1999-2012 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 import errno
 import io
+import re
 import sys
 import warnings
 
@@ -25,8 +26,13 @@ from portage.const import (MANIFEST1_HASH_FUNCTIONS, MANIFEST2_HASH_DEFAULTS,
        MANIFEST2_HASH_FUNCTIONS, MANIFEST2_IDENTIFIERS, MANIFEST2_REQUIRED_HASH)
 from portage.localization import _
 
+_manifest_re = re.compile(
+       r'^(' + '|'.join(MANIFEST2_IDENTIFIERS) + ') (.*)( \d+( \S+ \S+)+)$',
+       re.UNICODE)
+
 if sys.hexversion >= 0x3000000:
        _unicode = str
+       basestring = str
 else:
        _unicode = unicode
 
@@ -66,18 +72,17 @@ def guessThinManifestFileType(filename):
                return None
        return "DIST"
 
-def parseManifest2(mysplit):
+def parseManifest2(line):
+       if not isinstance(line, basestring):
+               line = ' '.join(line)
        myentry = None
-       if len(mysplit) > 4 and mysplit[0] in MANIFEST2_IDENTIFIERS:
-               mytype = mysplit[0]
-               myname = mysplit[1]
-               try:
-                       mysize = int(mysplit[2])
-               except ValueError:
-                       return None
-               myhashes = dict(zip(mysplit[3::2], mysplit[4::2]))
-               myhashes["size"] = mysize
-               myentry = Manifest2Entry(type=mytype, name=myname, hashes=myhashes)
+       match = _manifest_re.match(line)
+       if match is not None:
+               tokens = match.group(3).split()
+               hashes = dict(zip(tokens[1::2], tokens[2::2]))
+               hashes["size"] = int(tokens[0])
+               myentry = Manifest2Entry(type=match.group(1),
+                       name=match.group(2), hashes=hashes)
        return myentry
 
 class ManifestEntry(object):
@@ -208,9 +213,8 @@ class Manifest(object):
                """Parse manifest lines and return a list of manifest entries."""
                for myline in mylines:
                        myentry = None
-                       mysplit = myline.split()
                        for parser in self.parsers:
-                               myentry = parser(mysplit)
+                               myentry = parser(myline)
                                if myentry is not None:
                                        yield myentry
                                        break # go to the next line