jcrvalidator 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/jcr/check_groups.rb +4 -0
- data/lib/jcr/evaluate_array_rules.rb +1 -1
- data/lib/jcr/evaluate_group_rules.rb +1 -1
- data/lib/jcr/evaluate_member_rules.rb +11 -4
- data/lib/jcr/evaluate_object_rules.rb +12 -2
- data/lib/jcr/evaluate_rules.rb +29 -5
- data/lib/jcr/evaluate_value_rules.rb +7 -15
- data/lib/jcr/jcr.rb +8 -1
- data/lib/jcr/parser.rb +32 -20
- data/lib/jcr/process_directives.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0b80dde864c20a32ff286e29e11b5179b3fa935
|
4
|
+
data.tar.gz: 8670787681c6b2aa7639f5c1fad552f5843f2d88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f3da7c4224cfe32ea94f0681a8bbc39b32dd095056ebdf94ae0cc8f55b5332b212fca7b07800b992e3c6357e01876bff05b3b282f45d914194ac4e3a0788708
|
7
|
+
data.tar.gz: 5cd168ff7ea72fd9671d337c4cd0830fd38e4bac75480bb4d65d7e22252186b6edf2e24576f469705483cb1dbcde127c2187c8e4c2a08c609aa5f7865f861647
|
data/lib/jcr/check_groups.rb
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
|
15
15
|
require 'jcr/parser'
|
16
16
|
require 'jcr/map_rule_names'
|
17
|
+
require 'pp'
|
17
18
|
|
18
19
|
module JCR
|
19
20
|
|
@@ -69,6 +70,9 @@ module JCR
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def self.check_member_for_group node, mapping
|
73
|
+
if node.is_a? Array
|
74
|
+
node = node[0]
|
75
|
+
end
|
72
76
|
if node[:target_rule_name]
|
73
77
|
trule = get_name_mapping( node[:target_rule_name][:rule_name], mapping )
|
74
78
|
disallowed_group_in_member?( trule, mapping )
|
@@ -51,7 +51,7 @@ module JCR
|
|
51
51
|
trace( econs, "Evaluating array rule starting at #{slice_to_s(jcr)} against", data )
|
52
52
|
trace_def( econs, "array", jcr, data )
|
53
53
|
retval = evaluate_array( jcr, rule_atom, data, econs, behavior )
|
54
|
-
trace_eval( econs, "Array", retval )
|
54
|
+
trace_eval( econs, "Array", retval, jcr, data, "array" )
|
55
55
|
pop_trace_stack( econs )
|
56
56
|
return retval
|
57
57
|
|
@@ -32,7 +32,7 @@ module JCR
|
|
32
32
|
trace( econs, "Evaluating group rule against ", data )
|
33
33
|
trace_def( econs, "group", jcr, data )
|
34
34
|
retval = evaluate_group( jcr, rule_atom, data, econs, behavior )
|
35
|
-
trace_eval( econs, "Group", retval )
|
35
|
+
trace_eval( econs, "Group", retval, jcr, data, "group" )
|
36
36
|
pop_trace_stack( econs )
|
37
37
|
return retval
|
38
38
|
|
@@ -31,7 +31,7 @@ module JCR
|
|
31
31
|
trace( econs, "Evaluating member rule for key '#{data[0]}' starting at #{slice_to_s(jcr)} against ", data[1])
|
32
32
|
trace_def( econs, "member", jcr, data )
|
33
33
|
retval = evaluate_member( jcr, rule_atom, data, econs )
|
34
|
-
trace_eval( econs, "Member", retval )
|
34
|
+
trace_eval( econs, "Member", retval, jcr, data, "member" )
|
35
35
|
pop_trace_stack( econs )
|
36
36
|
return retval
|
37
37
|
|
@@ -45,7 +45,7 @@ module JCR
|
|
45
45
|
|
46
46
|
|
47
47
|
rules, annotations = get_rules_and_annotations( jcr )
|
48
|
-
rule = rules
|
48
|
+
rule = merge_rules( rules )
|
49
49
|
|
50
50
|
member_match = false
|
51
51
|
|
@@ -55,7 +55,13 @@ module JCR
|
|
55
55
|
member_match = true
|
56
56
|
end
|
57
57
|
else # must be regex
|
58
|
-
|
58
|
+
regex = rule[:member_regex][:regex]
|
59
|
+
if regex.is_a? Array
|
60
|
+
match_spec = Regexp.new( "" )
|
61
|
+
trace( econs, "Noting empty regular expression." )
|
62
|
+
else
|
63
|
+
match_spec = Regexp.new( rule[:member_regex][:regex].to_s )
|
64
|
+
end
|
59
65
|
if match_spec =~ data[ 0 ]
|
60
66
|
member_match = true
|
61
67
|
end
|
@@ -63,6 +69,7 @@ module JCR
|
|
63
69
|
|
64
70
|
if member_match
|
65
71
|
e = evaluate_rule( rule, rule_atom, data[ 1 ], econs )
|
72
|
+
e.member_found = true
|
66
73
|
return evaluate_not( annotations, e, econs )
|
67
74
|
end
|
68
75
|
|
@@ -74,7 +81,7 @@ module JCR
|
|
74
81
|
def self.member_to_s( jcr, shallow=true )
|
75
82
|
rules, annotations = get_rules_and_annotations( jcr )
|
76
83
|
retval = ""
|
77
|
-
rule = rules
|
84
|
+
rule = merge_rules( rules )
|
78
85
|
case
|
79
86
|
when rule[:member_name]
|
80
87
|
retval = %Q|"#{rule[:member_name][:q_string].to_s}"|
|
@@ -33,7 +33,7 @@ module JCR
|
|
33
33
|
trace( econs, "Evaluating object rule starting at #{slice_to_s(jcr)} against", data )
|
34
34
|
trace_def( econs, "object", jcr, data )
|
35
35
|
retval = evaluate_object( jcr, rule_atom, data, econs, behavior )
|
36
|
-
trace_eval( econs, "Object", retval )
|
36
|
+
trace_eval( econs, "Object", retval, jcr, data, "object" )
|
37
37
|
pop_trace_stack( econs )
|
38
38
|
return retval
|
39
39
|
|
@@ -124,22 +124,32 @@ module JCR
|
|
124
124
|
end
|
125
125
|
else
|
126
126
|
trace( econs, "No member '#{k}' found in object.")
|
127
|
+
e = evaluate_rule(rule, rule_atom, [nil, nil], econs, nil)
|
128
|
+
repeat_results[ nil ] = nil if e.success
|
127
129
|
end
|
128
130
|
|
129
131
|
else
|
130
132
|
|
131
|
-
|
133
|
+
regex = lrules[0][:member_regex][:regex]
|
134
|
+
trace( econs, "Scanning object for #{regex}.")
|
132
135
|
i = 0
|
136
|
+
found = false
|
133
137
|
repeat_results = data.select do |k,v|
|
134
138
|
unless behavior.checked_hash[k]
|
135
139
|
if i < repeat_max
|
136
140
|
e = evaluate_rule(rule, rule_atom, [k, v], econs, nil)
|
137
141
|
behavior.checked_hash[k] = e.success
|
138
142
|
i = i + 1 if e.success
|
143
|
+
found = true if e.member_found
|
139
144
|
e.success
|
140
145
|
end
|
141
146
|
end
|
142
147
|
end
|
148
|
+
unless found
|
149
|
+
trace( econs, "No member matching #{regex} found in object.")
|
150
|
+
e = evaluate_rule(rule, rule_atom, [nil, nil], econs, nil)
|
151
|
+
repeat_results[ nil ] = nil if e.success
|
152
|
+
end
|
143
153
|
|
144
154
|
end
|
145
155
|
|
data/lib/jcr/evaluate_rules.rb
CHANGED
@@ -19,6 +19,7 @@ require 'addressable/uri'
|
|
19
19
|
require 'addressable/template'
|
20
20
|
require 'email_address_validator'
|
21
21
|
require 'big-phoney'
|
22
|
+
require 'json'
|
22
23
|
|
23
24
|
require 'jcr/parser'
|
24
25
|
require 'jcr/map_rule_names'
|
@@ -45,7 +46,7 @@ end
|
|
45
46
|
module JCR
|
46
47
|
|
47
48
|
class Evaluation
|
48
|
-
attr_accessor :success, :reason, :
|
49
|
+
attr_accessor :success, :reason, :member_found
|
49
50
|
def initialize success, reason
|
50
51
|
@success = success
|
51
52
|
@reason = reason
|
@@ -53,8 +54,9 @@ module JCR
|
|
53
54
|
end
|
54
55
|
|
55
56
|
class EvalConditions
|
56
|
-
attr_accessor :mapping, :callbacks, :trace, :trace_stack
|
57
|
+
attr_accessor :mapping, :callbacks, :trace, :trace_stack, :first_failure
|
57
58
|
def initialize mapping, callbacks, trace = false
|
59
|
+
@first_failure = nil
|
58
60
|
@mapping = mapping
|
59
61
|
@trace = trace
|
60
62
|
@trace_stack = []
|
@@ -207,6 +209,16 @@ module JCR
|
|
207
209
|
return rules, annotations
|
208
210
|
end
|
209
211
|
|
212
|
+
def self.merge_rules rules
|
213
|
+
new_rule = Hash.new
|
214
|
+
rules.each do |rule|
|
215
|
+
new_rule.merge!(rule) do |key,oldval,newval|
|
216
|
+
raise "error: conflict in merge of #{rule} with #{new_rule}"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
return new_rule
|
220
|
+
end
|
221
|
+
|
210
222
|
def self.evaluate_not annotations, evaluation, econs
|
211
223
|
is_not = false
|
212
224
|
annotations.each do |a|
|
@@ -296,15 +308,27 @@ module JCR
|
|
296
308
|
else
|
297
309
|
s = "** unknown rule **"
|
298
310
|
end
|
299
|
-
trace( econs, "#{type}: #{s}", data)
|
311
|
+
trace( econs, "#{type} definition: #{s}", data)
|
300
312
|
end
|
301
313
|
end
|
302
314
|
|
303
|
-
def self.trace_eval econs, message, evaluation
|
315
|
+
def self.trace_eval econs, message, evaluation, jcr, data, type
|
304
316
|
if evaluation.success
|
305
317
|
trace( econs, "#{message} evaluation is true" )
|
306
318
|
else
|
307
319
|
trace( econs, "#{message} evaluation failed: #{evaluation.reason}")
|
320
|
+
unless econs.first_failure
|
321
|
+
econs.first_failure = evaluation
|
322
|
+
trace( econs, "** LIKELY ROOT CAUSE FOR FAILURE **" )
|
323
|
+
trace( econs, "***********************************" )
|
324
|
+
rule = find_first_slice( jcr )
|
325
|
+
pos = "Failed rule at line,column: #{rule.line_and_column} file position offset: #{rule.offset}"
|
326
|
+
trace( econs, pos )
|
327
|
+
trace_def( econs, type, jcr, data )
|
328
|
+
data_s = "JSON that failed to validate: #{data.to_json}"
|
329
|
+
trace( econs, data_s )
|
330
|
+
trace( econs, "***********************************" )
|
331
|
+
end
|
308
332
|
end
|
309
333
|
end
|
310
334
|
|
@@ -363,7 +387,7 @@ module JCR
|
|
363
387
|
elsif rule[:rule]
|
364
388
|
retval = rule_to_s( rule[:rule], shallow )
|
365
389
|
else
|
366
|
-
retval = "** unknown rule definition **"
|
390
|
+
retval = "** unknown rule definition ** #{rule}"
|
367
391
|
end
|
368
392
|
return retval
|
369
393
|
end
|
@@ -33,7 +33,7 @@ module JCR
|
|
33
33
|
rules, annotations = get_rules_and_annotations( jcr )
|
34
34
|
|
35
35
|
retval = evaluate_not( annotations, evaluate_values( rules[0], rule_atom, data, econs ), econs )
|
36
|
-
trace_eval( econs, "Value", retval)
|
36
|
+
trace_eval( econs, "Value", retval, jcr, data, "value")
|
37
37
|
pop_trace_stack( econs )
|
38
38
|
return retval
|
39
39
|
end
|
@@ -219,25 +219,17 @@ module JCR
|
|
219
219
|
end
|
220
220
|
|
221
221
|
#
|
222
|
-
# uri and uri
|
222
|
+
# uri and uri scheme
|
223
223
|
#
|
224
224
|
|
225
225
|
when jcr[:uri]
|
226
226
|
return bad_value( jcr, rule_atom, "URI", data ) unless data.is_a?( String )
|
227
227
|
uri = Addressable::URI.parse( data )
|
228
228
|
return bad_value( jcr, rule_atom, "URI", data ) unless uri.is_a?( Addressable::URI )
|
229
|
-
when jcr[:
|
230
|
-
t = jcr[:
|
229
|
+
when jcr[:uri_scheme]
|
230
|
+
t = jcr[:uri_scheme].to_s
|
231
231
|
return bad_value( jcr, rule_atom, t, data ) unless data.is_a? String
|
232
|
-
|
233
|
-
e = template.extract( data )
|
234
|
-
if e == nil
|
235
|
-
return bad_value( jcr, rule_atom, t, data )
|
236
|
-
else
|
237
|
-
e.each do |k,v|
|
238
|
-
return bad_value( jcr, rule_atom, t, data ) unless v
|
239
|
-
end
|
240
|
-
end
|
232
|
+
return bad_value( jcr, rule_atom, t, data ) unless data.start_with?( t )
|
241
233
|
|
242
234
|
#
|
243
235
|
# phone and email value rules
|
@@ -476,8 +468,8 @@ module JCR
|
|
476
468
|
|
477
469
|
when rule[:uri]
|
478
470
|
retval = "URI"
|
479
|
-
when rule[:
|
480
|
-
retval = "URI
|
471
|
+
when rule[:uri_scheme]
|
472
|
+
retval = "URI with specific scheme #{rule[:uri_scheme].to_s}"
|
481
473
|
|
482
474
|
when rule[:email]
|
483
475
|
retval = "email"
|
data/lib/jcr/jcr.rb
CHANGED
@@ -207,6 +207,13 @@ module JCR
|
|
207
207
|
opt.on("-h","display help") do |help|
|
208
208
|
options[:help] = true
|
209
209
|
end
|
210
|
+
|
211
|
+
opt.separator ""
|
212
|
+
opt.separator "Return codes:"
|
213
|
+
opt.separator " 0 = success"
|
214
|
+
opt.separator " 1 = parsing or other bad condition"
|
215
|
+
opt.separator " 2 = fall through bad condition"
|
216
|
+
opt.separator " 3 = unsuccessful evaluation of JSON"
|
210
217
|
end
|
211
218
|
|
212
219
|
opt_parser.parse! my_argv
|
@@ -286,7 +293,7 @@ module JCR
|
|
286
293
|
if verbose
|
287
294
|
puts "Failure: #{e.reason}"
|
288
295
|
end
|
289
|
-
ec =
|
296
|
+
ec = 3
|
290
297
|
end
|
291
298
|
return ec
|
292
299
|
end
|
data/lib/jcr/parser.rb
CHANGED
@@ -36,34 +36,46 @@ module JCR
|
|
36
36
|
#/ spaces? -> [ spaces ]
|
37
37
|
rule(:wsp) { match('[\t ]') }
|
38
38
|
# WSP is a standard ABNF production so is not expanded here
|
39
|
-
rule(:
|
40
|
-
#!
|
41
|
-
#!
|
42
|
-
#!
|
43
|
-
|
39
|
+
rule(:dsps) { spcCmnt.repeat(1) | wsp.repeat(1) }
|
40
|
+
#! DSPs = ; Directive spaces
|
41
|
+
#! 1*WSP / ; When in one-line directive
|
42
|
+
#! 1*spcCmnt ; When in muti-line directive
|
43
|
+
rule(:dsps?) { dsps.maybe }
|
44
|
+
#/ DSPs? -> [ DSPs ]
|
45
|
+
rule(:comment) { str(';') >> match('[^\r\n]').repeat >> match('[\r\n]') }
|
46
|
+
#! comment = ";" *comment-char comment-end-char
|
47
|
+
#! comment-char = HTAB / %x20-10FFFF
|
48
|
+
#! ; Any char other than CR / LF
|
49
|
+
#! comment-end-char = CR / LF
|
44
50
|
#!
|
45
51
|
|
46
52
|
rule(:directive) { ( str('#') >> (one_line_directive | multi_line_directive) ).as(:directive) }
|
47
53
|
#! directive = "#" (one_line_directive / multi_line_directive)
|
48
|
-
rule(:one_line_directive) { (
|
49
|
-
#! one_line_directive =
|
54
|
+
rule(:one_line_directive) { ( dsps? >> ( directive_def | one_line_tbd_directive_d ) >> wsp.repeat >> match('[\r\n]') ) }
|
55
|
+
#! one_line_directive = DSPs?
|
50
56
|
#! (directive_def / one_line_tbd_directive_d) *WSP eol
|
51
57
|
rule(:multi_line_directive) { str('{') >> spcCmnt? >> (directive_def | multi_line_tbd_directive_d) >> spcCmnt? >> str('}') }
|
52
58
|
#! multi_line_directive = "{" spcCmnt?
|
53
59
|
#! (directive_def / multi_line_tbd_directive_d) spcCmnt? "}"
|
54
60
|
rule(:directive_def) { jcr_version_d | ruleset_id_d | import_d }
|
55
61
|
#! directive_def = jcr_version_d / ruleset_id_d / import_d
|
56
|
-
rule(:jcr_version_d) { (str('jcr-version') >>
|
57
|
-
|
62
|
+
rule(:jcr_version_d) { ( str('jcr-version') >> dsps >>
|
63
|
+
non_neg_integer.as(:major_version) >> str('.') >> non_neg_integer.as(:minor_version) >>
|
64
|
+
( dsps >> str('+') >> dsps? >> extension_id ).repeat
|
65
|
+
).as(:jcr_version_d) }
|
66
|
+
#! jcr_version_d = jcr-version-kw DSPs major_version "." minor_version
|
67
|
+
#! *( DSPs "+" DSPs? extension_id )
|
58
68
|
#> jcr-version-kw = "jcr-version"
|
59
69
|
#! major_version = non_neg_integer
|
60
70
|
#! minor_version = non_neg_integer
|
61
|
-
rule(:
|
62
|
-
#!
|
71
|
+
rule(:extension_id) { match('[a-zA-Z]') >> match('[\S]').repeat }
|
72
|
+
#! extension_id = ALPHA *not-space
|
73
|
+
rule(:ruleset_id_d) { (str('ruleset-id') >> dsps >> ruleset_id.as(:ruleset_id)).as(:ruleset_id_d) }
|
74
|
+
#! ruleset_id_d = ruleset-id-kw DSPs ruleset_id
|
63
75
|
#> ruleset-id-kw = "ruleset-id"
|
64
|
-
rule(:import_d) { (str('import') >>
|
65
|
-
#! import_d = import-kw
|
66
|
-
#! [
|
76
|
+
rule(:import_d) { (str('import') >> dsps >> ruleset_id.as(:ruleset_id) >> ( dsps >> str('as') >> dsps >> ruleset_id_alias ).maybe).as(:import_d) }
|
77
|
+
#! import_d = import-kw DSPs ruleset_id
|
78
|
+
#! [ DSPs as_kw DSPs ruleset_id_alias ]
|
67
79
|
#> import-kw = "import"
|
68
80
|
#> as-kw = "as"
|
69
81
|
rule(:ruleset_id) { match('[a-zA-Z]') >> match('[\S]').repeat }
|
@@ -77,9 +89,9 @@ module JCR
|
|
77
89
|
#! one_line_directive_parameters = *not_eol
|
78
90
|
#! not_eol = HTAB / %x20-10FFFF
|
79
91
|
#! eol = CR / LF
|
80
|
-
rule(:multi_line_tbd_directive_d) { name.as(:directive_name) >> (
|
92
|
+
rule(:multi_line_tbd_directive_d) { name.as(:directive_name) >> ( spcCmnt.repeat(1) >> multi_line_directive_parameters.as(:directive_parameters) ).maybe }
|
81
93
|
#! multi_line_tbd_directive_d = directive_name
|
82
|
-
#! [
|
94
|
+
#! [ 1*spcCmnt multi_line_directive_parameters ]
|
83
95
|
rule(:multi_line_directive_parameters) { multi_line_parameters }
|
84
96
|
#! multi_line_directive_parameters = multi_line_parameters
|
85
97
|
rule(:multi_line_parameters) { (comment | q_string | regex | match('[^"/;}]')).repeat }
|
@@ -243,8 +255,8 @@ module JCR
|
|
243
255
|
rule(:idn_type) { str('idn').as(:idn) }
|
244
256
|
#! idn_type = idn-kw
|
245
257
|
#> idn-kw = "idn"
|
246
|
-
rule(:uri_range) { str('uri..') >>
|
247
|
-
#! uri_range = uri-dotdot-kw
|
258
|
+
rule(:uri_range) { str('uri..') >> uri_scheme }
|
259
|
+
#! uri_range = uri-dotdot-kw uri_scheme
|
248
260
|
#> uri-dotdot-kw = "uri.."
|
249
261
|
rule(:uri_type) { str('uri').as(:uri) }
|
250
262
|
#! uri_type = uri-kw
|
@@ -414,8 +426,8 @@ module JCR
|
|
414
426
|
#! regex_modifiers = *( "i" / "s" / "x" )
|
415
427
|
#!
|
416
428
|
|
417
|
-
rule(:
|
418
|
-
#!
|
429
|
+
rule(:uri_scheme) { ( match('[a-zA-Z]').repeat(1) ).as(:uri_scheme) }
|
430
|
+
#! uri_scheme = 1*ALPHA
|
419
431
|
|
420
432
|
end
|
421
433
|
|
@@ -52,10 +52,10 @@ module JCR
|
|
52
52
|
major = directive[:major_version].to_str.to_i
|
53
53
|
minor = directive[:minor_version].to_str.to_i
|
54
54
|
if major != 0
|
55
|
-
raise "jcr version #{major}.#{minor} is incompatible with 0.
|
55
|
+
raise "jcr version #{major}.#{minor} is incompatible with 0.7"
|
56
56
|
end
|
57
|
-
if minor !=
|
58
|
-
raise "jcr version #{major}.#{minor} is incompatible with 0.
|
57
|
+
if minor != 7
|
58
|
+
raise "jcr version #{major}.#{minor} is incompatible with 0.7"
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jcrvalidator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Newton
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-07-
|
12
|
+
date: 2016-07-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parslet
|