Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Added meaningful exceptions to IPAddr #173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 59 additions & 42 deletions lib/ipaddr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,27 @@ class IPAddr
\z
}xi

# Generic IPAddr related error. Exceptions raised in this class should
# inherit from Error.
class Error < ArgumentError; end

# Raised when the provided IP address is an invalid address.
class InvalidAddressError < Error; end

# Raised when the address family is invalid such as an address with an
# unsupported family, an address with an inconsistent family, or an address
# who's family cannot be determined.
class AddressFamilyError < Error; end

# Raised when the address is an invalid IPv4 address.
class InvalidIPv4Error < Error; end

# Raised when the address is an invalid IPv6 address.
class InvalidIPv6Error < Error; end

# Raised when the address is an invalid length.
class InvalidPrefixError < Error; end

# Returns the address family of this IP address.
attr_reader :family

Expand All @@ -100,7 +121,7 @@ def IPAddr::ntop(addr)
when 16
s = IN6FORMAT % addr.unpack('n8')
else
raise ArgumentError, "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
return s
end
Expand Down Expand Up @@ -226,7 +247,7 @@ def hton
(@addr >> (112 - 16 * i)) & 0xffff
}.pack('n8')
else
raise "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
end

Expand Down Expand Up @@ -258,7 +279,7 @@ def ipv4_compat?
# into an IPv4-mapped IPv6 address.
def ipv4_mapped
if !ipv4?
raise ArgumentError, "not an IPv4 address"
raise InvalidIPv4Error, "not an IPv4 address"
end
return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
end
Expand All @@ -267,7 +288,7 @@ def ipv4_mapped
# into an IPv4-compatible IPv6 address.
def ipv4_compat
if !ipv4?
raise ArgumentError, "not an IPv4 address"
raise InvalidIPv4Error, "not an IPv4 address"
end
return self.clone.set(@addr, Socket::AF_INET6)
end
Expand All @@ -291,22 +312,22 @@ def reverse
when Socket::AF_INET6
return ip6_arpa
else
raise "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
end

# Returns a string for DNS reverse lookup compatible with RFC3172.
def ip6_arpa
if !ipv6?
raise ArgumentError, "not an IPv6 address"
raise InvalidIPv6Error, "not an IPv6 address"
end
return _reverse + ".ip6.arpa"
end

# Returns a string for DNS reverse lookup compatible with RFC1886.
def ip6_int
if !ipv6?
raise ArgumentError, "not an IPv6 address"
raise InvalidIPv6Error, "not an IPv6 address"
end
return _reverse + ".ip6.int"
end
Expand Down Expand Up @@ -346,7 +367,7 @@ def to_range
when Socket::AF_INET6
end_addr = (@addr | (IN6MASK ^ @mask_addr))
else
raise "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end

return clone.set(begin_addr, @family)..clone.set(end_addr, @family)
Expand All @@ -361,29 +382,31 @@ def inspect
when Socket::AF_INET6
af = "IPv6"
else
raise "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
return sprintf("#<%s: %s:%s/%s>", self.class.name,
af, _to_string(@addr), _to_string(@mask_addr))
end

protected



