viff

changeset 1159:a8206d017f43

Replace the unsafe marshal module with the safe struct module. This changes the ShareExchanger.sendData method so that data must now always be a string, integers and other types will no longer work. Part of this patch: http://lists.viff.dk/pipermail/viff-patches-viff.dk/2008-October/000053.html Committed by Martin Geisler.
author Mikkel Krøigård <mk@daimi.au.dk>
date Tue, 14 Apr 2009 23:05:41 +0200
parents ed3302fd93f1
children d5741e841ccc
files viff/runtime.py viff/test/test_basic_runtime.py
diffstat 2 files changed, 31 insertions(+), 13 deletions(-) [+]
line diff
     1.1 --- a/viff/runtime.py	Tue Apr 14 15:07:30 2009 +0200
     1.2 +++ b/viff/runtime.py	Tue Apr 14 23:05:41 2009 +0200
     1.3 @@ -34,7 +34,7 @@
     1.4  __docformat__ = "restructuredtext"
     1.5  
     1.6  import time
     1.7 -import marshal
     1.8 +import struct
     1.9  from optparse import OptionParser, OptionGroup
    1.10  from collections import deque
    1.11  
    1.12 @@ -305,7 +305,18 @@
    1.13                      self.transport.loseConnection()
    1.14              self.factory.identify_peer(self)
    1.15          else:
    1.16 -            program_counter, data_type, data = marshal.loads(string)
    1.17 +            # TODO: we cannot handle the empty string
    1.18 +            # also note that we cannot handle pcs longer than 256
    1.19 +            pc_size = ord(string[0])
    1.20 +            fmt = (pc_size + 1)*'i'
    1.21 +            predata_size = struct.calcsize(fmt) + 1
    1.22 +            fmt = "%s%is" % (fmt, len(string)-predata_size)
    1.23 +
    1.24 +            unpacked = struct.unpack(fmt, string[1:])
    1.25 +
    1.26 +            program_counter = unpacked[:pc_size]
    1.27 +            data_type, data = unpacked[-2:]
    1.28 +
    1.29              key = (program_counter, data_type)
    1.30  
    1.31              deq = self.incoming_data.setdefault(key, deque())
    1.32 @@ -321,8 +332,11 @@
    1.33              # TypeError. They should be handled somehow.
    1.34  
    1.35      def sendData(self, program_counter, data_type, data):
    1.36 -        send_data = (program_counter, data_type, data)
    1.37 -        self.sendString(marshal.dumps(send_data))
    1.38 +        pc_size = len(program_counter)
    1.39 +        fmt = "%s%is" % ((pc_size + 1)*'i', len(data))
    1.40 +        data_tuple = program_counter + (data_type, data)
    1.41 +
    1.42 +        self.sendString(chr(pc_size) + struct.pack(fmt, *data_tuple))
    1.43  
    1.44      def sendShare(self, program_counter, share):
    1.45          """Send a share.
    1.46 @@ -330,7 +344,7 @@
    1.47          The program counter and the share are marshalled and sent to
    1.48          the peer.
    1.49          """
    1.50 -        self.sendData(program_counter, SHARE, share.value)
    1.51 +        self.sendData(program_counter, SHARE, hex(share.value))
    1.52  
    1.53      def loseConnection(self):
    1.54          """Disconnect this protocol instance."""
    1.55 @@ -635,8 +649,12 @@
    1.56              return share
    1.57  
    1.58      def _expect_share(self, peer_id, field):
    1.59 +
    1.60 +        def unpack_share(value_string):
    1.61 +            return field(long(value_string, 16))
    1.62 +
    1.63          share = Share(self, field)
    1.64 -        share.addCallback(lambda value: field(value))
    1.65 +        share.addCallback(unpack_share)
    1.66          self._expect_data(peer_id, SHARE, share)
    1.67          return share
    1.68  
     2.1 --- a/viff/test/test_basic_runtime.py	Tue Apr 14 15:07:30 2009 +0200
     2.2 +++ b/viff/test/test_basic_runtime.py	Tue Apr 14 23:05:41 2009 +0200
     2.3 @@ -1,4 +1,4 @@
     2.4 -# Copyright 2008 VIFF Development Team.
     2.5 +# Copyright 2008, 2009 VIFF Development Team.
     2.6  #
     2.7  # This file is part of VIFF, the Virtual Ideal Functionality Framework.
     2.8  #
     2.9 @@ -140,17 +140,17 @@
    2.10          for peer_id in range(1, self.num_players+1):
    2.11              if peer_id != runtime.id:
    2.12                  pc = tuple(runtime.program_counter)
    2.13 -                runtime.protocols[peer_id].sendData(pc, 42, 100)
    2.14 -                runtime.protocols[peer_id].sendData(pc, 42, 200)
    2.15 -                runtime.protocols[peer_id].sendData(pc, 42, 300)
    2.16 +                runtime.protocols[peer_id].sendData(pc, 42, "100")
    2.17 +                runtime.protocols[peer_id].sendData(pc, 42, "200")
    2.18 +                runtime.protocols[peer_id].sendData(pc, 42, "300")
    2.19  
    2.20          # Then receive the data.
    2.21          deferreds = []
    2.22          for peer_id in range(1, self.num_players+1):
    2.23              if peer_id != runtime.id:
    2.24 -                d100 = Deferred().addCallback(self.assertEquals, 100)
    2.25 -                d200 = Deferred().addCallback(self.assertEquals, 200)
    2.26 -                d300 = Deferred().addCallback(self.assertEquals, 300)
    2.27 +                d100 = Deferred().addCallback(self.assertEquals, "100")
    2.28 +                d200 = Deferred().addCallback(self.assertEquals, "200")
    2.29 +                d300 = Deferred().addCallback(self.assertEquals, "300")
    2.30                  runtime._expect_data(peer_id, 42, d100)
    2.31                  runtime._expect_data(peer_id, 42, d200)
    2.32                  runtime._expect_data(peer_id, 42, d300)