jcrvalidator 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|