json-schema 2.8.0 → 5.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +82 -11
- data/lib/json-schema/attribute.rb +13 -14
- data/lib/json-schema/attributes/additionalitems.rb +1 -0
- data/lib/json-schema/attributes/additionalproperties.rb +3 -6
- data/lib/json-schema/attributes/allof.rb +6 -4
- data/lib/json-schema/attributes/anyof.rb +2 -2
- data/lib/json-schema/attributes/const.rb +15 -0
- data/lib/json-schema/attributes/dependencies.rb +1 -6
- data/lib/json-schema/attributes/dependencies_v4.rb +11 -0
- data/lib/json-schema/attributes/disallow.rb +2 -1
- data/lib/json-schema/attributes/divisibleby.rb +1 -1
- data/lib/json-schema/attributes/enum.rb +2 -2
- data/lib/json-schema/attributes/extends.rb +7 -7
- data/lib/json-schema/attributes/format.rb +2 -1
- data/lib/json-schema/attributes/formats/custom.rb +1 -1
- data/lib/json-schema/attributes/formats/date.rb +2 -1
- data/lib/json-schema/attributes/formats/date_time.rb +3 -2
- data/lib/json-schema/attributes/formats/date_time_v4.rb +2 -1
- data/lib/json-schema/attributes/formats/ip.rb +1 -1
- data/lib/json-schema/attributes/formats/time.rb +1 -1
- data/lib/json-schema/attributes/formats/uri.rb +2 -1
- data/lib/json-schema/attributes/items.rb +1 -0
- data/lib/json-schema/attributes/limit.rb +0 -127
- data/lib/json-schema/attributes/limits/items.rb +15 -0
- data/lib/json-schema/attributes/limits/length.rb +15 -0
- data/lib/json-schema/attributes/limits/max_items.rb +15 -0
- data/lib/json-schema/attributes/limits/max_length.rb +15 -0
- data/lib/json-schema/attributes/limits/max_properties.rb +15 -0
- data/lib/json-schema/attributes/limits/maximum.rb +15 -0
- data/lib/json-schema/attributes/limits/maximum_inclusive.rb +11 -0
- data/lib/json-schema/attributes/limits/min_items.rb +15 -0
- data/lib/json-schema/attributes/limits/min_length.rb +15 -0
- data/lib/json-schema/attributes/limits/min_properties.rb +15 -0
- data/lib/json-schema/attributes/limits/minimum.rb +15 -0
- data/lib/json-schema/attributes/limits/minimum_inclusive.rb +11 -0
- data/lib/json-schema/attributes/limits/numeric.rb +16 -0
- data/lib/json-schema/attributes/limits/properties.rb +15 -0
- data/lib/json-schema/attributes/maxdecimal.rb +1 -1
- data/lib/json-schema/attributes/not.rb +2 -2
- data/lib/json-schema/attributes/oneof.rb +2 -4
- data/lib/json-schema/attributes/patternproperties.rb +2 -1
- data/lib/json-schema/attributes/properties.rb +9 -17
- data/lib/json-schema/attributes/properties_v4.rb +13 -0
- data/lib/json-schema/attributes/propertynames.rb +23 -0
- data/lib/json-schema/attributes/ref.rb +8 -8
- data/lib/json-schema/attributes/required.rb +4 -3
- data/lib/json-schema/attributes/type.rb +3 -2
- data/lib/json-schema/attributes/type_v4.rb +1 -1
- data/lib/json-schema/errors/validation_error.rb +5 -6
- data/lib/json-schema/schema/reader.rb +3 -1
- data/lib/json-schema/schema/validator.rb +3 -3
- data/lib/json-schema/schema.rb +3 -4
- data/lib/json-schema/util/array_set.rb +1 -1
- data/lib/json-schema/util/uri.rb +98 -75
- data/lib/json-schema/util/uuid.rb +203 -226
- data/lib/json-schema/validator.rb +122 -115
- data/lib/json-schema/validators/draft1.rb +21 -23
- data/lib/json-schema/validators/draft2.rb +22 -24
- data/lib/json-schema/validators/draft3.rb +26 -28
- data/lib/json-schema/validators/draft4.rb +34 -36
- data/lib/json-schema/validators/draft6.rb +36 -36
- data/lib/json-schema/validators/hyper-draft1.rb +2 -3
- data/lib/json-schema/validators/hyper-draft2.rb +2 -3
- data/lib/json-schema/validators/hyper-draft3.rb +2 -3
- data/lib/json-schema/validators/hyper-draft4.rb +2 -3
- data/lib/json-schema/validators/hyper-draft6.rb +2 -3
- data/lib/json-schema.rb +2 -3
- data/resources/draft-06.json +41 -41
- metadata +67 -31
@@ -4,6 +4,8 @@ require 'bigdecimal'
|
|
4
4
|
require 'digest/sha1'
|
5
5
|
require 'date'
|
6
6
|
require 'thread'
|
7
|
+
require 'timeout'
|
8
|
+
require 'stringio'
|
7
9
|
require 'yaml'
|
8
10
|
|
9
11
|
require 'json-schema/schema/reader'
|
@@ -14,21 +16,22 @@ require 'json-schema/errors/json_parse_error'
|
|
14
16
|
require 'json-schema/util/uri'
|
15
17
|
|
16
18
|
module JSON
|
17
|
-
|
18
19
|
class Validator
|
19
|
-
|
20
20
|
@@schemas = {}
|
21
21
|
@@cache_schemas = true
|
22
22
|
@@default_opts = {
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
23
|
+
list: false,
|
24
|
+
version: nil,
|
25
|
+
validate_schema: false,
|
26
|
+
record_errors: false,
|
27
|
+
errors_as_objects: false,
|
28
|
+
insert_defaults: false,
|
29
|
+
clear_cache: false,
|
30
|
+
strict: false,
|
31
|
+
allPropertiesRequired: false,
|
32
|
+
noAdditionalProperties: false,
|
33
|
+
parse_data: true,
|
34
|
+
parse_integer: true,
|
32
35
|
}
|
33
36
|
@@validators = {}
|
34
37
|
@@default_validator = nil
|
@@ -37,32 +40,32 @@ module JSON
|
|
37
40
|
@@serializer = nil
|
38
41
|
@@mutex = Mutex.new
|
39
42
|
|
40
|
-
def initialize(schema_data,
|
43
|
+
def initialize(schema_data, opts = {})
|
41
44
|
@options = @@default_opts.clone.merge(opts)
|
42
45
|
@errors = []
|
43
46
|
|
44
|
-
|
45
|
-
@options[:version] = validator
|
47
|
+
configured_validator = self.class.validator_for_name(@options[:version])
|
46
48
|
@options[:schema_reader] ||= self.class.schema_reader
|
47
49
|
|
48
|
-
@validation_options = @options[:record_errors] ? {:
|
50
|
+
@validation_options = @options[:record_errors] ? { record_errors: true } : {}
|
49
51
|
@validation_options[:insert_defaults] = true if @options[:insert_defaults]
|
50
|
-
|
52
|
+
if @options[:strict] == true
|
53
|
+
@validation_options[:allPropertiesRequired] = true
|
54
|
+
@validation_options[:noAdditionalProperties] = true
|
55
|
+
else
|
56
|
+
@validation_options[:allPropertiesRequired] = true if @options[:allPropertiesRequired]
|
57
|
+
@validation_options[:noAdditionalProperties] = true if @options[:noAdditionalProperties]
|
58
|
+
end
|
51
59
|
@validation_options[:clear_cache] = true if !@@cache_schemas || @options[:clear_cache]
|
52
60
|
|
53
|
-
@@mutex.synchronize { @base_schema = initialize_schema(schema_data) }
|
54
|
-
@original_data = data
|
55
|
-
@data = initialize_data(data)
|
61
|
+
@@mutex.synchronize { @base_schema = initialize_schema(schema_data, configured_validator) }
|
56
62
|
@@mutex.synchronize { build_schemas(@base_schema) }
|
57
63
|
|
58
64
|
# validate the schema, if requested
|
59
65
|
if @options[:validate_schema]
|
60
|
-
if @base_schema.schema["$schema"]
|
61
|
-
base_validator = self.class.validator_for_name(@base_schema.schema["$schema"])
|
62
|
-
end
|
63
|
-
metaschema = base_validator ? base_validator.metaschema : validator.metaschema
|
64
66
|
# Don't clear the cache during metaschema validation!
|
65
|
-
self.class.
|
67
|
+
meta_validator = self.class.new(@base_schema.validator.metaschema, { clear_cache: false })
|
68
|
+
meta_validator.validate(@base_schema.schema)
|
66
69
|
end
|
67
70
|
|
68
71
|
# If the :fragment option is set, try and validate against the fragment
|
@@ -73,60 +76,61 @@ module JSON
|
|
73
76
|
|
74
77
|
def schema_from_fragment(base_schema, fragment)
|
75
78
|
schema_uri = base_schema.uri
|
76
|
-
fragments = fragment.split(
|
79
|
+
fragments = fragment.split('/').map { |f| f.gsub('~0', '~').gsub('~1', '/') }
|
77
80
|
|
78
81
|
# ensure the first element was a hash, per the fragment spec
|
79
|
-
if fragments.shift !=
|
80
|
-
raise JSON::Schema::SchemaError
|
82
|
+
if fragments.shift != '#'
|
83
|
+
raise JSON::Schema::SchemaError, 'Invalid fragment syntax in :fragment option'
|
81
84
|
end
|
82
85
|
|
86
|
+
schema_fragment = base_schema.schema
|
83
87
|
fragments.each do |f|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
elsif base_schema.is_a?(Hash)
|
90
|
-
if !base_schema.has_key?(f)
|
91
|
-
raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
|
92
|
-
end
|
93
|
-
base_schema = JSON::Schema.new(base_schema[f],schema_uri,@options[:version])
|
94
|
-
elsif base_schema.is_a?(Array)
|
95
|
-
if base_schema[f.to_i].nil?
|
96
|
-
raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
|
97
|
-
end
|
98
|
-
base_schema = JSON::Schema.new(base_schema[f.to_i],schema_uri,@options[:version])
|
99
|
-
else
|
100
|
-
raise JSON::Schema::SchemaError.new("Invalid schema encountered when resolving :fragment option")
|
88
|
+
case schema_fragment
|
89
|
+
when Hash
|
90
|
+
schema_fragment = schema_fragment[f]
|
91
|
+
when Array
|
92
|
+
schema_fragment = schema_fragment[f.to_i]
|
101
93
|
end
|
102
94
|
end
|
103
95
|
|
96
|
+
unless schema_fragment.is_a?(Hash)
|
97
|
+
raise JSON::Schema::SchemaError, 'Invalid fragment resolution for :fragment option'
|
98
|
+
end
|
99
|
+
|
100
|
+
schema = JSON::Schema.new(schema_fragment, schema_uri, base_schema.validator)
|
101
|
+
|
104
102
|
if @options[:list]
|
105
|
-
|
103
|
+
schema.to_array_schema
|
104
|
+
elsif schema.is_a?(Hash)
|
105
|
+
JSON::Schema.new(schema, schema_uri, @options[:version])
|
106
106
|
else
|
107
|
-
|
107
|
+
schema
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
111
|
# Run a simple true/false validation of data against a schema
|
112
|
-
def validate
|
113
|
-
|
112
|
+
def validate(data)
|
113
|
+
original_data = data
|
114
|
+
data = initialize_data(data)
|
115
|
+
@base_schema.validate(data, [], self, @validation_options)
|
114
116
|
|
115
117
|
if @options[:record_errors]
|
116
118
|
if @options[:errors_as_objects]
|
117
|
-
@errors.map{|e| e.to_hash}
|
119
|
+
@errors.map { |e| e.to_hash }
|
118
120
|
else
|
119
|
-
@errors.map{|e| e.to_string}
|
121
|
+
@errors.map { |e| e.to_string }
|
120
122
|
end
|
121
123
|
else
|
122
124
|
true
|
123
125
|
end
|
124
126
|
ensure
|
127
|
+
@errors = []
|
128
|
+
|
125
129
|
if @validation_options[:clear_cache] == true
|
126
130
|
self.class.clear_cache
|
127
131
|
end
|
128
132
|
if @validation_options[:insert_defaults]
|
129
|
-
self.class.merge_missing_values(
|
133
|
+
self.class.merge_missing_values(data, original_data)
|
130
134
|
end
|
131
135
|
end
|
132
136
|
|
@@ -147,13 +151,13 @@ module JSON
|
|
147
151
|
schema = parent_schema.schema
|
148
152
|
|
149
153
|
# Build ref schemas if they exist
|
150
|
-
if schema[
|
151
|
-
load_ref_schema(parent_schema, schema[
|
154
|
+
if schema['$ref']
|
155
|
+
load_ref_schema(parent_schema, schema['$ref'])
|
152
156
|
end
|
153
157
|
|
154
|
-
case schema[
|
158
|
+
case schema['extends']
|
155
159
|
when String
|
156
|
-
load_ref_schema(parent_schema, schema[
|
160
|
+
load_ref_schema(parent_schema, schema['extends'])
|
157
161
|
when Array
|
158
162
|
schema['extends'].each do |type|
|
159
163
|
handle_schema(parent_schema, type)
|
@@ -161,7 +165,7 @@ module JSON
|
|
161
165
|
end
|
162
166
|
|
163
167
|
# Check for schemas in union types
|
164
|
-
[
|
168
|
+
%w[type disallow].each do |key|
|
165
169
|
if schema[key].is_a?(Array)
|
166
170
|
schema[key].each do |type|
|
167
171
|
if type.is_a?(Hash)
|
@@ -175,7 +179,8 @@ module JSON
|
|
175
179
|
# are themselves schemas.
|
176
180
|
%w[definitions properties patternProperties].each do |key|
|
177
181
|
next unless value = schema[key]
|
178
|
-
|
182
|
+
|
183
|
+
value.each do |_k, inner_schema|
|
179
184
|
handle_schema(parent_schema, inner_schema)
|
180
185
|
end
|
181
186
|
end
|
@@ -183,20 +188,22 @@ module JSON
|
|
183
188
|
# Schema properties whose values are themselves schemas.
|
184
189
|
%w[additionalProperties additionalItems dependencies extends].each do |key|
|
185
190
|
next unless schema[key].is_a?(Hash)
|
191
|
+
|
186
192
|
handle_schema(parent_schema, schema[key])
|
187
193
|
end
|
188
194
|
|
189
195
|
# Schema properties whose values may be an array of schemas.
|
190
196
|
%w[allOf anyOf oneOf not].each do |key|
|
191
197
|
next unless value = schema[key]
|
198
|
+
|
192
199
|
Array(value).each do |inner_schema|
|
193
200
|
handle_schema(parent_schema, inner_schema)
|
194
201
|
end
|
195
202
|
end
|
196
203
|
|
197
204
|
# Items are always schemas
|
198
|
-
if schema[
|
199
|
-
items = schema[
|
205
|
+
if schema['items']
|
206
|
+
items = schema['items'].clone
|
200
207
|
items = [items] unless items.is_a?(Array)
|
201
208
|
|
202
209
|
items.each do |item|
|
@@ -205,10 +212,9 @@ module JSON
|
|
205
212
|
end
|
206
213
|
|
207
214
|
# Convert enum to a ArraySet
|
208
|
-
if schema[
|
209
|
-
schema[
|
215
|
+
if schema['enum'].is_a?(Array)
|
216
|
+
schema['enum'] = ArraySet.new(schema['enum'])
|
210
217
|
end
|
211
|
-
|
212
218
|
end
|
213
219
|
|
214
220
|
# Either load a reference schema or create a new schema
|
@@ -231,58 +237,57 @@ module JSON
|
|
231
237
|
@errors
|
232
238
|
end
|
233
239
|
|
234
|
-
|
235
240
|
class << self
|
236
|
-
def validate(schema, data,opts={})
|
241
|
+
def validate(schema, data, opts = {})
|
237
242
|
begin
|
238
243
|
validate!(schema, data, opts)
|
239
244
|
rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError
|
240
|
-
|
245
|
+
false
|
241
246
|
end
|
242
247
|
end
|
243
248
|
|
244
|
-
def validate_json(schema, data, opts={})
|
245
|
-
validate(schema, data, opts.merge(:
|
249
|
+
def validate_json(schema, data, opts = {})
|
250
|
+
validate(schema, data, opts.merge(json: true))
|
246
251
|
end
|
247
252
|
|
248
|
-
def validate_uri(schema, data, opts={})
|
249
|
-
validate(schema, data, opts.merge(:
|
253
|
+
def validate_uri(schema, data, opts = {})
|
254
|
+
validate(schema, data, opts.merge(uri: true))
|
250
255
|
end
|
251
256
|
|
252
|
-
def validate!(schema, data,opts={})
|
253
|
-
validator = new(schema,
|
254
|
-
validator.validate
|
257
|
+
def validate!(schema, data, opts = {})
|
258
|
+
validator = new(schema, opts)
|
259
|
+
validator.validate(data)
|
255
260
|
end
|
256
261
|
|
257
|
-
def validate2(schema, data, opts={})
|
258
|
-
warn
|
262
|
+
def validate2(schema, data, opts = {})
|
263
|
+
warn '[DEPRECATION NOTICE] JSON::Validator#validate2 has been replaced by JSON::Validator#validate! and will be removed in version >= 3. Please use the #validate! method instead.'
|
259
264
|
validate!(schema, data, opts)
|
260
265
|
end
|
261
266
|
|
262
|
-
def validate_json!(schema, data, opts={})
|
263
|
-
validate!(schema, data, opts.merge(:
|
267
|
+
def validate_json!(schema, data, opts = {})
|
268
|
+
validate!(schema, data, opts.merge(json: true))
|
264
269
|
end
|
265
270
|
|
266
|
-
def validate_uri!(schema, data, opts={})
|
267
|
-
validate!(schema, data, opts.merge(:
|
271
|
+
def validate_uri!(schema, data, opts = {})
|
272
|
+
validate!(schema, data, opts.merge(uri: true))
|
268
273
|
end
|
269
274
|
|
270
|
-
def fully_validate(schema, data, opts={})
|
271
|
-
validate!(schema, data, opts.merge(:
|
275
|
+
def fully_validate(schema, data, opts = {})
|
276
|
+
validate!(schema, data, opts.merge(record_errors: true))
|
272
277
|
end
|
273
278
|
|
274
|
-
def fully_validate_schema(schema, opts={})
|
279
|
+
def fully_validate_schema(schema, opts = {})
|
275
280
|
data = schema
|
276
281
|
schema = validator_for_name(opts[:version]).metaschema
|
277
282
|
fully_validate(schema, data, opts)
|
278
283
|
end
|
279
284
|
|
280
|
-
def fully_validate_json(schema, data, opts={})
|
281
|
-
fully_validate(schema, data, opts.merge(:
|
285
|
+
def fully_validate_json(schema, data, opts = {})
|
286
|
+
fully_validate(schema, data, opts.merge(json: true))
|
282
287
|
end
|
283
288
|
|
284
|
-
def fully_validate_uri(schema, data, opts={})
|
285
|
-
fully_validate(schema, data, opts.merge(:
|
289
|
+
def fully_validate_uri(schema, data, opts = {})
|
290
|
+
fully_validate(schema, data, opts.merge(uri: true))
|
286
291
|
end
|
287
292
|
|
288
293
|
def schema_reader
|
@@ -295,7 +300,6 @@ module JSON
|
|
295
300
|
|
296
301
|
def clear_cache
|
297
302
|
@@schemas = {}
|
298
|
-
JSON::Util::URI.clear_cache
|
299
303
|
end
|
300
304
|
|
301
305
|
def schemas
|
@@ -322,7 +326,7 @@ module JSON
|
|
322
326
|
end
|
323
327
|
|
324
328
|
def cache_schemas=(val)
|
325
|
-
warn
|
329
|
+
warn '[DEPRECATION NOTICE] Schema caching is now a validation option. Schemas will still be cached if this is set to true, but this method will be removed in version >= 3. Please use the :clear_cache validation option instead.'
|
326
330
|
@@cache_schemas = val == true ? true : false
|
327
331
|
end
|
328
332
|
|
@@ -334,32 +338,34 @@ module JSON
|
|
334
338
|
@@default_validator
|
335
339
|
end
|
336
340
|
|
337
|
-
def validator_for_uri(schema_uri, raise_not_found=true)
|
341
|
+
def validator_for_uri(schema_uri, raise_not_found = true)
|
338
342
|
return default_validator unless schema_uri
|
343
|
+
|
339
344
|
u = JSON::Util::URI.parse(schema_uri)
|
340
345
|
validator = validators["#{u.scheme}://#{u.host}#{u.path}"]
|
341
346
|
if validator.nil? && raise_not_found
|
342
|
-
raise JSON::Schema::SchemaError
|
347
|
+
raise JSON::Schema::SchemaError, "Schema not found: #{schema_uri}"
|
343
348
|
else
|
344
349
|
validator
|
345
350
|
end
|
346
351
|
end
|
347
352
|
|
348
|
-
def validator_for_name(schema_name, raise_not_found=true)
|
353
|
+
def validator_for_name(schema_name, raise_not_found = true)
|
349
354
|
return default_validator unless schema_name
|
355
|
+
|
350
356
|
schema_name = schema_name.to_s
|
351
357
|
validator = validators.values.detect do |v|
|
352
358
|
Array(v.names).include?(schema_name)
|
353
359
|
end
|
354
360
|
if validator.nil? && raise_not_found
|
355
|
-
raise JSON::Schema::SchemaError
|
361
|
+
raise JSON::Schema::SchemaError, 'The requested JSON schema version is not supported'
|
356
362
|
else
|
357
363
|
validator
|
358
364
|
end
|
359
365
|
end
|
360
366
|
|
361
367
|
def validator_for(schema_uri)
|
362
|
-
warn
|
368
|
+
warn '[DEPRECATION NOTICE] JSON::Validator#validator_for has been replaced by JSON::Validator#validator_for_uri and will be removed in version >= 3. Please use the #validator_for_uri method instead.'
|
363
369
|
validator_for_uri(schema_uri)
|
364
370
|
end
|
365
371
|
|
@@ -371,7 +377,7 @@ module JSON
|
|
371
377
|
@@default_validator = v
|
372
378
|
end
|
373
379
|
|
374
|
-
def register_format_validator(format, validation_proc, versions = (@@validators.flat_map{ |
|
380
|
+
def register_format_validator(format, validation_proc, versions = (@@validators.flat_map { |_k, v| v.names.first } + [nil]))
|
375
381
|
custom_format_validator = JSON::Schema::CustomFormat.new(validation_proc)
|
376
382
|
versions.each do |version|
|
377
383
|
validator = validator_for_name(version)
|
@@ -379,14 +385,14 @@ module JSON
|
|
379
385
|
end
|
380
386
|
end
|
381
387
|
|
382
|
-
def deregister_format_validator(format, versions = (@@validators.flat_map{ |
|
388
|
+
def deregister_format_validator(format, versions = (@@validators.flat_map { |_k, v| v.names.first } + [nil]))
|
383
389
|
versions.each do |version|
|
384
390
|
validator = validator_for_name(version)
|
385
391
|
validator.formats[format.to_s] = validator.default_formats[format.to_s]
|
386
392
|
end
|
387
393
|
end
|
388
394
|
|
389
|
-
def restore_default_formats(versions = (@@validators.flat_map{ |
|
395
|
+
def restore_default_formats(versions = (@@validators.flat_map { |_k, v| v.names.first } + [nil]))
|
390
396
|
versions.each do |version|
|
391
397
|
validator = validator_for_name(version)
|
392
398
|
validator.formats = validator.default_formats.clone
|
@@ -410,7 +416,7 @@ module JSON
|
|
410
416
|
if @@available_json_backends.include?(backend)
|
411
417
|
@@json_backend = backend
|
412
418
|
else
|
413
|
-
raise JSON::Schema::JsonParseError
|
419
|
+
raise JSON::Schema::JsonParseError, "The JSON backend '#{backend}' could not be found."
|
414
420
|
end
|
415
421
|
end
|
416
422
|
end
|
@@ -420,26 +426,26 @@ module JSON
|
|
420
426
|
begin
|
421
427
|
MultiJson.respond_to?(:adapter) ? MultiJson.load(s) : MultiJson.decode(s)
|
422
428
|
rescue MultiJson::ParseError => e
|
423
|
-
raise JSON::Schema::JsonParseError
|
429
|
+
raise JSON::Schema::JsonParseError, e.message
|
424
430
|
end
|
425
431
|
else
|
426
432
|
case @@json_backend.to_s
|
427
433
|
when 'json'
|
428
434
|
begin
|
429
|
-
JSON.parse(s, :
|
435
|
+
JSON.parse(s, quirks_mode: true)
|
430
436
|
rescue JSON::ParserError => e
|
431
|
-
raise JSON::Schema::JsonParseError
|
437
|
+
raise JSON::Schema::JsonParseError, e.message
|
432
438
|
end
|
433
439
|
when 'yajl'
|
434
440
|
begin
|
435
441
|
json = StringIO.new(s)
|
436
442
|
parser = Yajl::Parser.new
|
437
|
-
parser.parse(json) or raise
|
443
|
+
parser.parse(json) or raise(JSON::Schema::JsonParseError, 'The JSON could not be parsed by yajl')
|
438
444
|
rescue Yajl::ParseError => e
|
439
|
-
raise JSON::Schema::JsonParseError
|
445
|
+
raise JSON::Schema::JsonParseError, e.message
|
440
446
|
end
|
441
447
|
else
|
442
|
-
raise JSON::Schema::JsonParseError
|
448
|
+
raise JSON::Schema::JsonParseError, "No supported JSON parsers found. The following parsers are suported:\n * yajl-ruby\n * json"
|
443
449
|
end
|
444
450
|
end
|
445
451
|
end
|
@@ -478,7 +484,6 @@ module JSON
|
|
478
484
|
end
|
479
485
|
end
|
480
486
|
|
481
|
-
|
482
487
|
if Gem::Specification::find_all_by_name('yajl-ruby').any?
|
483
488
|
require 'yajl'
|
484
489
|
@@available_json_backends << 'yajl'
|
@@ -486,11 +491,11 @@ module JSON
|
|
486
491
|
end
|
487
492
|
|
488
493
|
if @@json_backend == 'yajl'
|
489
|
-
@@serializer = lambda{|o| Yajl::Encoder.encode(o) }
|
494
|
+
@@serializer = lambda { |o| Yajl::Encoder.encode(o) }
|
490
495
|
elsif @@json_backend == 'json'
|
491
|
-
@@serializer = lambda{|o| JSON.dump(o) }
|
496
|
+
@@serializer = lambda { |o| JSON.dump(o) }
|
492
497
|
else
|
493
|
-
@@serializer = lambda{|o| YAML.dump(o) }
|
498
|
+
@@serializer = lambda { |o| YAML.dump(o) }
|
494
499
|
end
|
495
500
|
end
|
496
501
|
end
|
@@ -499,10 +504,10 @@ module JSON
|
|
499
504
|
|
500
505
|
if Gem::Specification::find_all_by_name('uuidtools').any?
|
501
506
|
require 'uuidtools'
|
502
|
-
@@fake_uuid_generator = lambda{|s| UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, s).to_s }
|
507
|
+
@@fake_uuid_generator = lambda { |s| UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, s).to_s }
|
503
508
|
else
|
504
509
|
require 'json-schema/util/uuid'
|
505
|
-
@@fake_uuid_generator = lambda{|s| JSON::Util::UUID.create_v5(s,JSON::Util::UUID::Nil).to_s }
|
510
|
+
@@fake_uuid_generator = lambda { |s| JSON::Util::UUID.create_v5(s, JSON::Util::UUID::Nil).to_s }
|
506
511
|
end
|
507
512
|
|
508
513
|
def serialize schema
|
@@ -517,12 +522,12 @@ module JSON
|
|
517
522
|
@@fake_uuid_generator.call(schema)
|
518
523
|
end
|
519
524
|
|
520
|
-
def initialize_schema(schema)
|
525
|
+
def initialize_schema(schema, default_validator)
|
521
526
|
if schema.is_a?(String)
|
522
527
|
begin
|
523
528
|
# Build a fake URI for this
|
524
529
|
schema_uri = JSON::Util::URI.parse(fake_uuid(schema))
|
525
|
-
schema = JSON::Schema.new(
|
530
|
+
schema = JSON::Schema.new(JSON::Validator.parse(schema), schema_uri, default_validator)
|
526
531
|
if @options[:list] && @options[:fragment].nil?
|
527
532
|
schema = schema.to_array_schema
|
528
533
|
end
|
@@ -552,13 +557,13 @@ module JSON
|
|
552
557
|
elsif schema.is_a?(Hash)
|
553
558
|
schema_uri = JSON::Util::URI.parse(fake_uuid(serialize(schema)))
|
554
559
|
schema = JSON::Schema.stringify(schema)
|
555
|
-
schema = JSON::Schema.new(schema, schema_uri,
|
560
|
+
schema = JSON::Schema.new(schema, schema_uri, default_validator)
|
556
561
|
if @options[:list] && @options[:fragment].nil?
|
557
562
|
schema = schema.to_array_schema
|
558
563
|
end
|
559
564
|
self.class.add_schema(schema)
|
560
565
|
else
|
561
|
-
raise JSON::Schema::SchemaParseError,
|
566
|
+
raise JSON::Schema::SchemaParseError, 'Invalid schema - must be either a string or a hash'
|
562
567
|
end
|
563
568
|
|
564
569
|
schema
|
@@ -573,12 +578,14 @@ module JSON
|
|
573
578
|
data = self.class.parse(custom_open(json_uri))
|
574
579
|
elsif data.is_a?(String)
|
575
580
|
begin
|
576
|
-
|
581
|
+
# Check if the string is valid integer
|
582
|
+
strict_convert = data.match?(/\A[+-]?\d+\z/) && !@options[:parse_integer]
|
583
|
+
data = strict_convert ? data : self.class.parse(data)
|
577
584
|
rescue JSON::Schema::JsonParseError
|
578
585
|
begin
|
579
586
|
json_uri = Util::URI.normalized_uri(data)
|
580
587
|
data = self.class.parse(custom_open(json_uri))
|
581
|
-
rescue JSON::Schema::JsonLoadError
|
588
|
+
rescue JSON::Schema::JsonLoadError, JSON::Schema::UriError
|
582
589
|
# Silently discard the error - use the data as-is
|
583
590
|
end
|
584
591
|
end
|
@@ -591,7 +598,7 @@ module JSON
|
|
591
598
|
uri = Util::URI.normalized_uri(uri) if uri.is_a?(String)
|
592
599
|
if uri.absolute? && Util::URI::SUPPORTED_PROTOCOLS.include?(uri.scheme)
|
593
600
|
begin
|
594
|
-
open(uri.to_s).read
|
601
|
+
URI.open(uri.to_s).read
|
595
602
|
rescue OpenURI::HTTPError, Timeout::Error => e
|
596
603
|
raise JSON::Schema::JsonLoadError, e.message
|
597
604
|
end
|
@@ -2,27 +2,26 @@ require 'json-schema/schema/validator'
|
|
2
2
|
|
3
3
|
module JSON
|
4
4
|
class Schema
|
5
|
-
|
6
5
|
class Draft1 < Validator
|
7
6
|
def initialize
|
8
7
|
super
|
9
8
|
@attributes = {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
9
|
+
'type' => JSON::Schema::TypeAttribute,
|
10
|
+
'disallow' => JSON::Schema::DisallowAttribute,
|
11
|
+
'format' => JSON::Schema::FormatAttribute,
|
12
|
+
'maximum' => JSON::Schema::MaximumInclusiveAttribute,
|
13
|
+
'minimum' => JSON::Schema::MinimumInclusiveAttribute,
|
14
|
+
'minItems' => JSON::Schema::MinItemsAttribute,
|
15
|
+
'maxItems' => JSON::Schema::MaxItemsAttribute,
|
16
|
+
'minLength' => JSON::Schema::MinLengthAttribute,
|
17
|
+
'maxLength' => JSON::Schema::MaxLengthAttribute,
|
18
|
+
'maxDecimal' => JSON::Schema::MaxDecimalAttribute,
|
19
|
+
'enum' => JSON::Schema::EnumAttribute,
|
20
|
+
'properties' => JSON::Schema::PropertiesOptionalAttribute,
|
21
|
+
'pattern' => JSON::Schema::PatternAttribute,
|
22
|
+
'additionalProperties' => JSON::Schema::AdditionalPropertiesAttribute,
|
23
|
+
'items' => JSON::Schema::ItemsAttribute,
|
24
|
+
'extends' => JSON::Schema::ExtendsAttribute,
|
26
25
|
}
|
27
26
|
@default_formats = {
|
28
27
|
'date-time' => DateTimeFormat,
|
@@ -30,16 +29,15 @@ module JSON
|
|
30
29
|
'time' => TimeFormat,
|
31
30
|
'ip-address' => IP4Format,
|
32
31
|
'ipv6' => IP6Format,
|
33
|
-
'uri' => UriFormat
|
32
|
+
'uri' => UriFormat,
|
34
33
|
}
|
35
34
|
@formats = @default_formats.clone
|
36
|
-
@uri = JSON::Util::URI.parse(
|
37
|
-
@names = [
|
38
|
-
@metaschema_name =
|
35
|
+
@uri = JSON::Util::URI.parse('http://json-schema.org/draft-01/schema#')
|
36
|
+
@names = ['draft1']
|
37
|
+
@metaschema_name = 'draft-01.json'
|
39
38
|
end
|
40
39
|
|
41
|
-
JSON::Validator.register_validator(
|
40
|
+
JSON::Validator.register_validator(new)
|
42
41
|
end
|
43
|
-
|
44
42
|
end
|
45
43
|
end
|