From 050767702cbbd8724a542ceb5ed7f618d88bd07f Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 18 Dec 2013 21:09:42 -0800 Subject: [PATCH] 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 --- gpg-migrate.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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): -- 2.26.2