I'm using an old thread to post new code which attempts to solve the same problem. What constitutes a secure pickle? this?
sock.py
from socket import socket
from socket import AF_INET
from socket import SOCK_STREAM
from socket import gethostbyname
from socket import gethostnameclass SocketServer:def __init__(self, port):self.sock = socket(AF_INET, SOCK_STREAM)self.port = portdef listen(self, data):self.sock.bind(("127.0.0.1", self.port))self.sock.listen(len(data))while data:s = self.sock.accept()[0]siz, dat = data.pop()s.send(siz)s.send(dat)s.close()class Socket:def __init__(self, host, port):self.sock = socket(AF_INET, SOCK_STREAM)self.sock.connect((host, port))def recv(self, size):return self.sock.recv(size)
pack.py
#http://stackoverflow.com/questions/6234586/we-need-to-pickle-any-sort-of-callable
from marshal import dumps as marshal_dumps
from pickle import dumps as pickle_dumps
from struct import pack as struct_packclass packer:def __init__(self):self.f = []def pack(self, what):if type(what) is type(lambda:None):self.f = []self.f.append(marshal_dumps(what.func_code))self.f.append(pickle_dumps(what.func_name))self.f.append(pickle_dumps(what.func_defaults))self.f.append(pickle_dumps(what.func_closure))self.f = pickle_dumps(self.f)return (struct_pack('Q', len(self.f)), self.f)
unpack.py
from types import FunctionType
from pickle import loads as pickle_loads
from marshal import loads as marshal_loads
from struct import unpack as struct_unpack
from struct import calcsize#http://stackoverflow.com/questions/6234586/we-need-to-pickle-any-sort-of-callableclass unpacker:def __init__(self):self.f = []self.fcompiled = lambda:Noneself.sizeofsize = calcsize('Q')def unpack(self, sock):size = struct_unpack('Q', sock.recv(self.sizeofsize))[0]self.f = pickle_loads(sock.recv(size))a = marshal_loads(self.f[0])b = globals() ##c = pickle_loads(self.f[1])d = pickle_loads(self.f[2])e = pickle_loads(self.f[3])self.fcompiled = FunctionType(a, b, c, d, e)return self.fcompiled
test.py
from unpack import unpacker
from pack import packer
from sock import SocketServer
from sock import Socket
from threading import Thread
from time import sleepcount = 2
port = 4446def f():print 42def server():ss = SocketServer(port)pack = packer()functions = [pack.pack(f) for nothing in range(count)]ss.listen(functions)if __name__ == "__main__":Thread(target=server).start()sleep(1)unpack = unpacker()for nothing in range(count):print unpack.unpack(Socket("127.0.0.1", port))
output:
<function f at 0x12917d0>
<function f at 0x12915f0>