Skip to content

Commit

Permalink
Merge pull request #123 from kaoudis/kaoudis/remove-ambiguous-leading…
Browse files Browse the repository at this point in the history
…-zero-ipv4-octets

remove possibility of base-ambiguous IPv4 octets with leading zeroes
  • Loading branch information
bluemonk authored Jul 18, 2021
2 parents 1d48e38 + bb4fb04 commit 826d6fa
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 31 deletions.
44 changes: 22 additions & 22 deletions lib/ipaddress.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -71,7 +71,7 @@ def self.ntoa(uint)
raise(::ArgumentError, "not a long integer: #{uint.inspect}")
end
ret = []
4.times do
4.times do
ret.unshift(uint & 0xff)
uint >>= 8
end
Expand All @@ -89,7 +89,7 @@ def self.ntoa(uint)
def ipv4?
self.kind_of? IPAddress::IPv4
end

#
# True if the object is an IPv6 address
#
Expand Down Expand Up @@ -124,7 +124,7 @@ def self.valid?(addr)
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
#
Expand Down Expand Up @@ -196,12 +196,12 @@ def self.valid_ipv6_subnet?(addr)
# #=> 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.
Expand All @@ -215,7 +215,7 @@ def self.valid_ipv4_netmask?(addr)
rescue
return false
end

#
# Checks if the given string is a valid IPv6 address
#
Expand All @@ -227,43 +227,43 @@ def self.valid_ipv4_netmask?(addr)
# 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:
#
# ip = IPAddress "172.16.10.1/24"
# 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
Expand All @@ -285,8 +285,8 @@ class Hash # :nodoc:
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
Expand Down
33 changes: 24 additions & 9 deletions test/ipaddress_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@ def setup

@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",
Expand All @@ -39,18 +41,18 @@ def setup

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])}
Expand All @@ -59,6 +61,19 @@ def test_method_IPAddress
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")
Expand Down

0 comments on commit 826d6fa

Please sign in to comment.