diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-01-17 11:35:15 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-01-17 11:35:15 +0100 |
commit | 23e1f441997e082d8ca876853a88ee54b0be4676 (patch) | |
tree | 494592452b4dfa148d0ddb7a2ae2215af00a51b6 /ffi | |
parent | 739b528ec5b1c94ee3c5c1e37bb88c810c48a0a4 (diff) |
ffi: Fix last commit.
- Fixes error handling in the Python bindings.
Diffstat (limited to 'ffi')
-rw-r--r-- | ffi/lang/python/sequoia/core.py | 34 | ||||
-rw-r--r-- | ffi/lang/python/sequoia/glue.py | 14 | ||||
-rw-r--r-- | ffi/lang/python/sequoia/openpgp.py | 108 |
3 files changed, 80 insertions, 76 deletions
diff --git a/ffi/lang/python/sequoia/core.py b/ffi/lang/python/sequoia/core.py index 9810c27b..117e1207 100644 --- a/ffi/lang/python/sequoia/core.py +++ b/ffi/lang/python/sequoia/core.py @@ -3,7 +3,7 @@ from enum import Enum from _sequoia import ffi, lib from .error import Error -from .glue import SQObject +from .glue import SQObject, invoke class NetworkPolicy(Enum): Offline = lib.SQ_NETWORK_POLICY_OFFLINE @@ -45,12 +45,11 @@ class AbstractReader(SQObject, io.RawIOBase): return False def readinto(self, buf): - bytes_read = lib.sq_reader_read( - self.context().ref(), self.ref(), - ffi.cast("uint8_t *", ffi.from_buffer(buf)), len(buf)) - if bytes_read < 0: - raise Error._last(self.context()) - return bytes_read + return invoke( + lib.sq_reader_read, + self.ref(), + ffi.cast("uint8_t *", ffi.from_buffer(buf)), + len(buf)) def close(self): self._delete() @@ -66,9 +65,8 @@ class Reader(AbstractReader): @classmethod def open(cls, ctx, filename): return Reader( - lib.sq_reader_from_file( - ctx.ref(), - filename.encode()), + invoke(lib.sq_reader_from_file, + filename.encode()), context=ctx) @classmethod @@ -92,12 +90,11 @@ class AbstractWriter(SQObject, io.RawIOBase): return True def write(self, buf): - bytes_written = lib.sq_writer_write( - self.context().ref(), self.ref(), - ffi.cast("const uint8_t *", ffi.from_buffer(buf)), len(buf)) - if bytes_written < 0: - raise Error._last(self.context()) - return bytes_written + return invoke( + lib.sq_writer_write, + self.ref(), + ffi.cast("const uint8_t *", ffi.from_buffer(buf)), + len(buf)) def close(self): self._delete() @@ -113,9 +110,8 @@ class Writer(AbstractWriter): @classmethod def open(cls, ctx, filename): return Writer( - lib.sq_writer_from_file( - ctx.ref(), - filename.encode()), + invoke(lib.sq_writer_from_file, + filename.encode()), context=ctx) @classmethod diff --git a/ffi/lang/python/sequoia/glue.py b/ffi/lang/python/sequoia/glue.py index 799c550c..5bfd4aae 100644 --- a/ffi/lang/python/sequoia/glue.py +++ b/ffi/lang/python/sequoia/glue.py @@ -3,6 +3,20 @@ from datetime import datetime, timezone from _sequoia import ffi, lib from . import error +def invoke(fun, *args): + """Invokes the given FFI function. + + This function invokes the given FFI function. It must only be + used for functions that expect an error pointer as first argument. + + If an error is encountered, an exception is raised. + """ + err = ffi.new("sq_error_t[1]") + result = fun(err, *args) + if err[0] != ffi.NULL: + raise Error._from(err[0]) + return result + class SQObject(object): # These class attributes determine what features the wrapper class # implements. They must be set to the relevant Sequoia functions. diff --git a/ffi/lang/python/sequoia/openpgp.py b/ffi/lang/python/sequoia/openpgp.py index aaea5262..747f0b9f 100644 --- a/ffi/lang/python/sequoia/openpgp.py +++ b/ffi/lang/python/sequoia/openpgp.py @@ -2,7 +2,7 @@ from enum import Enum from _sequoia import ffi, lib from .error import Error -from .glue import _str, SQObject +from .glue import _str, SQObject, invoke from .core import AbstractReader, AbstractWriter class KeyID(SQObject): @@ -54,25 +54,25 @@ class PacketPile(SQObject): @classmethod def from_reader(cls, ctx, reader): - return PacketPile(lib.sq_packet_pile_from_reader(ctx.ref(), reader.ref()), + return PacketPile(invoke(lib.sq_packet_pile_from_reader, reader.ref()), context=ctx) @classmethod def open(cls, ctx, filename): - return PacketPile(lib.sq_packet_pile_from_file(ctx.ref(), filename.encode()), + return PacketPile(invoke(lib.sq_packet_pile_from_file, filename.encode()), context=ctx) @classmethod def from_bytes(cls, ctx, source): - return PacketPile(lib.sq_packet_pile_from_bytes(ctx.ref(), - ffi.from_buffer(source), - len(source)), + return PacketPile(invoke(lib.sq_packet_pile_from_bytes, + ffi.from_buffer(source), + len(source)), context=ctx) def serialize(self, writer): - status = lib.sq_packet_pile_serialize(self.context().ref(), - self.ref(), - writer.ref()) + status = invoke(lib.sq_packet_pile_serialize, + self.ref(), + writer.ref()) if status: raise Error._last(self.context()) @@ -83,30 +83,30 @@ class TPK(SQObject): @classmethod def from_reader(cls, ctx, reader): - return TPK(lib.sq_tpk_from_reader(ctx.ref(), reader.ref()), + return TPK(invoke(lib.sq_tpk_from_reader, reader.ref()), context=ctx) @classmethod def open(cls, ctx, filename): - return TPK(lib.sq_tpk_from_file(ctx.ref(), filename.encode()), + return TPK(invoke(lib.sq_tpk_from_file, filename.encode()), context=ctx) @classmethod def from_packet_pile(cls, ctx, packet_pile): - return TPK(lib.sq_tpk_from_packet_pile(ctx.ref(), packet_pile.ref_consume()), + return TPK(invoke(lib.sq_tpk_from_packet_pile, packet_pile.ref_consume()), context=ctx) @classmethod def from_bytes(cls, ctx, source): - return TPK(lib.sq_tpk_from_bytes(ctx.ref(), - ffi.from_buffer(source), - len(source)), + return TPK(invoke(lib.sq_tpk_from_bytes, + ffi.from_buffer(source), + len(source)), context=ctx) def serialize(self, writer): - status = lib.sq_tpk_serialize(self.context().ref(), - self.ref(), - writer.ref()) + status = invoke(lib.sq_tpk_serialize, + self.ref(), + writer.ref()) if status: raise Error._last(self.context()) @@ -115,9 +115,9 @@ class TPK(SQObject): context=self.context()) def merge(self, other): - new = lib.sq_tpk_merge(self.context().ref(), - self.ref_consume(), - other.ref_consume()) + new = invoke(lib.sq_tpk_merge, + self.ref_consume(), + other.ref_consume()) if new == ffi.NULL: raise Error._last(self.context()) self.ref_replace(new) @@ -149,10 +149,10 @@ class ArmorReader(AbstractReader): class ArmorWriter(AbstractWriter): @classmethod def new(cls, ctx, inner, kind): - aw = ArmorWriter(lib.sq_armor_writer_new(ctx.ref(), - inner.ref(), - kind.value, - ffi.NULL, 0), #XXX headers + aw = ArmorWriter(invoke(lib.sq_armor_writer_new, + inner.ref(), + kind.value, + ffi.NULL, 0), #XXX headers context=ctx) aw.inner = inner return aw @@ -221,12 +221,11 @@ class SKESK(SQObject): key = ffi.new("uint8_t[32]") key_len = ffi.new("size_t[1]") key_len[0] = len(key) - if lib.sq_skesk_decrypt(self.context().ref(), - self.ref(), - ffi.from_buffer(passphrase), - len(passphrase), - algo, key, key_len): - raise Error._last(self.context()) + invoke(lib.sq_skesk_decrypt, + self.ref(), + ffi.from_buffer(passphrase), + len(passphrase), + algo, key, key_len) return (algo[0], ffi.buffer(key, key_len[0])) class SEIP(SQObject): @@ -284,21 +283,21 @@ class PacketParser(SQObject): @classmethod def from_reader(cls, ctx, reader): return PacketParserResult( - lib.sq_packet_parser_from_reader(ctx.ref(), reader.ref()), + invoke(lib.sq_packet_parser_from_reader, reader.ref()), context=ctx) @classmethod def open(cls, ctx, filename): return PacketParserResult( - lib.sq_packet_parser_from_file(ctx.ref(), filename.encode()), + invoke(lib.sq_packet_parser_from_file, filename.encode()), context=ctx) @classmethod def from_bytes(cls, ctx, source): return PacketParserResult( - lib.sq_packet_parser_from_bytes(ctx.ref(), - ffi.from_buffer(source), - len(source)), + invoke(lib.sq_packet_parser_from_bytes, + ffi.from_buffer(source), + len(source)), context=ctx) @property @@ -321,11 +320,10 @@ class PacketParser(SQObject): ppr = ffi.new("sq_packet_parser_result_t[1]") new_rl = ffi.new("uint8_t[1]") - if lib.sq_packet_parser_next(self.context().ref(), - self.ref_consume(), - packet, - ppr): - raise Error._last(self.context()) + invoke(lib.sq_packet_parser_next, + self.ref_consume(), + packet, + ppr) return (Packet(packet[0]), PacketParserResult(ppr[0], self.context())) @@ -335,27 +333,23 @@ class PacketParser(SQObject): ppr = ffi.new("sq_packet_parser_result_t[1]") new_rl = ffi.new("uint8_t[1]") - if lib.sq_packet_parser_recurse(self.context().ref(), - self.ref_consume(), - packet, - ppr): - raise Error._last(self.context()) + invoke(lib.sq_packet_parser_recurse, + self.ref_consume(), + packet, + ppr) return (Packet(packet[0]), PacketParserResult(ppr[0], self.context())) def buffer_unread_content(self): buf_len = ffi.new("size_t[1]") - buf = lib.sq_packet_parser_buffer_unread_content(self.context().ref(), - self.ref(), - buf_len) - if buf == ffi.NULL: - raise Error._last(self.context()) + buf = invoke(lib.sq_packet_parser_buffer_unread_content, + self.ref(), + buf_len) return ffi.buffer(buf, buf_len[0]) def decrypt(self, algo, key): - if lib.sq_packet_parser_decrypt(self.context().ref(), - self.ref(), - algo, - ffi.from_buffer(key), - len(key)): - raise Error._last(self.context()) + invoke(lib.sq_packet_parser_decrypt, + self.ref(), + algo, + ffi.from_buffer(key), + len(key)) |