Skip to content

Commit be01430

Browse files
committed
ntop: Measure address size in bytes
`IPAddr.ntop` takes the binary representation of an IP address, whose length should be 4 or 16 *bytes* (not characters/codepoints). The current implementation accepts strings in any encoding, but for some values in non-BINARY encoding, it fails proper length check and raises an `AddressFamilyError`. Since passing strings in a multibyte encoding has never worked correctly for years, this patch makes it an explicit error with an `InvalidAddressError`. Fixes: #56
1 parent a2a09e3 commit be01430

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

lib/ipaddr.rb

+6-1
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,13 @@ def self.new_ntoh(addr)
110110

111111
# Convert a network byte ordered string form of an IP address into
112112
# human readable form.
113+
# It expects the string to be encoded in Encoding::US_ASCII (BINARY).
113114
def self.ntop(addr)
114-
case addr.size
115+
if addr.is_a?(String) && addr.encoding != Encoding::BINARY
116+
raise InvalidAddressError, "invalid encoding (given #{addr.encoding}, expected BINARY)"
117+
end
118+
119+
case addr.bytesize
115120
when 4
116121
addr.unpack('C4').join('.')
117122
when 16

test/test_ipaddr.rb

+24-5
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,37 @@ def test_s_new_ntoh
133133

134134
def test_ntop
135135
# IPv4
136-
assert_equal("192.168.1.1", IPAddr.ntop("\xC0\xA8\x01\x01"))
136+
assert_equal("192.168.1.1", IPAddr.ntop("\xC0\xA8\x01\x01".b))
137+
assert_equal("10.231.140.171", IPAddr.ntop("\x0A\xE7\x8C\xAB".b))
137138
# IPv6
138139
assert_equal("0000:0000:0000:0000:0000:0000:0000:0001",
139-
IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"))
140+
IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01".b))
141+
assert_equal("fe80:0000:0000:0000:f09f:9985:f09f:9986",
142+
IPAddr.ntop("\xFE\x80\x00\x00\x00\x00\x00\x00\xF0\x9F\x99\x85\xF0\x9F\x99\x86".b))
140143

141144
# Invalid parameters
145+
## wrong length
142146
assert_raise(IPAddr::AddressFamilyError) {
143-
IPAddr.ntop("192.168.1.1")
147+
IPAddr.ntop("192.168.1.1".b)
144148
}
145-
146149
assert_raise(IPAddr::AddressFamilyError) {
147-
IPAddr.ntop("\xC0\xA8\x01\xFF1")
150+
IPAddr.ntop("\xC0\xA8\x01\xFF1".b)
151+
}
152+
## UTF-8
153+
assert_raise(IPAddr::InvalidAddressError) {
154+
IPAddr.ntop("192.168.1.1")
155+
}
156+
assert_raise(IPAddr::InvalidAddressError) {
157+
IPAddr.ntop("\x0A\x0A\x0A\x0A")
158+
}
159+
assert_raise(IPAddr::InvalidAddressError) {
160+
IPAddr.ntop("\x0A\xE7\x8C\xAB")
161+
}
162+
assert_raise(IPAddr::InvalidAddressError) {
163+
IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
164+
}
165+
assert_raise(IPAddr::InvalidAddressError) {
166+
IPAddr.ntop("\xFE\x80\x00\x00\x00\x00\x00\x00\xF0\x9F\x99\x85\xF0\x9F\x99\x86")
148167
}
149168
end
150169

0 commit comments

Comments
 (0)