From 1c303da20351a6f7d3715e2a32cad766df4b73ae Mon Sep 17 00:00:00 2001 From: Jonas Peschla Date: Sun, 26 Oct 2014 12:32:03 +0100 Subject: [PATCH 1/2] Use IPAddr class to validate ip formats --- lib/json-schema/attributes/formats/ip4.rb | 14 +++++--------- lib/json-schema/attributes/formats/ip6.rb | 22 +++++----------------- test/test_jsonschema_draft1.rb | 2 ++ test/test_jsonschema_draft2.rb | 2 ++ test/test_jsonschema_draft3.rb | 2 ++ test/test_jsonschema_draft4.rb | 2 ++ 6 files changed, 18 insertions(+), 26 deletions(-) diff --git a/lib/json-schema/attributes/formats/ip4.rb b/lib/json-schema/attributes/formats/ip4.rb index e4d5da60..6e59b9c1 100644 --- a/lib/json-schema/attributes/formats/ip4.rb +++ b/lib/json-schema/attributes/formats/ip4.rb @@ -1,20 +1,16 @@ require 'json-schema/attribute' -require 'uri' +require 'ipaddr' module JSON class Schema class IP4Format < FormatAttribute def self.validate(current_schema, data, fragments, processor, validator, options = {}) if data.is_a?(String) error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv4 address" - r = Regexp.new('^(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}$') - if (m = r.match(data)) - 1.upto(4) do |x| - validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[x].to_i > 255 - end - else - validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) - return + begin + ip = IPAddr.new data + rescue IPAddr::InvalidAddressError end + validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) unless ip && ip.ipv4? end end end diff --git a/lib/json-schema/attributes/formats/ip6.rb b/lib/json-schema/attributes/formats/ip6.rb index bdfd7673..3f595a1d 100644 --- a/lib/json-schema/attributes/formats/ip6.rb +++ b/lib/json-schema/attributes/formats/ip6.rb @@ -1,28 +1,16 @@ require 'json-schema/attribute' -require 'uri' +require 'ipaddr' module JSON class Schema class IP6Format < FormatAttribute def self.validate(current_schema, data, fragments, processor, validator, options = {}) if data.is_a?(String) error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv6 address" - r = Regexp.new('^[a-f0-9:]+$') - if (r.match(data)) - # All characters are valid, now validate structure - parts = data.split(":") - validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if parts.length > 8 - condensed_zeros = false - parts.each do |part| - if part.length == 0 - validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if condensed_zeros - condensed_zeros = true - end - validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if part.length > 4 - end - else - validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) - return + begin + ip = IPAddr.new data + rescue IPAddr::InvalidAddressError end + validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) unless ip && ip.ipv6? end end end diff --git a/test/test_jsonschema_draft1.rb b/test/test_jsonschema_draft1.rb index 2d77e16b..9b9b0b64 100644 --- a/test/test_jsonschema_draft1.rb +++ b/test/test_jsonschema_draft1.rb @@ -613,6 +613,8 @@ def test_format_ipv6 assert(!JSON::Validator.validate(schema,data,:version => :draft1)) data = {"a" => "1111:2222:8888:9999:aaaa:cccc:eeee:ffff:bbbb"} assert(!JSON::Validator.validate(schema,data,:version => :draft1)) + assert(JSON::Validator.validate(schema, {"a" => "::1"}, :version => :draft1), 'validate with shortcut') + assert(!JSON::Validator.validate(schema, {"a" => "42"}, :version => :draft1), 'not validate a simple number') end def test_format_time diff --git a/test/test_jsonschema_draft2.rb b/test/test_jsonschema_draft2.rb index 54accb5e..ed4a0751 100644 --- a/test/test_jsonschema_draft2.rb +++ b/test/test_jsonschema_draft2.rb @@ -685,6 +685,8 @@ def test_format_ipv6 assert(!JSON::Validator.validate(schema,data,:version => :draft2)) data = {"a" => "1111:2222:8888:9999:aaaa:cccc:eeee:ffff:bbbb"} assert(!JSON::Validator.validate(schema,data,:version => :draft2)) + assert(JSON::Validator.validate(schema, {"a" => "::1"}, :version => :draft2), 'validate with shortcut') + assert(!JSON::Validator.validate(schema, {"a" => "42"}, :version => :draft2), 'not validate a simple number') end def test_format_time diff --git a/test/test_jsonschema_draft3.rb b/test/test_jsonschema_draft3.rb index e262f9b3..aec121f2 100644 --- a/test/test_jsonschema_draft3.rb +++ b/test/test_jsonschema_draft3.rb @@ -984,6 +984,8 @@ def test_format_ipv6 assert(!JSON::Validator.validate(schema,data)) data = {"a" => "1111:2222:8888:9999:aaaa:cccc:eeee:ffff:bbbb"} assert(!JSON::Validator.validate(schema,data)) + assert(JSON::Validator.validate(schema, {"a" => "::1"}), 'validate with shortcut') + assert(!JSON::Validator.validate(schema, {"a" => "42"}), 'not validate a simple number') end def test_format_time diff --git a/test/test_jsonschema_draft4.rb b/test/test_jsonschema_draft4.rb index 1b016470..ad1c6ace 100644 --- a/test/test_jsonschema_draft4.rb +++ b/test/test_jsonschema_draft4.rb @@ -927,6 +927,8 @@ def test_format_ipv6 assert(!JSON::Validator.validate(schema,data)) data = {"a" => "1111:2222:8888:9999:aaaa:cccc:eeee:ffff:bbbb"} assert(!JSON::Validator.validate(schema,data)) + assert(JSON::Validator.validate(schema, {"a" => "::1"}), 'validate with shortcut') + assert(!JSON::Validator.validate(schema, {"a" => "42"}), 'not validate a simple number') end From c8d026565c51a1bbb869ceaaede730aecbb1da19 Mon Sep 17 00:00:00 2001 From: Jonas Peschla Date: Sun, 26 Oct 2014 12:46:59 +0100 Subject: [PATCH 2/2] And another 1.9.3 compatibility fix --- lib/json-schema/attributes/formats/ip4.rb | 3 ++- lib/json-schema/attributes/formats/ip6.rb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/json-schema/attributes/formats/ip4.rb b/lib/json-schema/attributes/formats/ip4.rb index 6e59b9c1..846ef9b0 100644 --- a/lib/json-schema/attributes/formats/ip4.rb +++ b/lib/json-schema/attributes/formats/ip4.rb @@ -8,7 +8,8 @@ def self.validate(current_schema, data, fragments, processor, validator, options error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv4 address" begin ip = IPAddr.new data - rescue IPAddr::InvalidAddressError + rescue ArgumentError => e + raise e unless e.message == 'invalid address' end validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) unless ip && ip.ipv4? end diff --git a/lib/json-schema/attributes/formats/ip6.rb b/lib/json-schema/attributes/formats/ip6.rb index 3f595a1d..86e9c74c 100644 --- a/lib/json-schema/attributes/formats/ip6.rb +++ b/lib/json-schema/attributes/formats/ip6.rb @@ -8,7 +8,8 @@ def self.validate(current_schema, data, fragments, processor, validator, options error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv6 address" begin ip = IPAddr.new data - rescue IPAddr::InvalidAddressError + rescue ArgumentError => e + raise e unless e.message == 'invalid address' end validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) unless ip && ip.ipv6? end