Skip to content
Open
Show file tree
Hide file tree
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
19 changes: 19 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,31 @@
module ValidatesUrlFormatOf
IPv4_PART = /\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]/ # 0-255

# http://en.wikipedia.org/wiki/IP_address
# http://en.wikipedia.org/wiki/Default_route
# http://en.wikipedia.org/wiki/Localhost

# Blocks IPv4 10.0.0.0 - 10.255.255.255
TWENTY_FOUR_BIT_BLOCK = /(?!10\.((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.?)){3})/
# Blocks IPv4 172.16.0.0 - 172.31.255.255
TWENTY_BIT_BLOCK = /(?!172\.(0?3[0-1]|0?2[0-9]|0?1[6-9])\.((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.?)){2})/
# Blocks IPv4 192.168.0.0 - 192.168.255.255
SIXTEEN_BIT_BLOCK = /(?!192\.168\.((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.?)){2})/
# Blocks IPv4 127.0.0.1 (which is also localhost)
LOCALHOST_LOOPBACK = /(?!127\.0\.0\.[0-8])/
ALL_ROUTES = /(?!0\.0\.0\.0)/
RFC_1918_IPS = %r{#{TWENTY_FOUR_BIT_BLOCK}#{TWENTY_BIT_BLOCK}#{SIXTEEN_BIT_BLOCK}}

# First regexp doesn't work in Ruby 1.8 and second has a bug in 1.9.2:
# https://github.com/henrik/validates_url_format_of/issues/issue/4/#comment_760674
ALNUM = "ä".match(/[[:alnum:]]/) ? /[[:alnum:]]/ : /[^\W_]/

REGEXP = %r{
\A
https?:// # http:// or https://
#{LOCALHOST_LOOPBACK} # blocks 127.0.0.0/8
#{ALL_ROUTES} # blocks 0.0.0.0
#{RFC_1918_IPS} # blocks the use of RFC 1918 private network IPv4 addresses
([^\s:@]+:[^\s:@]*@)? # optional username:pw@
( ((#{ALNUM}+\.)*xn--)?#{ALNUM}+([-.]#{ALNUM}+)*\.[a-z]{2,6}\.? | # domain (including Punycode/IDN)...
#{IPv4_PART}(\.#{IPv4_PART}){3} ) # or IPv4
Expand All @@ -20,6 +38,7 @@ module ValidatesUrlFormatOf
DEFAULT_MESSAGE = 'does not appear to be a valid URL'
DEFAULT_MESSAGE_URL = 'does not appear to be valid'


def validates_url_format_of(*attr_names)
options = { :allow_nil => false,
:allow_blank => false,
Expand Down
13 changes: 13 additions & 0 deletions test/validates_url_format_of_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ def test_should_reject_invalid_urls
end
end

def test_require_publicly_routeable_ip4_addresses
private_ips_10 = 100.times.map { "http://10.#{Random.new.rand(0..255)}.#{Random.new.rand(0..255)}.#{Random.new.rand(0..255)}" }
private_ips_172 = 100.times.map { "http://172.#{Random.new.rand(16..31)}.#{Random.new.rand(0..255)}.#{Random.new.rand(0..255)}" }
private_ips_192 = 100.times.map { "http://192.168.#{Random.new.rand(0..255)}.#{Random.new.rand(0..255)}" }
reserved_ips = (private_ips_10 << private_ips_172 << private_ips_192 << "http://0.0.0.0" << "http://127.0.0.1").flatten
reserved_ips.each do |url|
@model.homepage = url
@model.valid?
assert [email protected][:homepage].empty?, "#{url.inspect} should have been rejected"
end

end

def test_different_defaults_based_on_attribute_name
@model.homepage = 'x'
@model.my_UrL_hooray = 'x'
Expand Down