From 35768d673872eea5ea74b21f91e4913c18d59932 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Tue, 6 Oct 2015 19:42:10 -0700 Subject: [PATCH] wormhole/invitation code is now unicode --- docs/api.md | 11 ++++------- src/wormhole/blocking/transcribe.py | 6 +++--- src/wormhole/codes.py | 4 ++-- src/wormhole/scripts/cmd_receive.py | 2 +- src/wormhole/scripts/cmd_send.py | 2 +- src/wormhole/scripts/runner.py | 4 +++- src/wormhole/test/test_blocking.py | 6 +++--- src/wormhole/test/test_scripts.py | 4 ++-- src/wormhole/test/test_twisted.py | 6 +++--- src/wormhole/twisted/transcribe.py | 8 ++++---- 10 files changed, 26 insertions(+), 27 deletions(-) diff --git a/docs/api.md b/docs/api.md index e6040f5..5d9826f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -157,8 +157,8 @@ include randomly-selected words or characters. Dice, coin flips, shuffled cards, or repeated sampling of a high-resolution stopwatch are all useful techniques. -Note that the code is a human-readable string (the python "str" type: so -unicode in python3, plain bytes in python2). +Note that the code is a human-readable string (the python "unicode" type in +python2, "str" in python3). ## Application Identifier @@ -248,13 +248,10 @@ python2, "bytes" in python3): * data in/out * transit records in/out -Some human-readable parameters are passed as strings: "str" in python2, "str" -(i.e. unicode) in python3: +Other (human-facing) values are always unicode ("unicode" in python2, "str" +in python3): * wormhole code - -And some are always unicode, in both python2 and python3: - * relay URL * transit URLs * transit connection hints (e.g. "host:port") diff --git a/src/wormhole/blocking/transcribe.py b/src/wormhole/blocking/transcribe.py index 420d513..75f8302 100644 --- a/src/wormhole/blocking/transcribe.py +++ b/src/wormhole/blocking/transcribe.py @@ -186,7 +186,7 @@ class Wormhole: if self.code is not None: raise UsageError channelid = self._channel_manager.allocate() code = codes.make_code(channelid, code_length) - assert isinstance(code, str), type(code) + assert isinstance(code, type(u"")), type(code) self._set_code_and_channelid(code) self._start() return code @@ -198,7 +198,7 @@ class Wormhole: return code def set_code(self, code): # used for human-made pre-generated codes - if not isinstance(code, str): raise UsageError + if not isinstance(code, type(u"")): raise UsageError if self.code is not None: raise UsageError self._set_code_and_channelid(code) self._start() @@ -215,7 +215,7 @@ class Wormhole: def _start(self): # allocate the rest now too, so it can be serialized - self.sp = SPAKE2_Symmetric(self.code.encode("ascii"), + self.sp = SPAKE2_Symmetric(to_bytes(self.code), idSymmetric=to_bytes(self._appid)) self.msg1 = self.sp.start() diff --git a/src/wormhole/codes.py b/src/wormhole/codes.py index c26a819..88a8d49 100644 --- a/src/wormhole/codes.py +++ b/src/wormhole/codes.py @@ -11,7 +11,7 @@ def make_code(channel_id, code_length): words.append(byte_to_odd_word[os.urandom(1)].lower()) else: words.append(byte_to_even_word[os.urandom(1)].lower()) - return str(channel_id) + "-" + "-".join(words) + return u"%d-%s" % (channel_id, u"-".join(words)) def extract_channel_id(code): channel_id = int(code.split("-")[0]) @@ -82,7 +82,7 @@ def input_code_with_completion(prompt, get_channel_ids, code_length): readline.set_completer(c.wrap_completer) readline.set_completer_delims("") code = six.moves.input(prompt) - return code + return code.decode("utf-8") if __name__ == "__main__": code = input_code_with_completion("Enter wormhole code: ", lambda: [], 2) diff --git a/src/wormhole/scripts/cmd_receive.py b/src/wormhole/scripts/cmd_receive.py index 3fc9331..d369b09 100644 --- a/src/wormhole/scripts/cmd_receive.py +++ b/src/wormhole/scripts/cmd_receive.py @@ -15,7 +15,7 @@ def receive(args): w = Wormhole(APPID, args.relay_url) if args.zeromode: assert not args.code - args.code = "0-" + args.code = u"0-" code = args.code if not code: code = w.input_code("Enter receive wormhole code: ", args.code_length) diff --git a/src/wormhole/scripts/cmd_send.py b/src/wormhole/scripts/cmd_send.py index c4a3797..18f8e4a 100644 --- a/src/wormhole/scripts/cmd_send.py +++ b/src/wormhole/scripts/cmd_send.py @@ -46,7 +46,7 @@ def send(args): w = Wormhole(APPID, args.relay_url) if args.zeromode: assert not args.code - args.code = "0-" + args.code = u"0-" if args.code: w.set_code(args.code) code = args.code diff --git a/src/wormhole/scripts/runner.py b/src/wormhole/scripts/runner.py index 18b38c7..a95b72e 100644 --- a/src/wormhole/scripts/runner.py +++ b/src/wormhole/scripts/runner.py @@ -69,7 +69,8 @@ p = subparsers.add_parser("send", usage="wormhole send [FILENAME]") p.add_argument("--text", metavar="MESSAGE", help="text message to send, instead of a file") -p.add_argument("--code", metavar="CODE", help="human-generated code phrase") +p.add_argument("--code", metavar="CODE", help="human-generated code phrase", + type=type(u"")) p.add_argument("-0", dest="zeromode", action="store_true", help="enable no-code anything-goes mode") p.add_argument("what", nargs="?", default=None, metavar="[FILENAME]", @@ -95,6 +96,7 @@ p.add_argument("code", nargs="?", default=None, metavar="[CODE]", help=dedent("""\ The magic-wormhole code, from the sender. If omitted, the program will ask for it, using tab-completion."""), + type=type(u""), ) p.set_defaults(func=cmd_receive.receive) diff --git a/src/wormhole/test/test_blocking.py b/src/wormhole/test/test_blocking.py index 65e5be0..6463d1a 100644 --- a/src/wormhole/test/test_blocking.py +++ b/src/wormhole/test/test_blocking.py @@ -140,8 +140,8 @@ class Blocking(ServerBase, unittest.TestCase): def test_fixed_code(self): w1 = BlockingWormhole(APPID, self.relayurl) w2 = BlockingWormhole(APPID, self.relayurl) - w1.set_code("123-purple-elephant") - w2.set_code("123-purple-elephant") + w1.set_code(u"123-purple-elephant") + w2.set_code(u"123-purple-elephant") d = self.doBoth([w1.send_data, b"data1"], [w2.send_data, b"data2"]) def _sent(res): return self.doBoth([w1.get_data], [w2.get_data]) @@ -201,7 +201,7 @@ class Blocking(ServerBase, unittest.TestCase): self.assertRaises(UsageError, w1.get_verifier) self.assertRaises(UsageError, w1.get_data) self.assertRaises(UsageError, w1.send_data, b"data") - w1.set_code("123-purple-elephant") + w1.set_code(u"123-purple-elephant") self.assertRaises(UsageError, w1.set_code, "123-nope") self.assertRaises(UsageError, w1.get_code) w2 = BlockingWormhole(APPID, self.relayurl) diff --git a/src/wormhole/test/test_scripts.py b/src/wormhole/test/test_scripts.py index 6fe3c93..ce7ba50 100644 --- a/src/wormhole/test/test_scripts.py +++ b/src/wormhole/test/test_scripts.py @@ -82,7 +82,7 @@ class Scripts(ServerBase, ScriptsBase, unittest.TestCase): def test_send_text_pre_generated_code(self): wormhole = self.find_executable() server_args = ["--relay-url", self.relayurl] - code = "1-abc" + code = u"1-abc" message = "test message" send_args = server_args + [ "send", @@ -120,7 +120,7 @@ class Scripts(ServerBase, ScriptsBase, unittest.TestCase): def test_send_file_pre_generated_code(self): self.maxDiff=None - code = "1-abc" + code = u"1-abc" filename = "testfile" message = "test message" diff --git a/src/wormhole/test/test_twisted.py b/src/wormhole/test/test_twisted.py index 2d20057..70ac2ae 100644 --- a/src/wormhole/test/test_twisted.py +++ b/src/wormhole/test/test_twisted.py @@ -128,8 +128,8 @@ class Basic(ServerBase, unittest.TestCase): def test_fixed_code(self): w1 = Wormhole(APPID, self.relayurl) w2 = Wormhole(APPID, self.relayurl) - w1.set_code("123-purple-elephant") - w2.set_code("123-purple-elephant") + w1.set_code(u"123-purple-elephant") + w2.set_code(u"123-purple-elephant") d = self.doBoth(w1.send_data(b"data1"), w2.send_data(b"data2")) def _sent(res): return self.doBoth(w1.get_data(), w2.get_data()) @@ -188,7 +188,7 @@ class Basic(ServerBase, unittest.TestCase): self.assertRaises(UsageError, w1.get_verifier) self.assertRaises(UsageError, w1.send_data, b"data") self.assertRaises(UsageError, w1.get_data) - w1.set_code("123-purple-elephant") + w1.set_code(u"123-purple-elephant") self.assertRaises(UsageError, w1.set_code, "123-nope") self.assertRaises(UsageError, w1.get_code) w2 = Wormhole(APPID, self.relayurl) diff --git a/src/wormhole/twisted/transcribe.py b/src/wormhole/twisted/transcribe.py index a475223..675ad5e 100644 --- a/src/wormhole/twisted/transcribe.py +++ b/src/wormhole/twisted/transcribe.py @@ -223,7 +223,7 @@ class Wormhole: d = self._channel_manager.allocate() def _got_channelid(channelid): code = codes.make_code(channelid, code_length) - assert isinstance(code, str), type(code) + assert isinstance(code, type(u"")), type(code) self._set_code_and_channelid(code) self._start() return code @@ -231,7 +231,7 @@ class Wormhole: return d def set_code(self, code): - if not isinstance(code, str): raise UsageError + if not isinstance(code, type(u"")): raise UsageError if self.code is not None: raise UsageError self._set_code_and_channelid(code) self._start() @@ -248,7 +248,7 @@ class Wormhole: def _start(self): # allocate the rest now too, so it can be serialized - self.sp = SPAKE2_Symmetric(self.code.encode("ascii"), + self.sp = SPAKE2_Symmetric(to_bytes(self.code), idSymmetric=to_bytes(self._appid)) self.msg1 = self.sp.start() @@ -274,7 +274,7 @@ class Wormhole: d = json.loads(data) self = klass(d["appid"], d["relay_url"]) self._set_side(d["side"].encode("ascii")) - self._set_code_and_channelid(d["code"].encode("ascii")) + self._set_code_and_channelid(d["code"]) self.sp = SPAKE2_Symmetric.from_serialized(json.dumps(d["spake2"])) self.msg1 = d["msg1"].decode("hex") return self