diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb index 10027f3..538a799 100644 --- a/lib/ipaddr.rb +++ b/lib/ipaddr.rb @@ -712,6 +712,7 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC) raise AddressFamilyError, "unsupported address family: #{family}" end end + requested_family = family prefix, prefixlen = addr.split('/', 2) if prefix =~ /\A\[(.*)\]\z/i prefix = $1 @@ -722,6 +723,9 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC) zone_id = $2 family = Socket::AF_INET6 end + if requested_family != Socket::AF_UNSPEC && family != requested_family + raise AddressFamilyError, "address family mismatch" + end # It seems AI_NUMERICHOST doesn't do the job. #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil, # Socket::AI_NUMERICHOST) diff --git a/test/test_ipaddr.rb b/test/test_ipaddr.rb index 6a4b0cb..b37a07d 100644 --- a/test/test_ipaddr.rb +++ b/test/test_ipaddr.rb @@ -3,6 +3,18 @@ require 'ipaddr' class TC_IPAddr < Test::Unit::TestCase + def test_ipv6_literals_respect_explicit_family + ['[::]', '::%eth0', '[::%eth0]', '[fe80::1%eth0]/64'].each do |literal| + assert_raise(IPAddr::AddressFamilyError, literal) do + IPAddr.new(literal, Socket::AF_INET) + end + assert_raise(IPAddr::AddressFamilyError, literal) do + IPAddr.new(literal, Socket::AF_UNIX) + end + assert_equal(IPAddr.new(literal), IPAddr.new(literal, Socket::AF_INET6)) + end + end + def test_s_new [ ["3FFE:505:ffff::/48"],