# Set +@addr+, the internal stored ip address, to given +addr+. The
# parameter +addr+ is validated using the first +family+ member,
# which is +Socket::AF_INET+ or +Socket::AF_INET6+.
def set(addr, *family)
case family[0] ? family[0] : @family
when Socket::AF_INET
if addr < 0 || addr > IN4MASK
raise ArgumentError, "invalid address"
raise InvalidAddressError, "invalid address"
end
when Socket::AF_INET6
if addr < 0 || addr > IN6MASK
raise ArgumentError, "invalid address"
raise InvalidAddressError, "invalid address"
end
else
raise ArgumentError, "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
@addr = addr
if family[0]
Expand All @@ -400,7 +423,7 @@ def mask!(mask)
else
m = IPAddr.new(mask)
if m.family != @family
raise ArgumentError, "address family is not same"
raise AddressFamilyError, "address family is not same"
end
@mask_addr = m.to_i
@addr &= @mask_addr
Expand All @@ -412,18 +435,18 @@ def mask!(mask)
case @family
when Socket::AF_INET
if prefixlen < 0 || prefixlen > 32
raise ArgumentError, "invalid length"
raise InvalidPrefixError, "invalid length"
end
masklen = 32 - prefixlen
@mask_addr = ((IN4MASK >> masklen) << masklen)
when Socket::AF_INET6
if prefixlen < 0 || prefixlen > 128
raise ArgumentError, "invalid length"
raise InvalidPrefixError, "invalid length"
end
masklen = 128 - prefixlen
@mask_addr = ((IN6MASK >> masklen) << masklen)
else
raise "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
@addr = ((@addr >> masklen) << masklen)
return self
Expand Down Expand Up @@ -457,9 +480,9 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC)
@mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
return
when Socket::AF_UNSPEC
raise ArgumentError, "address family must be specified"
raise AddressFamilyError, "address family must be specified"
else
raise ArgumentError, "unsupported address family: #{family}"
raise AddressFamilyError, "unsupported address family: #{family}"
end
end
prefix, prefixlen = addr.split('/')
Expand All @@ -482,7 +505,7 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC)
@family = Socket::AF_INET6
end
if family != Socket::AF_UNSPEC && @family != family
raise ArgumentError, "address family mismatch"
raise AddressFamilyError, "address family mismatch"
end
if prefixlen
mask!(prefixlen)
Expand Down Expand Up @@ -511,8 +534,8 @@ def in_addr(addr)
octets = m.captures
end
octets.inject(0) { |i, s|
(n = s.to_i) < 256 or raise ArgumentError, "invalid address"
s.match(/\A0./) and raise ArgumentError, "zero-filled number is ambiguous"
(n = s.to_i) < 256 or raise InvalidAddressError, "invalid address"
s.match(/\A0./) and raise InvalidIPv4Error, "zero-filled number is ambiguous"
i << 8 | n
}
end
Expand All @@ -529,18 +552,18 @@ def in6_addr(left)
right = ''
when RE_IPV6ADDRLIKE_COMPRESSED
if $4
left.count(':') <= 6 or raise ArgumentError, "invalid address"
left.count(':') <= 6 or raise InvalidAddressError, "invalid address"
addr = in_addr($~[4,4])
left = $1
right = $3 + '0:0'
else
left.count(':') <= 7 or raise ArgumentError, "invalid address"
left.count(':') <= 7 or raise InvalidAddressError, "invalid address"
left = $1
right = $2
addr = 0
end
else
raise ArgumentError, "invalid address"
raise InvalidAddressError, "invalid address"
end
l = left.split(':')
r = right.split(':')
Expand All @@ -560,7 +583,7 @@ def addr_mask(addr)
when Socket::AF_INET6
return addr & IN6MASK
else
raise "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
end

Expand All @@ -573,7 +596,7 @@ def _reverse
when Socket::AF_INET6
return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.')
else
raise "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
end

Expand All @@ -586,7 +609,7 @@ def _to_string(addr)
when Socket::AF_INET6
return (("%.32x" % addr).gsub!(/.{4}(?!$)/, '\&:'))
else
raise "unsupported address family"
raise AddressFamilyError, "unsupported address family"
end
end

Expand Down Expand Up @@ -713,19 +736,13 @@ def test_s_new

assert_equal("2001:200:300::", IPAddr.new("[2001:200:300::]/48").to_s)

[
["192.168.0.256"],
["192.168.0.011"],
["fe80::1%fxp0"],
["::1/255.255.255.0"],
[IPAddr.new("::1").to_i],
["::ffff:192.168.1.2/120", Socket::AF_INET],
["[192.168.1.2]/120"],
].each { |args|
assert_raises(ArgumentError) {
IPAddr.new(*args)
}
}
assert_raises(IPAddr::InvalidAddressError) { IPAddr.new('192.168.0.256') }
assert_raises(IPAddr::InvalidIPv4Error) { IPAddr.new('192.168.0.011') }
assert_raises(IPAddr::InvalidAddressError) { IPAddr.new("fe80::1%fxp0") }
assert_raises(IPAddr::AddressFamilyError) { IPAddr.new("::1/255.255.255.0") }
assert_raises(IPAddr::AddressFamilyError) { IPAddr.new(1) }
assert_raises(IPAddr::AddressFamilyError) { IPAddr.new("::ffff:192.168.1.2/120", Socket::AF_INET) }
assert_raises(IPAddr::InvalidAddressError) { IPAddr.new("[192.168.1.2]/120") }
end

def test_s_new_ntoh
Expand Down Expand Up @@ -786,14 +803,14 @@ def test_reverse

def test_ip6_arpa
assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa", IPAddr.new("3ffe:505:2::f").ip6_arpa)
assert_raises(ArgumentError) {
assert_raises(IPAddr::InvalidIPv6Error) {
IPAddr.new("192.168.2.1").ip6_arpa
}
end

def test_ip6_int
assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.int", IPAddr.new("3ffe:505:2::f").ip6_int)
assert_raises(ArgumentError) {
assert_raises(IPAddr::InvalidIPv6Error) {
IPAddr.new("192.168.2.1").ip6_int
}
end
Expand Down