Skip to content

Commit

Permalink
[ruby/ipaddr] ntop: Measure address size in bytes
Browse files Browse the repository at this point in the history
`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: ruby/ipaddr#56

ruby/ipaddr@a33fd14d4a
  • Loading branch information
hanazuki authored and hsbt committed Dec 25, 2023
1 parent ea5776e commit eb53131
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
7 changes: 6 additions & 1 deletion lib/ipaddr.rb
Expand Up @@ -110,8 +110,13 @@ def self.new_ntoh(addr)

# Convert a network byte ordered string form of an IP address into
# human readable form.
# It expects the string to be encoded in Encoding::ASCII_8BIT (BINARY).
def self.ntop(addr)
case addr.size
if addr.is_a?(String) && addr.encoding != Encoding::BINARY
raise InvalidAddressError, "invalid encoding (given #{addr.encoding}, expected BINARY)"
end

case addr.bytesize
when 4
addr.unpack('C4').join('.')
when 16
Expand Down
29 changes: 24 additions & 5 deletions test/test_ipaddr.rb
Expand Up @@ -133,18 +133,37 @@ def test_s_new_ntoh

def test_ntop
# IPv4
assert_equal("192.168.1.1", IPAddr.ntop("\xC0\xA8\x01\x01"))
assert_equal("192.168.1.1", IPAddr.ntop("\xC0\xA8\x01\x01".b))
assert_equal("10.231.140.171", IPAddr.ntop("\x0A\xE7\x8C\xAB".b))
# IPv6
assert_equal("0000:0000:0000:0000:0000:0000:0000:0001",
IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"))
IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01".b))
assert_equal("fe80:0000:0000:0000:f09f:9985:f09f:9986",
IPAddr.ntop("\xFE\x80\x00\x00\x00\x00\x00\x00\xF0\x9F\x99\x85\xF0\x9F\x99\x86".b))

# Invalid parameters
## wrong length
assert_raise(IPAddr::AddressFamilyError) {
IPAddr.ntop("192.168.1.1")
IPAddr.ntop("192.168.1.1".b)
}

assert_raise(IPAddr::AddressFamilyError) {
IPAddr.ntop("\xC0\xA8\x01\xFF1")
IPAddr.ntop("\xC0\xA8\x01\xFF1".b)
}
## UTF-8
assert_raise(IPAddr::InvalidAddressError) {
IPAddr.ntop("192.168.1.1")
}
assert_raise(IPAddr::InvalidAddressError) {
IPAddr.ntop("\x0A\x0A\x0A\x0A")
}
assert_raise(IPAddr::InvalidAddressError) {
IPAddr.ntop("\x0A\xE7\x8C\xAB")
}
assert_raise(IPAddr::InvalidAddressError) {
IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
}
assert_raise(IPAddr::InvalidAddressError) {
IPAddr.ntop("\xFE\x80\x00\x00\x00\x00\x00\x00\xF0\x9F\x99\x85\xF0\x9F\x99\x86")
}
end

Expand Down

0 comments on commit eb53131

Please sign in to comment.