Commit 928aa7a0 authored by Jason Madden's avatar Jason Madden

Apply the same async and zodbpickle fixes to the ZEO4 server.

parent b3ee072b
...@@ -418,10 +418,10 @@ class Connection(smac.SizedMessageAsyncConnection, object): ...@@ -418,10 +418,10 @@ class Connection(smac.SizedMessageAsyncConnection, object):
# will raise an exception. The exception will ultimately # will raise an exception. The exception will ultimately
# result in asycnore calling handle_error(), which will # result in asycnore calling handle_error(), which will
# close the connection. # close the connection.
msgid, async, name, args = self.decode(message) msgid, async_, name, args = self.decode(message)
if debug_zrpc: if debug_zrpc:
self.log("recv msg: %s, %s, %s, %s" % (msgid, async, name, self.log("recv msg: %s, %s, %s, %s" % (msgid, async_, name,
short_repr(args)), short_repr(args)),
level=TRACE) level=TRACE)
...@@ -446,12 +446,12 @@ class Connection(smac.SizedMessageAsyncConnection, object): ...@@ -446,12 +446,12 @@ class Connection(smac.SizedMessageAsyncConnection, object):
self.send_reply(msgid, ret) self.send_reply(msgid, ret)
elif name == REPLY: elif name == REPLY:
assert not async assert not async_
self.handle_reply(msgid, args) self.handle_reply(msgid, args)
else: else:
self.handle_request(msgid, async, name, args) self.handle_request(msgid, async_, name, args)
def handle_request(self, msgid, async, name, args): def handle_request(self, msgid, async_, name, args):
obj = self.obj obj = self.obj
if name.startswith('_') or not hasattr(obj, name): if name.startswith('_') or not hasattr(obj, name):
...@@ -482,14 +482,14 @@ class Connection(smac.SizedMessageAsyncConnection, object): ...@@ -482,14 +482,14 @@ class Connection(smac.SizedMessageAsyncConnection, object):
self.log("%s() raised exception: %s" % (name, msg), self.log("%s() raised exception: %s" % (name, msg),
logging.ERROR, exc_info=True) logging.ERROR, exc_info=True)
error = sys.exc_info()[:2] error = sys.exc_info()[:2]
if async: if async_:
self.log("Asynchronous call raised exception: %s" % self, self.log("Asynchronous call raised exception: %s" % self,
level=logging.ERROR, exc_info=True) level=logging.ERROR, exc_info=True)
else: else:
self.return_error(msgid, *error) self.return_error(msgid, *error)
return return
if async: if async_:
if ret is not None: if ret is not None:
raise ZRPCError("async method %s returned value %s" % raise ZRPCError("async method %s returned value %s" %
(name, short_repr(ret))) (name, short_repr(ret)))
...@@ -545,15 +545,15 @@ class Connection(smac.SizedMessageAsyncConnection, object): ...@@ -545,15 +545,15 @@ class Connection(smac.SizedMessageAsyncConnection, object):
def send_call(self, method, args, async_=False): def send_call(self, method, args, async_=False):
# send a message and return its msgid # send a message and return its msgid
if async: if async_:
msgid = 0 msgid = 0
else: else:
msgid = self._new_msgid() msgid = self._new_msgid()
if debug_zrpc: if debug_zrpc:
self.log("send msg: %d, %d, %s, ..." % (msgid, async, method), self.log("send msg: %d, %d, %s, ..." % (msgid, async_, method),
level=TRACE) level=TRACE)
buf = self.encode(msgid, async, method, args) buf = self.encode(msgid, async_, method, args)
self.message_output(buf) self.message_output(buf)
return msgid return msgid
......
...@@ -17,6 +17,8 @@ from ZEO._compat import Unpickler, Pickler, BytesIO, PY3, PYPY ...@@ -17,6 +17,8 @@ from ZEO._compat import Unpickler, Pickler, BytesIO, PY3, PYPY
from .error import ZRPCError from .error import ZRPCError
from .log import log, short_repr from .log import log, short_repr
PY2 = not PY3
def encode(*args): # args: (msgid, flags, name, args) def encode(*args): # args: (msgid, flags, name, args)
# (We used to have a global pickler, but that's not thread-safe. :-( ) # (We used to have a global pickler, but that's not thread-safe. :-( )
...@@ -106,6 +108,8 @@ _silly = ('__doc__',) ...@@ -106,6 +108,8 @@ _silly = ('__doc__',)
exception_type_type = type(Exception) exception_type_type = type(Exception)
_SAFE_MODULE_NAMES = ('ZopeUndo.Prefix', 'copy_reg', '__builtin__', 'zodbpickle')
def find_global(module, name): def find_global(module, name):
"""Helper for message unpickler""" """Helper for message unpickler"""
try: try:
...@@ -118,7 +122,7 @@ def find_global(module, name): ...@@ -118,7 +122,7 @@ def find_global(module, name):
except AttributeError: except AttributeError:
raise ZRPCError("module %s has no global %s" % (module, name)) raise ZRPCError("module %s has no global %s" % (module, name))
safe = getattr(r, '__no_side_effects__', 0) safe = getattr(r, '__no_side_effects__', 0) or (PY2 and module in _SAFE_MODULE_NAMES)
if safe: if safe:
return r return r
...@@ -130,9 +134,10 @@ def find_global(module, name): ...@@ -130,9 +134,10 @@ def find_global(module, name):
def server_find_global(module, name): def server_find_global(module, name):
"""Helper for message unpickler""" """Helper for message unpickler"""
if module not in _SAFE_MODULE_NAMES:
raise ImportError("Module not allowed: %s" % (module,))
try: try:
if module != 'ZopeUndo.Prefix':
raise ImportError
m = __import__(module, _globals, _globals, _silly) m = __import__(module, _globals, _globals, _silly)
except ImportError as msg: except ImportError as msg:
raise ZRPCError("import error %s: %s" % (module, msg)) raise ZRPCError("import error %s: %s" % (module, msg))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment