-
-
Notifications
You must be signed in to change notification settings - Fork 610
Description
A pattern that appears in the codebase is to try calling a (dis)connection handler with one set of arguments, and if it raises a TypeError
, call again with a different set:
python-socketio/src/socketio/server.py
Lines 537 to 542 in b01b197
try: | |
success = self._trigger_event( | |
'connect', namespace, sid, self.environ[eio_sid]) | |
except TypeError: | |
success = self._trigger_event( | |
'connect', namespace, sid, self.environ[eio_sid], None) |
This is risky if the event handler itself can raise a TypeError
, unrelated to the handler's arity. This could cause the handler to be run up to the point it throws a TypeError
, then the TypeError
is consumed and the handler is called again.
A contrived example might be:
@sio.on('connect', namespace='*')
async def on_client_connect(namespace, sid, environ, *args):
initialize_client_state(sid)
2 + "two"
This will be called once with (namespace, sid, environ)
and initialize some client state. Then it will raise a TypeError
, so it will be called again with (namespace, sid, environ, auth)
. The client state will be initialized a second time, which might lead to an unexpected state, resource leaks, etc.
It may be better to check inspect.signature(handler).parameters
-- however when the event is triggered with self._trigger_event()
it doesn't have a reference to the handler callable.
(I'm filing this only because while debugging some other part of my application, I kept getting complaints about including auth
or not including auth
in my parameter list. Finally I settled on adding *args
and moving on.)