From bb4fb04de5e7413642176c7ffd60bae696295fcf Mon Sep 17 00:00:00 2001 From: kaoudis Date: Sat, 17 Jul 2021 11:46:05 -0600 Subject: remove potential for creating base-ambiguous octets of three digits or less --- lib/ipaddress.rb | 44 ++++++++++++++++++++++---------------------- test/ipaddress_test.rb | 33 ++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/lib/ipaddress.rb b/lib/ipaddress.rb index 280b450..96ac9f5 100644 --- a/lib/ipaddress.rb +++ b/lib/ipaddress.rb @@ -26,12 +26,12 @@ module IPAddress # Parse the argument string to create a new # IPv4, IPv6 or Mapped IP object # - # ip = IPAddress.parse 167837953 # 10.1.1.1 + # ip = IPAddress.parse 167837953 # 10.1.1.1 # ip = IPAddress.parse "172.16.10.1/24" # ip6 = IPAddress.parse "2001:db8::8:800:200c:417a/64" # ip_mapped = IPAddress.parse "::ffff:172.16.10.1/128" # - # All the object created will be instances of the + # All the object created will be instances of the # correct class: # # ip.class @@ -42,17 +42,17 @@ module IPAddress # #=> IPAddress::IPv6::Mapped # def IPAddress::parse(str) - + # Check if an int was passed if str.kind_of? Integer - return IPAddress::IPv4.new(ntoa(str)) + return IPAddress::IPv4.new(ntoa(str)) end case str when /:.+\./ IPAddress::IPv6::Mapped.new(str) when /\./ - IPAddress::IPv4.new(str) + IPAddress::IPv4.new(str) when /:/ IPAddress::IPv6.new(str) else @@ -71,7 +71,7 @@ module IPAddress raise(::ArgumentError, "not a long integer: #{uint.inspect}") end ret = [] - 4.times do + 4.times do ret.unshift(uint & 0xff) uint >>= 8 end @@ -89,7 +89,7 @@ module IPAddress def ipv4? self.kind_of? IPAddress::IPv4 end - + # # True if the object is an IPv6 address # @@ -124,7 +124,7 @@ module IPAddress valid_ip?(addr) || valid_ipv4_subnet?(addr) || valid_ipv6_subnet?(addr) end - # + # # Checks if the given string is a valid IP address, # either IPv4 or IPv6 # @@ -196,12 +196,12 @@ module IPAddress # #=> true # def self.valid_ipv4?(addr) - if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr + if /^(0|[1-9]{1}\d{0,2})\.(0|[1-9]{1}\d{0,2})\.(0|[1-9]{1}\d{0,2})\.(0|[1-9]{1}\d{0,2})$/ =~ addr return $~.captures.all? {|i| i.to_i < 256} end false end - + # # Checks if the argument is a valid IPv4 netmask # expressed in dotted decimal format. @@ -215,7 +215,7 @@ module IPAddress rescue return false end - + # # Checks if the given string is a valid IPv6 address # @@ -227,35 +227,35 @@ module IPAddress # IPAddress::valid_ipv6? "2002::DEAD::BEEF" # #=> false # - def self.valid_ipv6?(addr) + def self.valid_ipv6?(addr) # https://gist.github.com/cpetschnig/294476 # http://forums.intermapper.com/viewtopic.php?t=452 return true if /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ =~ addr false end - # + # # Deprecate method # def self.deprecate(message = nil) # :nodoc: message ||= "You are using deprecated behavior which will be removed from the next major or minor release." warn("DEPRECATION WARNING: #{message}") end - + end # module IPAddress # -# IPAddress is a wrapper method built around -# IPAddress's library classes. Its purpouse is to -# make you indipendent from the type of IP address +# IPAddress is a wrapper method built around +# IPAddress's library classes. Its purpouse is to +# make you indipendent from the type of IP address # you're going to use. # -# For example, instead of creating the three types +# For example, instead of creating the three types # of IP addresses using their own contructors # # ip = IPAddress::IPv4.new "172.16.10.1/24" # ip6 = IPAddress::IPv6.new "2001:db8::8:800:200c:417a/64" -# ip_mapped = IPAddress::IPv6::Mapped "::ffff:172.16.10.1/128" +# ip_mapped = IPAddress::IPv6::Mapped "::ffff:172.16.10.1/128" # # you can just use the IPAddress wrapper: # @@ -263,7 +263,7 @@ end # module IPAddress # ip6 = IPAddress "2001:db8::8:800:200c:417a/64" # ip_mapped = IPAddress "::ffff:172.16.10.1/128" # -# All the object created will be instances of the +# All the object created will be instances of the # correct class: # # ip.class @@ -285,8 +285,8 @@ if RUBY_VERSION =~ /^1\.8/ alias :key :index end module Math # :nodoc: - def Math.log2(n) - log(n) / log(2) + def Math.log2(n) + log(n) / log(2) end end end diff --git a/test/ipaddress_test.rb b/test/ipaddress_test.rb index d5bdf60..777352e 100644 --- a/test/ipaddress_test.rb +++ b/test/ipaddress_test.rb @@ -18,17 +18,19 @@ class IPAddressTest < Minitest::Test @invalid_ipv4_uint32 = [4294967296, # 256.0.0.0 "A294967295", # Invalid uINT - -1] # Invalid + -1] # Invalid @ipv4class = IPAddress::IPv4 @ipv6class = IPAddress::IPv6 @mappedclass = IPAddress::IPv6::Mapped - + @invalid_ipv4 = ["10.0.0.256", "10.0.0.0.0", "10.0.0", - "10.0"] + "10.0", + "0127.010.010.010", + "055.055.055.055"] @valid_ipv4_range = ["10.0.0.1-254", "10.0.1-254.0", @@ -39,18 +41,18 @@ class IPAddressTest < Minitest::Test def test_method_IPAddress - assert_instance_of @ipv4class, @method.call(@valid_ipv4) - assert_instance_of @ipv6class, @method.call(@valid_ipv6) + assert_instance_of @ipv4class, @method.call(@valid_ipv4) + assert_instance_of @ipv6class, @method.call(@valid_ipv6) assert_instance_of @mappedclass, @method.call(@valid_mapped) assert_raises(ArgumentError) {@method.call(@invalid_ipv4)} assert_raises(ArgumentError) {@method.call(@invalid_ipv6)} assert_raises(ArgumentError) {@method.call(@invalid_mapped)} - assert_instance_of @ipv4class, @method.call(@valid_ipv4_uint32[0]) - assert_instance_of @ipv4class, @method.call(@valid_ipv4_uint32[1]) - assert_instance_of @ipv4class, @method.call(@valid_ipv4_uint32[2]) - assert_instance_of @ipv4class, @method.call(@valid_ipv4_uint32[3]) + assert_instance_of @ipv4class, @method.call(@valid_ipv4_uint32[0]) + assert_instance_of @ipv4class, @method.call(@valid_ipv4_uint32[1]) + assert_instance_of @ipv4class, @method.call(@valid_ipv4_uint32[2]) + assert_instance_of @ipv4class, @method.call(@valid_ipv4_uint32[3]) assert_raises(ArgumentError) {@method.call(@invalid_ipv4_uint32[0])} assert_raises(ArgumentError) {@method.call(@invalid_ipv4_uint32[1])} @@ -59,6 +61,19 @@ class IPAddressTest < Minitest::Test end def test_module_method_valid? + assert_equal true, IPAddress::valid?("0.0.0.5/20") + assert_equal true, IPAddress::valid?("0.0.0.0/8") + assert_equal false, IPAddress::valid?("800.754.1.1/13") + assert_equal false, IPAddress::valid?("0xff/4") + assert_equal false, IPAddress::valid?("0xff.0xff.0xff.0xfe/20") + assert_equal false, IPAddress::valid?("037.05.05.01/8") + assert_equal false, IPAddress::valid?("0127.0.0.01/16") + assert_equal false, IPAddress::valid?("055.027.043.09/16") + # four digits fails the three digits check + assert_equal false, IPAddress::valid?("0255.0255.0255.01/20") + assert_equal false, IPAddress::valid?("013.055.0255.0216/29") + assert_equal false, IPAddress::valid?("013.055.025.021/29") + assert_equal false, IPAddress::valid?("052.015.024.020/29") assert_equal true, IPAddress::valid?("10.0.0.0/24") assert_equal true, IPAddress::valid?("10.0.0.0/255.255.255.0") assert_equal false, IPAddress::valid?("10.0.0.0/64") -- cgit v1.2.1