Permalink
Browse files

* lib/ipaddr.rb: Introduce several new error classes where only

  ArgumentError and StandardError were used.  IPAddr::Error is
  their common ancestor class that inherits from ArgumentError for
  backward compatibility.  Submitted by Jon Daniel.  Fixes #173 on
  GitHub.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36868 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
1 parent 926552f commit e03d266c1dbf82c25fd63a2a4a1a9665dbc1bab4 @knu knu committed Aug 31, 2012
Showing with 61 additions and 42 deletions.
  1. +8 −0 ChangeLog
  2. +53 −42 lib/ipaddr.rb
View
@@ -1,3 +1,11 @@
+Fri Aug 31 16:23:20 2012 Akinori MUSHA <knu@iDaemons.org>
+
+ * lib/ipaddr.rb: Introduce several new error classes where only
+ ArgumentError and StandardError were used. IPAddr::Error is
+ their common ancestor class that inherits from ArgumentError for
+ backward compatibility. Submitted by Jon Daniel. Fixes #173 on
+ GitHub.
+
Fri Aug 31 14:51:27 2012 NAKAMURA Usaku <usa@ruby-lang.org>
* test/bigdecimal/test_bigdecimal.rb (TestBigDecimal#test_to_f): added
View
@@ -82,6 +82,21 @@ 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 length.
+ class InvalidPrefixError < InvalidAddressError; end
+
# Returns the address family of this IP address.
attr_reader :family
@@ -100,7 +115,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
@@ -226,7 +241,7 @@ def hton
(@addr >> (112 - 16 * i)) & 0xffff
}.pack('n8')
else
- raise "unsupported address family"
+ raise AddressFamilyError, "unsupported address family"
end
end
@@ -258,7 +273,7 @@ def ipv4_compat?
# into an IPv4-mapped IPv6 address.
def ipv4_mapped
if !ipv4?
- raise ArgumentError, "not an IPv4 address"
+ raise InvalidAddressError, "not an IPv4 address"
end
return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
end
@@ -267,7 +282,7 @@ def ipv4_mapped
# into an IPv4-compatible IPv6 address.
def ipv4_compat
if !ipv4?
- raise ArgumentError, "not an IPv4 address"
+ raise InvalidAddressError, "not an IPv4 address"
end
return self.clone.set(@addr, Socket::AF_INET6)
end
@@ -291,22 +306,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 InvalidAddressError, "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 InvalidAddressError, "not an IPv6 address"
end
return _reverse + ".ip6.int"
end
@@ -346,7 +361,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)
@@ -361,7 +376,7 @@ 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))
@@ -376,14 +391,14 @@ 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]
@@ -400,7 +415,7 @@ def mask!(mask)
else
m = IPAddr.new(mask)
if m.family != @family
- raise ArgumentError, "address family is not same"
+ raise InvalidPrefixError, "address family is not same"
end
@mask_addr = m.to_i
@addr &= @mask_addr
@@ -412,18 +427,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
@@ -457,9 +472,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('/')
@@ -482,7 +497,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)
@@ -511,8 +526,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 InvalidAddressError, "zero-filled number in IPv4 address is ambiguous"
i << 8 | n
}
end
@@ -529,18 +544,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(':')
@@ -560,7 +575,7 @@ def addr_mask(addr)
when Socket::AF_INET6
return addr & IN6MASK
else
- raise "unsupported address family"
+ raise AddressFamilyError, "unsupported address family"
end
end
@@ -573,7 +588,7 @@ def _reverse
when Socket::AF_INET6
return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.')
else
- raise "unsupported address family"
+ raise AddressFamilyError, "unsupported address family"
end
end
@@ -586,7 +601,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
@@ -713,19 +728,15 @@ 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::InvalidAddressError) { IPAddr.new("192.168.0.011") }
+ assert_raises(IPAddr::InvalidAddressError) { IPAddr.new("fe80::1%fxp0") }
+ assert_raises(IPAddr::InvalidAddressError) { IPAddr.new("[192.168.1.2]/120") }
+ assert_raises(IPAddr::InvalidPrefixError) { IPAddr.new("::1/255.255.255.0") }
+ assert_raises(IPAddr::InvalidPrefixError) { IPAddr.new("::1/129") }
+ assert_raises(IPAddr::InvalidPrefixError) { IPAddr.new("192.168.0.1/33") }
+ assert_raises(IPAddr::AddressFamilyError) { IPAddr.new(1) }
+ assert_raises(IPAddr::AddressFamilyError) { IPAddr.new("::ffff:192.168.1.2/120", Socket::AF_INET) }
end
def test_s_new_ntoh
@@ -786,14 +797,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::InvalidAddressError) {
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::InvalidAddressError) {
IPAddr.new("192.168.2.1").ip6_int
}
end

0 comments on commit e03d266

Please sign in to comment.