Skip to content

Commit b139b77

Browse files
authored
Merge pull request #35 from alexander255/master
Allow parsing of DNS names and non-ASCII unix sockets
2 parents 164dcc3 + 73dead9 commit b139b77

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

multiaddr/codec.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import base58
22
import base64
33
import binascii
4+
import os
45

6+
import idna
57
from netaddr import IPAddress
68

79
from .protocols import code_to_varint
10+
from .protocols import P_DNS
11+
from .protocols import P_DNS4
12+
from .protocols import P_DNS6
813
from .protocols import P_DCCP
914
from .protocols import P_IP4
1015
from .protocols import P_IP6
@@ -156,7 +161,11 @@ def address_string_to_bytes(proto, addr_string):
156161
raise ValueError("invalid P2P multihash: %s" % mm)
157162
return b''.join([size, mm])
158163
elif proto.code == P_UNIX:
159-
addr_string_bytes = addr_string.encode("ascii")
164+
addr_string_bytes = os.fsencode(addr_string)
165+
size = code_to_varint(len(addr_string_bytes))
166+
return b''.join([size, binascii.hexlify(addr_string_bytes)])
167+
elif proto.code in (P_DNS, P_DNS4, P_DNS6):
168+
addr_string_bytes = idna.encode(addr_string, uts46=True)
160169
size = code_to_varint(len(addr_string_bytes))
161170
return b''.join([size, binascii.hexlify(addr_string_bytes)])
162171
else:
@@ -192,7 +201,11 @@ def address_bytes_to_string(proto, buf):
192201
elif proto.code == P_UNIX:
193202
buf = binascii.unhexlify(buf)
194203
size, num_bytes_read = read_varint_code(buf)
195-
return buf[num_bytes_read:].decode('ascii')
204+
return os.fsdecode(buf[num_bytes_read:])
205+
elif proto.code in (P_DNS, P_DNS4, P_DNS6):
206+
buf = binascii.unhexlify(buf)
207+
size, num_bytes_read = read_varint_code(buf)
208+
return idna.decode(buf[num_bytes_read:])
196209
raise ValueError("unknown protocol")
197210

198211

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ varint
22
six
33
base58
44
netaddr
5+
idna

tests/test_codec.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@
2323
(_names_to_protocols['p2p'],
2424
b'221220d52ebb89d85b02a284948203a62ff28389c57c9f42beec4ec20db76a68911c0b',
2525
'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'),
26+
27+
# Additional test data
28+
(_names_to_protocols['dns4'],
29+
b'30786e2d2d34676272696d2e786e2d2d2d2d796d63626161616a6c6336646a3762786e6532632e786e2d2d776762683163',
30+
u'موقع.وزارة-الاتصالات.مصر'), # Explicietly mark as unicode to force it LTR
31+
(_names_to_protocols['dns4'],
32+
b'16786e2d2d667562616c6c2d6374612e6578616d706c65',
33+
'fußball.example'), # This will fail if IDNA-2003/NamePrep is used
2634
]
2735

2836
BYTES_MAP_STR_TEST_DATA = [

tests/test_multiaddr.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545
"/ip4/127.0.0.1/p2p/tcp",
4646
"/unix",
4747
"/ip4/1.2.3.4/tcp/80/unix",
48-
"/ip4/127.0.0.1/tcp/9090/http/p2p-webcrt-direct"])
48+
"/ip4/127.0.0.1/tcp/9090/http/p2p-webcrt-direct",
49+
"/dns",
50+
"/dns4",
51+
"/dns6"])
4952
def test_invalid(addr_str):
5053
with pytest.raises(ValueError):
5154
Multiaddr(addr_str)
@@ -77,10 +80,13 @@ def test_invalid(addr_str):
7780
"/ip4/127.0.0.1/udp/1234",
7881
"/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
7982
"/unix/a/b/c/d/e",
83+
"/unix/Überrschung!/大柱",
8084
"/unix/stdio",
8185
"/ip4/1.2.3.4/tcp/80/unix/a/b/c/d/e/f",
8286
"/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234/unix/stdio",
83-
"/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct"]) # nopep8
87+
"/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct",
88+
"/dns/example.com",
89+
"/dns4/موقع.وزارة-الاتصالات.مصر"]) # nopep8
8490
def test_valid(addr_str):
8591
ma = Multiaddr(addr_str)
8692
assert str(ma) == addr_str.rstrip("/")

0 commit comments

Comments
 (0)