From e03d266c1dbf82c25fd63a2a4a1a9665dbc1bab4 Mon Sep 17 00:00:00 2001 From: knu Date: Fri, 31 Aug 2012 07:30:22 +0000 Subject: * 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 --- lib/ipaddr.rb | 95 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 42 deletions(-) (limited to 'lib/ipaddr.rb') diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb index 716ccaad40..a91dcc56ae 100644 --- a/lib/ipaddr.rb +++ b/lib/ipaddr.rb @@ -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 @@ class IPAddr 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 @@ class IPAddr (@addr >> (112 - 16 * i)) & 0xffff }.pack('n8') else - raise "unsupported address family" + raise AddressFamilyError, "unsupported address family" end end @@ -258,7 +273,7 @@ class IPAddr # 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 @@ class IPAddr # 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,14 +306,14 @@ class IPAddr 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 @@ -306,7 +321,7 @@ class IPAddr # 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 @@ class IPAddr 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 @@ class IPAddr 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 @@ class IPAddr 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 @@ class IPAddr 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 @@ class IPAddr 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 @@ class IPAddr @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 @@ class IPAddr @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 @@ class IPAddr 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 @@ class IPAddr 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 @@ class IPAddr when Socket::AF_INET6 return addr & IN6MASK else - raise "unsupported address family" + raise AddressFamilyError, "unsupported address family" end end @@ -573,7 +588,7 @@ class IPAddr 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 @@ class IPAddr 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 @@ class TC_IPAddr < Test::Unit::TestCase 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 @@ class TC_IPAddr < Test::Unit::TestCase 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 -- cgit v1.2.3