From: W. Trevor King Date: Thu, 19 Dec 2013 05:09:42 +0000 (-0800) Subject: Add a flexible packet-parsing framework X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=050767702cbbd8724a542ceb5ed7f618d88bd07f;p=gpg-migrate.git Add a flexible packet-parsing framework Shunting packet-type processing out to type-specific methods. For example, 'public-key packet' packets will be parsed by PGPPacket._parse_public_key_packet. From the re docs [1]: '+' Causes the resulting RE to match 1 or more repetitions of the preceding RE. ab+ will match 'a' followed by any non-zero number of 'b's; it will not match just 'a'. ... \W For Unicode (str) patterns: Matches Unicode word characters; this includes most characters that can be part of a word in any language, as well as numbers and the underscore. If the ASCII flag is used, only [a-zA-Z0-9_] is matched (but the flag affects the entire regular expression, so in such cases using an explicit [a-zA-Z0-9_] may be a better choice). For 8-bit (bytes) patterns: Matches characters considered alphanumeric in the ASCII character set; this is equivalent to [a-zA-Z0-9_]. [1]: http://docs.python.org/3/library/re.html#regular-expression-syntax --- diff --git a/gpg-migrate.py b/gpg-migrate.py index c41ddd4..f754aef 100755 --- a/gpg-migrate.py +++ b/gpg-migrate.py @@ -1,5 +1,6 @@ #!/usr/bin/python +import re as _re import subprocess as _subprocess import struct as _struct @@ -50,6 +51,11 @@ class PGPPacket (dict): 63: 'private', } + _clean_type_regex = _re.compile('\W+') + + def _clean_type(self): + return self._clean_type_regex.sub('_', self['type']) + def from_bytes(self, data): offset = self._parse_header(data=data) packet = data[offset:offset + self['length']] @@ -57,6 +63,12 @@ class PGPPacket (dict): raise ValueError('packet too short ({} < {})'.format( len(packet), self['length'])) offset += self['length'] + method_name = '_parse_{}'.format(self._clean_type()) + method = getattr(self, method_name, None) + if not method: + raise NotImplementedError( + 'cannot parse packet type {!r}'.format(self['type'])) + method(data=packet) return offset def _parse_header(self, data):