diff --git a/priv/python2/erlport/erlterms.py b/priv/python2/erlport/erlterms.py index 4246fac2..7e810c66 100644 --- a/priv/python2/erlport/erlterms.py +++ b/priv/python2/erlport/erlterms.py @@ -200,15 +200,23 @@ def decode_term(string, if not string: raise IncompleteData(string) tag = string[0] - if tag == "d": - # ATOM_EXT + if tag == "d" or tag == "w": + # ATOM_EXT, SMALL_ATOM_UTF8_EXT ln = len(string) - if ln < 3: - raise IncompleteData(string) - length = int2_unpack(string[1:3])[0] + 3 - if ln < length: - raise IncompleteData(string) - name = string[3:length] + if tag == "d": + if ln < 3: + raise IncompleteData(string) + length = int2_unpack(string[1:3])[0] + 3 + if ln < length: + raise IncompleteData(string) + name = string[3:length] + else: + if ln < 2: + raise IncompleteData(string) + length = ord(string[1]) + 2 + if ln < length: + raise IncompleteData(string) + name = string[2:length] if name == "true": return True, string[length:] elif name == "false": diff --git a/priv/python2/erlport/tests/erlterms_tests.py b/priv/python2/erlport/tests/erlterms_tests.py index 10d01063..7c4c0c9e 100644 --- a/priv/python2/erlport/tests/erlterms_tests.py +++ b/priv/python2/erlport/tests/erlterms_tests.py @@ -45,6 +45,8 @@ def test_atom(self): self.assertFalse(atom is Atom("test2")) self.assertTrue(atom is Atom("test")) self.assertEqual("X" * 255, Atom("X" * 255)) + self.assertEqual("\xc3\xa4", Atom("\xc3\xa4")) + self.assertEqual("\xe4", Atom("\xe4")) def test_invalid_atom(self): self.assertRaises(ValueError, Atom, "X" * 256) @@ -139,6 +141,7 @@ def test_decode(self): self.assertRaises(ValueError, decode, "\x83z") def test_decode_atom(self): + # ATOM_EXT: self.assertRaises(IncompleteData, decode, "\x83d") self.assertRaises(IncompleteData, decode, "\x83d\0") self.assertRaises(IncompleteData, decode, "\x83d\0\1") @@ -146,14 +149,31 @@ def test_decode_atom(self): self.assertEqual((Atom(""), "tail"), decode("\x83d\0\0tail")) self.assertEqual((Atom("test"), ""), decode("\x83d\0\4test")) self.assertEqual((Atom("test"), "tail"), decode("\x83d\0\4testtail")) + self.assertEqual((Atom("\xe4"), ""), decode("\x83d\0\1\xe4")) + # SMALL_ATOM_UTF8_EXT: + self.assertRaises(IncompleteData, decode, "\x83w") + self.assertRaises(IncompleteData, decode, "\x83w\1") + self.assertEqual((Atom(""), ""), decode("\x83w\0")) + self.assertEqual((Atom(""), "tail"), decode("\x83w\0tail")) + self.assertEqual((Atom("test"), ""), decode("\x83w\4test")) + self.assertEqual((Atom("test"), "tail"), decode("\x83w\4testtail")) + self.assertEqual((Atom("\xc3\xa4"), ""), decode("\x83w\2\xc3\xa4")) def test_decode_predefined_atoms(self): + # ATOM_EXT: self.assertEqual((True, ""), decode("\x83d\0\4true")) self.assertEqual((True, "tail"), decode("\x83d\0\4truetail")) self.assertEqual((False, ""), decode("\x83d\0\5false")) self.assertEqual((False, "tail"), decode("\x83d\0\5falsetail")) self.assertEqual((None, ""), decode("\x83d\0\11undefined")) self.assertEqual((None, "tail"), decode("\x83d\0\11undefinedtail")) + # SMALL_ATOM_UTF8_EXT: + self.assertEqual((True, ""), decode("\x83w\4true")) + self.assertEqual((True, "tail"), decode("\x83w\4truetail")) + self.assertEqual((False, ""), decode("\x83w\5false")) + self.assertEqual((False, "tail"), decode("\x83w\5falsetail")) + self.assertEqual((None, ""), decode("\x83w\11undefined")) + self.assertEqual((None, "tail"), decode("\x83w\11undefinedtail")) def test_decode_empty_list(self): self.assertEqual(([], ""), decode("\x83j")) diff --git a/priv/python3/erlport/erlterms.py b/priv/python3/erlport/erlterms.py index 3f071348..7706a764 100644 --- a/priv/python3/erlport/erlterms.py +++ b/priv/python3/erlport/erlterms.py @@ -199,15 +199,23 @@ def decode_term(string, if not string: raise IncompleteData(string) tag = string[0] - if tag == 100: - # ATOM_EXT + if tag == 100 or tag == 119: + # ATOM_EXT, SMALL_ATOM_UTF8_EXT ln = len(string) - if ln < 3: - raise IncompleteData(string) - length = int2_unpack(string[1:3])[0] + 3 - if ln < length: - raise IncompleteData(string) - name = string[3:length] + if tag == 100: + if ln < 3: + raise IncompleteData(string) + length = int2_unpack(string[1:3])[0] + 3 + if ln < length: + raise IncompleteData(string) + name = string[3:length] + else: + if ln < 2: + raise IncompleteData(string) + length = string[1] + 2 + if ln < length: + raise IncompleteData(string) + name = string[2:length] if name == b"true": return True, string[length:] elif name == b"false": diff --git a/priv/python3/erlport/tests/erlterms_tests.py b/priv/python3/erlport/tests/erlterms_tests.py index 86beedd6..7872963e 100644 --- a/priv/python3/erlport/tests/erlterms_tests.py +++ b/priv/python3/erlport/tests/erlterms_tests.py @@ -45,6 +45,8 @@ def test_atom(self): self.assertFalse(atom is Atom(b"test2")) self.assertTrue(atom is Atom(b"test")) self.assertEqual(b"X" * 255, Atom(b"X" * 255)) + self.assertEqual(b"\xc3\xa4", Atom(b"\xc3\xa4")) + self.assertEqual(b"\xe4", Atom(b"\xe4")) def test_invalid_atom(self): self.assertRaises(ValueError, Atom, b"X" * 256) @@ -139,6 +141,7 @@ def test_decode(self): self.assertRaises(ValueError, decode, b"\x83z") def test_decode_atom(self): + # ATOM_EXT: self.assertRaises(IncompleteData, decode, b"\x83d") self.assertRaises(IncompleteData, decode, b"\x83d\0") self.assertRaises(IncompleteData, decode, b"\x83d\0\1") @@ -146,14 +149,31 @@ def test_decode_atom(self): self.assertEqual((Atom(b""), b"tail"), decode(b"\x83d\0\0tail")) self.assertEqual((Atom(b"test"), b""), decode(b"\x83d\0\4test")) self.assertEqual((Atom(b"test"), b"tail"), decode(b"\x83d\0\4testtail")) + self.assertEqual((Atom(b"\xe4"), b""), decode(b"\x83d\0\1\xe4")) + # SMALL_ATOM_UTF8_EXT: + self.assertRaises(IncompleteData, decode, b"\x83w") + self.assertRaises(IncompleteData, decode, b"\x83w\1") + self.assertEqual((Atom(b""), b""), decode(b"\x83w\0")) + self.assertEqual((Atom(b""), b"tail"), decode(b"\x83w\0tail")) + self.assertEqual((Atom(b"test"), b""), decode(b"\x83w\4test")) + self.assertEqual((Atom(b"test"), b"tail"), decode(b"\x83w\4testtail")) + self.assertEqual((Atom(b"\xc3\xa4"), b""), decode(b"\x83w\2\xc3\xa4")) def test_decode_predefined_atoms(self): + # ATOM_EXT: self.assertEqual((True, b""), decode(b"\x83d\0\4true")) self.assertEqual((True, b"tail"), decode(b"\x83d\0\4truetail")) self.assertEqual((False, b""), decode(b"\x83d\0\5false")) self.assertEqual((False, b"tail"), decode(b"\x83d\0\5falsetail")) self.assertEqual((None, b""), decode(b"\x83d\0\11undefined")) self.assertEqual((None, b"tail"), decode(b"\x83d\0\11undefinedtail")) + # SMALL_ATOM_UTF8_EXT: + self.assertEqual((True, b""), decode(b"\x83w\4true")) + self.assertEqual((True, b"tail"), decode(b"\x83w\4truetail")) + self.assertEqual((False, b""), decode(b"\x83w\5false")) + self.assertEqual((False, b"tail"), decode(b"\x83w\5falsetail")) + self.assertEqual((None, b""), decode(b"\x83w\11undefined")) + self.assertEqual((None, b"tail"), decode(b"\x83w\11undefinedtail")) def test_decode_empty_list(self): self.assertEqual(([], b""), decode(b"\x83j"))