diff --git a/src/wormhole/blocking/transcribe.py b/src/wormhole/blocking/transcribe.py index 88d7757..967f035 100644 --- a/src/wormhole/blocking/transcribe.py +++ b/src/wormhole/blocking/transcribe.py @@ -319,6 +319,7 @@ class Wormhole: if not isinstance(phase, type(u"")): raise TypeError(type(phase)) if self._closed: raise UsageError if phase in self._sent_data: raise UsageError # only call this once + if phase.startswith(u"_"): raise UsageError # reserved for internals if self.code is None: raise UsageError if self._channel is None: raise UsageError # Without predefined roles, we can't derive predictably unique keys @@ -335,6 +336,7 @@ class Wormhole: def get_data(self, phase=u"data"): if not isinstance(phase, type(u"")): raise TypeError(type(phase)) if phase in self._got_data: raise UsageError # only call this once + if phase.startswith(u"_"): raise UsageError # reserved for internals if self._closed: raise UsageError if self.code is None: raise UsageError if self._channel is None: raise UsageError diff --git a/src/wormhole/test/test_blocking.py b/src/wormhole/test/test_blocking.py index ee564fb..e6a2ba8 100644 --- a/src/wormhole/test/test_blocking.py +++ b/src/wormhole/test/test_blocking.py @@ -274,6 +274,9 @@ class Blocking(ServerBase, unittest.TestCase): d.addCallback(lambda _: deferToThread(w1.send_data, b"data1", phase=u"1")) def _sent(res): + # underscore-prefixed phases are reserved + self.assertRaises(UsageError, w1.send_data, b"data1", phase=u"_1") + self.assertRaises(UsageError, w1.get_data, phase=u"_1") # you can't send twice to the same phase self.assertRaises(UsageError, w1.send_data, b"data1", phase=u"1") # but you can send to a different one diff --git a/src/wormhole/test/test_twisted.py b/src/wormhole/test/test_twisted.py index 9fe04c9..46b352b 100644 --- a/src/wormhole/test/test_twisted.py +++ b/src/wormhole/test/test_twisted.py @@ -259,6 +259,9 @@ class Basic(ServerBase, unittest.TestCase): d = self.doBoth(w1.get_verifier(), w2.get_verifier()) d.addCallback(lambda _: w1.send_data(b"data1", phase=u"1")) def _sent(res): + # underscore-prefixed phases are reserved + self.assertRaises(UsageError, w1.send_data, b"data1", phase=u"_1") + self.assertRaises(UsageError, w1.get_data, phase=u"_1") # you can't send twice to the same phase self.assertRaises(UsageError, w1.send_data, b"data1", phase=u"1") # but you can send to a different one diff --git a/src/wormhole/twisted/transcribe.py b/src/wormhole/twisted/transcribe.py index 9af8470..b9e328d 100644 --- a/src/wormhole/twisted/transcribe.py +++ b/src/wormhole/twisted/transcribe.py @@ -331,6 +331,7 @@ class Wormhole: raise TypeError(type(outbound_data)) if not isinstance(phase, type(u"")): raise TypeError(type(phase)) if phase in self._sent_data: raise UsageError # only call this once + if phase.startswith(u"_"): raise UsageError # reserved for internals if self.code is None: raise UsageError if self.channel is None: raise UsageError # Without predefined roles, we can't derive predictably unique keys @@ -349,6 +350,7 @@ class Wormhole: def get_data(self, phase=u"data"): if not isinstance(phase, type(u"")): raise TypeError(type(phase)) if phase in self._got_data: raise UsageError # only call this once + if phase.startswith(u"_"): raise UsageError # reserved for internals if self.code is None: raise UsageError if self.channel is None: raise UsageError self._got_data.add(phase)