cddl 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cddl.gemspec +1 -1
- data/data/cddl.abnf +5 -3
- data/lib/cddl.rb +122 -42
- data/test-data/a.cddl +9 -0
- data/test-data/b.cddl +3 -0
- data/test-data/ifmap-base-2.0v17.cddl +392 -0
- data/test/test-cddl.rb +129 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b41bbfc4b845713489d878733a2c1e51277ce80
|
4
|
+
data.tar.gz: 00096ccc572f588b44cd35007ef8795453f57430
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5481738cee35fb77e07500fe839b0f9a7c6473309938e098893f6af32cf3a00d5f720061e733211ac1df4f3dcd945cc0dbe3d855920a288e44cd432de01b723e
|
7
|
+
data.tar.gz: c3d84ab6506b6620996963e76040af1b097c4886b678317f70598a989fdd5d2a9e82d52119fb49e1e987e0abf9af7a2095addbafcf5592f9db287cd6f7dca3eb
|
data/cddl.gemspec
CHANGED
data/data/cddl.abnf
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
cddl = S 1*rule
|
2
2
|
rule = typename [genericparm] S "=" S type S
|
3
|
-
/ groupname [genericparm] S "=" S
|
3
|
+
/ groupname [genericparm] S "=" S grpent S
|
4
4
|
|
5
5
|
typename = id
|
6
6
|
groupname = id
|
@@ -27,11 +27,13 @@ rangeop = "..." / ".."
|
|
27
27
|
|
28
28
|
annotator = "." id
|
29
29
|
|
30
|
-
group =
|
31
|
-
|
30
|
+
group = grpchoice S *("//" S grpchoice S)
|
31
|
+
|
32
|
+
grpchoice = *grpent
|
32
33
|
|
33
34
|
grpent = [occur S] [memberkey S] type optcom
|
34
35
|
/ [occur S] groupname [genericarg] optcom ; always preempted by previous...
|
36
|
+
/ [occur S] "(" S group S ")" optcom
|
35
37
|
|
36
38
|
memberkey = type1 S "=>"
|
37
39
|
/ bareword S ":"
|
data/lib/cddl.rb
CHANGED
@@ -57,6 +57,10 @@ module CDDL
|
|
57
57
|
@abnf.parse_results
|
58
58
|
end
|
59
59
|
|
60
|
+
def ast_debug
|
61
|
+
ast.to_s[/.*comment/m] # stop at first comment -- prelude
|
62
|
+
end
|
63
|
+
|
60
64
|
def strip_nodes(n)
|
61
65
|
[n[0], *n[1..-1].map {|e|
|
62
66
|
e._strip
|
@@ -70,7 +74,7 @@ module CDDL
|
|
70
74
|
ast.each :rule do |rule|
|
71
75
|
rule_ast =
|
72
76
|
if rulename = rule.groupname
|
73
|
-
[:grpent,
|
77
|
+
[:grpent, rule.grpent]
|
74
78
|
elsif rulename = rule.typename
|
75
79
|
[:type1, *rule.type.children(:type1)]
|
76
80
|
else
|
@@ -117,10 +121,9 @@ module CDDL
|
|
117
121
|
|
118
122
|
def lookup_recurse_grpent(name)
|
119
123
|
rule = @stage1[name]
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
}]
|
124
|
+
# pp rule
|
125
|
+
fail unless rule.size == 2
|
126
|
+
[rule[0], *rule[1]]
|
124
127
|
end
|
125
128
|
|
126
129
|
# Memoize a bit here
|
@@ -138,10 +141,17 @@ module CDDL
|
|
138
141
|
case where[0]
|
139
142
|
when :type1
|
140
143
|
generate1(where[rand(where.size-1)+1])
|
144
|
+
when :grpchoice
|
145
|
+
chosen = where[rand(where.size-1)+1]
|
146
|
+
# pp [:chosen, chosen]
|
147
|
+
r = chosen.flat_map {|m| generate1(m, inmap)}
|
148
|
+
# pp r
|
149
|
+
r
|
141
150
|
when :map
|
142
151
|
Hash[where[1..-1].flat_map {|m| generate1(m, true)}]
|
143
152
|
when :recurse_grpent
|
144
|
-
|
153
|
+
name = where[1]
|
154
|
+
rule = lookup_recurse_grpent(name)
|
145
155
|
if @recursion < MAX_RECURSE
|
146
156
|
@recursion += 1
|
147
157
|
#p ["recurse_grpent", *rule]
|
@@ -315,6 +325,11 @@ module CDDL
|
|
315
325
|
n = validate_linear(d, start+i, rule)
|
316
326
|
return false unless n
|
317
327
|
i += n
|
328
|
+
elsif t == :grpchoice
|
329
|
+
return false unless r[1..-1].any? {|cand|
|
330
|
+
if n = validate_forward(d, start+i, [:foo, *cand])
|
331
|
+
i += n
|
332
|
+
end}
|
318
333
|
else
|
319
334
|
fail r.inspect unless t == :member
|
320
335
|
occ = 0
|
@@ -343,6 +358,49 @@ module CDDL
|
|
343
358
|
end
|
344
359
|
end
|
345
360
|
|
361
|
+
def map_check(d, d_check, members)
|
362
|
+
members.all? { |r|
|
363
|
+
# puts "SUBRULE: #{r.inspect}"
|
364
|
+
t, s, _e, k, v = r
|
365
|
+
case t
|
366
|
+
when :recurse_grpent
|
367
|
+
rule = lookup_recurse_grpent(s)
|
368
|
+
map_check(d, d_check, rule[1..-1])
|
369
|
+
when :grpchoice
|
370
|
+
r[1..-1].any? {|cand|
|
371
|
+
cand_d_check = d_check.dup
|
372
|
+
if map_check(d, cand_d_check, cand)
|
373
|
+
d_check.replace(cand_d_check)
|
374
|
+
end
|
375
|
+
}
|
376
|
+
when :member
|
377
|
+
# this is mostly quadratic; let's do the linear thing if possible
|
378
|
+
fail "member name not known for group entry #{r} in map" unless k
|
379
|
+
simple, simpleval = extract_value(k)
|
380
|
+
if simple
|
381
|
+
# puts "SIMPLE: #{d_check.inspect} #{simpleval}"
|
382
|
+
# add occurrence check; check that val is present in the first place
|
383
|
+
actual = d.fetch(simpleval, :not_found)
|
384
|
+
if actual == :not_found
|
385
|
+
s == 0 # minimum occurrence must be 0 then
|
386
|
+
else
|
387
|
+
validate1(actual, v) && d_check.delete(simpleval)
|
388
|
+
end
|
389
|
+
else
|
390
|
+
# puts "COMPLEX: #{k.inspect} #{simple.inspect} #{simpleval.inspect}"
|
391
|
+
keys = d_check.keys
|
392
|
+
ta, keys = keys.partition{ |key| validate1(key, k)}
|
393
|
+
# XXX check ta.size against s/e
|
394
|
+
ta.all? { |val|
|
395
|
+
validate1(d[val], v) && d_check.delete(val)
|
396
|
+
}
|
397
|
+
end
|
398
|
+
else
|
399
|
+
fail "Cannot validate #{t} in maps yet #{r}" # MMM
|
400
|
+
end
|
401
|
+
}
|
402
|
+
end
|
403
|
+
|
346
404
|
def validate1(d, where=rules)
|
347
405
|
# puts "DATA: #{d.inspect}"
|
348
406
|
# puts "RULE: #{where.inspect}"
|
@@ -354,32 +412,7 @@ module CDDL
|
|
354
412
|
when :map
|
355
413
|
if Hash === d
|
356
414
|
d_check = d.dup
|
357
|
-
where[1..-1]
|
358
|
-
# puts "SUBRULE: #{r.inspect}"
|
359
|
-
t, s, _e, k, v = r
|
360
|
-
fail unless t == :member
|
361
|
-
# this is mostly quadratic; let's do the linear thing if possible
|
362
|
-
fail "member name not known for group entry #{r} in map" unless k
|
363
|
-
simple, simpleval = extract_value(k)
|
364
|
-
if simple
|
365
|
-
# puts "SIMPLE: #{d_check.inspect} #{simpleval}"
|
366
|
-
# add occurrence check; check that val is present in the first place
|
367
|
-
actual = d.fetch(simpleval, :not_found)
|
368
|
-
if actual == :not_found
|
369
|
-
s == 0 # minimum occurrence must be 0 then
|
370
|
-
else
|
371
|
-
validate1(actual, v) && d_check.delete(simpleval)
|
372
|
-
end
|
373
|
-
else
|
374
|
-
# puts "COMPLEX: #{k.inspect} #{simple.inspect} #{simpleval.inspect}"
|
375
|
-
keys = d_check.keys
|
376
|
-
ta, keys = keys.partition{ |key| validate1(key, k)}
|
377
|
-
# XXX check ta.size against s/e
|
378
|
-
ta.all? { |val|
|
379
|
-
validate1(d[val], v) && d_check.delete(val)
|
380
|
-
}
|
381
|
-
end
|
382
|
-
} && d_check == {}
|
415
|
+
map_check(d, d_check, where[1..-1]) && d_check == {}
|
383
416
|
end
|
384
417
|
when :array
|
385
418
|
if Array === d
|
@@ -511,7 +544,7 @@ module CDDL
|
|
511
544
|
end
|
512
545
|
end
|
513
546
|
|
514
|
-
RECURSE_TYPE = {grpent: :recurse_grpent, type1: :recurse}
|
547
|
+
RECURSE_TYPE = {grpent: :recurse_grpent, type1: :recurse} # MMM
|
515
548
|
RECURSE_TYPE.default_proc = proc do |a|
|
516
549
|
fail a.inspect
|
517
550
|
end
|
@@ -549,15 +582,33 @@ module CDDL
|
|
549
582
|
end, val]
|
550
583
|
end
|
551
584
|
|
585
|
+
def workaround1(n)
|
586
|
+
n.children.each do |ch|
|
587
|
+
if ch.to_s == ")"
|
588
|
+
# warn "W1 #{ch.inspect} -> #{ch.group.inspect}"
|
589
|
+
return ch.group
|
590
|
+
end
|
591
|
+
end
|
592
|
+
nil
|
593
|
+
end
|
594
|
+
|
552
595
|
def grpent(n) # returns array of entries
|
553
|
-
|
596
|
+
occ = occur(n.occur)
|
597
|
+
if g = n.group || workaround1(n)
|
598
|
+
gr = group(g)
|
599
|
+
if occ != [1, 1]
|
600
|
+
gr = [[:member, *occ, nil, [:grpent, *gr]]]
|
601
|
+
end
|
602
|
+
return gr
|
603
|
+
end
|
604
|
+
nt = n.type || (n.s && n.s.type) || (n.bareword && n.bareword.s.type) # workarounds
|
554
605
|
unless nt
|
606
|
+
warn "NO NT"
|
555
607
|
warn @abnf.ast?
|
556
608
|
fail ["ntype", n, n.children].inspect
|
557
609
|
end
|
558
|
-
occ = occur(n.occur)
|
559
610
|
if mk = n.memberkey # work around unclear bug in ast generation below
|
560
|
-
if (t1 = mk.type1 || t1 = mk.value ||
|
611
|
+
if (t1 = mk.type1 || t1 = mk.value ||
|
561
612
|
((t1 = mk.s) && (t1 = t1.type) && (t1 = t1.type1))) # workaround
|
562
613
|
[[:member, *occ, type1(t1), type(nt)]]
|
563
614
|
else
|
@@ -582,6 +633,9 @@ module CDDL
|
|
582
633
|
t1 = t[1..-1].flatten(1)
|
583
634
|
if t1[0] == :recurse_grpent
|
584
635
|
[t1]
|
636
|
+
elsif Array === t1[0] && t1[0][0] == :grpchoice
|
637
|
+
fail t1.inspect unless t1.size == 1
|
638
|
+
t1
|
585
639
|
else
|
586
640
|
t1.flat_map {|t2|
|
587
641
|
if t2[0] == :member
|
@@ -667,6 +721,22 @@ module CDDL
|
|
667
721
|
end
|
668
722
|
end
|
669
723
|
|
724
|
+
def memberkey_check(s)
|
725
|
+
s.each do |member|
|
726
|
+
case member[0]
|
727
|
+
when :grpchoice
|
728
|
+
member[1..-1].each do |m|
|
729
|
+
memberkey_check(m)
|
730
|
+
end
|
731
|
+
when :recurse_grpent # XXX we don't have the entry yet
|
732
|
+
when :member
|
733
|
+
fail "map entry without member key given: #{member}" unless member[3]
|
734
|
+
else
|
735
|
+
fail ["type1 member", member].inspect unless member[0] == :member
|
736
|
+
end
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
670
740
|
BRACE = {"{" => :map, "[" => :array}
|
671
741
|
RANGE_EXCLUDE_END = {".." => false, "..." => true}
|
672
742
|
SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp]
|
@@ -711,10 +781,7 @@ module CDDL
|
|
711
781
|
s = n.children(:group).flat_map {|ch| group(ch)}
|
712
782
|
@insides.pop
|
713
783
|
if type == :map
|
714
|
-
s
|
715
|
-
fail unless member[0] == :member
|
716
|
-
fail "map entry without member key given: #{member}" unless member[3]
|
717
|
-
end
|
784
|
+
memberkey_check(s)
|
718
785
|
# XXX could do the occurrence multiplier here
|
719
786
|
end
|
720
787
|
# warn s.inspect
|
@@ -729,7 +796,7 @@ module CDDL
|
|
729
796
|
end
|
730
797
|
[:type1, *s.map {|mem|
|
731
798
|
t, _s, _e, _k, v = mem
|
732
|
-
fail unless t == :member
|
799
|
+
fail "enum #{t.inspect}" unless t == :member
|
733
800
|
v
|
734
801
|
}
|
735
802
|
]
|
@@ -750,7 +817,20 @@ module CDDL
|
|
750
817
|
end
|
751
818
|
|
752
819
|
def group(n) # returns array
|
753
|
-
n.children(:
|
820
|
+
choices = n.children(:grpchoice)
|
821
|
+
if choices == [] # "cannot happen", workaround
|
822
|
+
choices = n.s.children(:grpchoice)
|
823
|
+
# warn "W2: #{choices.inspect}"
|
824
|
+
end
|
825
|
+
choices = choices.map {|choice|
|
826
|
+
choice.children(:grpent).flat_map {|ch| grpent(ch)}
|
827
|
+
}
|
828
|
+
case choices.size
|
829
|
+
when 1
|
830
|
+
choices.first
|
831
|
+
else
|
832
|
+
[[:grpchoice, *choices]]
|
833
|
+
end
|
754
834
|
end
|
755
835
|
|
756
836
|
def occur(n)
|
data/test-data/a.cddl
ADDED
data/test-data/b.cddl
ADDED
@@ -0,0 +1,392 @@
|
|
1
|
+
messages = request / response
|
2
|
+
|
3
|
+
request = new-session-request / end-session / renew-session / publish-request / search-request / subscribe-request / poll-request
|
4
|
+
/ purge-publisher-request
|
5
|
+
|
6
|
+
; response = subscribe-received / publish-received / purge-publisher-received / results
|
7
|
+
|
8
|
+
;results = error-result / poll-result / search-result / new-session-result / end-session-result
|
9
|
+
|
10
|
+
message<namespace,name,attributes,content> = [
|
11
|
+
namespace: namespace,
|
12
|
+
name: name,
|
13
|
+
attributes: attributes,
|
14
|
+
content: content
|
15
|
+
]
|
16
|
+
|
17
|
+
error-code = "AccessDenied" / "Failure" / "InvalidIdentifier" / "InvalidIdentifierType" /
|
18
|
+
"IdentifierTooLong" / "InvalidMetadata" / "InvalidSchemaVersion" / "InvalidSessionID" /
|
19
|
+
"MetadataTooLong" / "SearchResultsTooBig" / "PollResultsTooBig" / "SystemError"
|
20
|
+
|
21
|
+
error-result =
|
22
|
+
message<"ifmap", "error-result",
|
23
|
+
[ ],
|
24
|
+
[ ? "name", ? tstr,
|
25
|
+
"error-code", error-code,
|
26
|
+
"error-string", tstr
|
27
|
+
]>
|
28
|
+
|
29
|
+
poll-result = ["", "poll-result", [], [ *(search-result / error-result)]]
|
30
|
+
|
31
|
+
response-choice = error-result / poll-result / search-result / subscribe-received /
|
32
|
+
publish-received / purge-publisher-received / new-session-result /
|
33
|
+
renew-session-result / end-session-result
|
34
|
+
|
35
|
+
response =
|
36
|
+
message<"ifmap", "response",
|
37
|
+
[ ? validation-attributes ],
|
38
|
+
[ response-choice ]>
|
39
|
+
|
40
|
+
purge-publisher-received =
|
41
|
+
["", "purge-publisher-received", [], []]
|
42
|
+
|
43
|
+
purge-publisher-request =
|
44
|
+
message<"ifmap", "purge-publisher",
|
45
|
+
[ "ifmap-publisher-id", tstr,
|
46
|
+
session-attributes
|
47
|
+
],
|
48
|
+
[]>
|
49
|
+
|
50
|
+
; needs to be constructed according to IF-MAP Filter syntax
|
51
|
+
filter-type = tstr
|
52
|
+
|
53
|
+
poll-request =
|
54
|
+
message<"ifmap", "poll",
|
55
|
+
[ session-attributes,
|
56
|
+
validation-attributes
|
57
|
+
],
|
58
|
+
[]>
|
59
|
+
|
60
|
+
subscribe-received =
|
61
|
+
["", "subscribe-received", [], []]
|
62
|
+
|
63
|
+
subscribe-request =
|
64
|
+
message<"ifmap", "subscribe",
|
65
|
+
[ session-attributes,
|
66
|
+
validation-attributes
|
67
|
+
],
|
68
|
+
[ 1*(subscribe-update / subscribe-delete)
|
69
|
+
]>
|
70
|
+
|
71
|
+
subscribe-delete =
|
72
|
+
message<"", "delete",
|
73
|
+
[ "name", tstr,
|
74
|
+
],
|
75
|
+
[]>
|
76
|
+
|
77
|
+
subscribe-update =
|
78
|
+
message<"", "update",
|
79
|
+
[ "match-links", filter-type,
|
80
|
+
"max-depth", uint,
|
81
|
+
"terminal-identifier-type", tstr,
|
82
|
+
"max-size", uint,
|
83
|
+
"result-filter", filter-type,
|
84
|
+
"name", tstr,
|
85
|
+
],
|
86
|
+
[ access-request / identity / ip-address / mac-address / device
|
87
|
+
]>
|
88
|
+
search-request =
|
89
|
+
message<"ifmap", "search",
|
90
|
+
[ session-attributes,
|
91
|
+
validation-attributes,
|
92
|
+
"match-links", filter-type,
|
93
|
+
"max-depth", uint,
|
94
|
+
"terminal-identifier-type", tstr,
|
95
|
+
"max-size", uint,
|
96
|
+
"result-filter", filter-type
|
97
|
+
],
|
98
|
+
[ access-request / identity / ip-address / mac-address / device
|
99
|
+
]>
|
100
|
+
|
101
|
+
search-result =
|
102
|
+
["", "search-result",
|
103
|
+
["name", tstr],
|
104
|
+
[ *result-item]]
|
105
|
+
|
106
|
+
result-item =
|
107
|
+
message<"", "result-item",
|
108
|
+
[],
|
109
|
+
[ 1*2(access-request / identity / ip-address / mac-address / device),
|
110
|
+
"metadata", metadata-list-type
|
111
|
+
]>
|
112
|
+
|
113
|
+
publish-request =
|
114
|
+
message<"ifmap", "publish",
|
115
|
+
[ session-attributes, validation-attributes ],
|
116
|
+
[+ (update-request / notify-request / delete-request) ]>
|
117
|
+
|
118
|
+
update-request = message<"", "update", [ ? lifetime-attributes], [ 1*2 identifier, metadata-list-type ]>
|
119
|
+
notify-request = message<"", "notify", [ ? lifetime-attributes], [ 1*2 identifier ]>
|
120
|
+
delete-request = message<"", "delete", [ "filter", tstr], []>
|
121
|
+
|
122
|
+
publish-received =
|
123
|
+
["", "publish-received", [], []]
|
124
|
+
|
125
|
+
renew-session = message<"ifmap", "renew-session", [ ? session-attributes ], []>
|
126
|
+
renew-session-result = ["", "renew-session-result", [], []]
|
127
|
+
|
128
|
+
end-session = message<"ifmap", "end-session", [], []>
|
129
|
+
end-session-result =
|
130
|
+
["", "end-session-result", [], []]
|
131
|
+
|
132
|
+
new-session-request =
|
133
|
+
message<"ifmap", "new-session",
|
134
|
+
[ "max-poll-result-size", uint],
|
135
|
+
[]>
|
136
|
+
|
137
|
+
new-session-result =
|
138
|
+
["", "new-session-result",
|
139
|
+
[ session-attributes,
|
140
|
+
"ifmap-publisher-id", tstr,
|
141
|
+
"max-poll-result-size", uint,
|
142
|
+
],
|
143
|
+
[]]
|
144
|
+
|
145
|
+
identifier = access-request / device / identity / ip-address / mac-address
|
146
|
+
|
147
|
+
session-attributes = (
|
148
|
+
"session-id", tstr
|
149
|
+
)
|
150
|
+
|
151
|
+
validation-attributes = (
|
152
|
+
"validation", ("None" / "BaseOnly" / "MetadataOnly" / "All")
|
153
|
+
)
|
154
|
+
|
155
|
+
adm-dom = (
|
156
|
+
"administrative-domain", tstr,
|
157
|
+
)
|
158
|
+
|
159
|
+
lifetime-attributes = (
|
160
|
+
"lifetime", ("session" / "forever")
|
161
|
+
)
|
162
|
+
|
163
|
+
access-request =
|
164
|
+
message<"ifmap", "access-request",
|
165
|
+
[ ? adm-dom,
|
166
|
+
"name", tstr
|
167
|
+
],
|
168
|
+
[]>
|
169
|
+
|
170
|
+
device = message<"ifmap", "device", [], [device-type]>
|
171
|
+
device-type =
|
172
|
+
message<"ifmap","aik-name", [], tstr> /
|
173
|
+
message<"ifmap","name", [], tstr>
|
174
|
+
|
175
|
+
identity = message<"ifmap", "identity",
|
176
|
+
[ ? adm-dom,
|
177
|
+
"name", tstr,
|
178
|
+
"type", ("aik-name" / "distinguished-name" / "dns-name" / "email-address" /
|
179
|
+
"hip-hit" / "kerberos-principal" / "trusted-platform-module" /
|
180
|
+
"username" / "other"),
|
181
|
+
"other-type-definition", tstr
|
182
|
+
],
|
183
|
+
[]>
|
184
|
+
|
185
|
+
ip-address = message<"ifmap", "ip-address",
|
186
|
+
[ ? adm-dom,
|
187
|
+
"value", tstr,
|
188
|
+
"type", ("IPv4" / "IPv6")
|
189
|
+
],
|
190
|
+
[]>
|
191
|
+
|
192
|
+
mac-address = message<"ifmap", "mac-address",
|
193
|
+
[ ? adm-dom,
|
194
|
+
"value", tstr,
|
195
|
+
],
|
196
|
+
[]>
|
197
|
+
|
198
|
+
metadata-attributes = (
|
199
|
+
"ifmap-publisher-id", tstr,
|
200
|
+
"ifmap-timestamp", tdate,
|
201
|
+
"ifmap-timestamp-fraction", tstr
|
202
|
+
)
|
203
|
+
|
204
|
+
; optional metadata attributes? not yet possible
|
205
|
+
single-value-metadata-attributes = (
|
206
|
+
? metadata-attributes,
|
207
|
+
"ifmap-cardinality", "singleValue"
|
208
|
+
)
|
209
|
+
|
210
|
+
multi-value-metadata-attributes = (
|
211
|
+
? metadata-attributes,
|
212
|
+
"ifmap-cardinality", "multiValue"
|
213
|
+
)
|
214
|
+
|
215
|
+
access-request-device = message<"meta", "access-request-device",
|
216
|
+
[ single-value-metadata-attributes ], []>
|
217
|
+
|
218
|
+
access-request-ip = message<"meta", "access-request-ip",
|
219
|
+
[ single-value-metadata-attributes ], []>
|
220
|
+
|
221
|
+
access-request-mac = message<"meta", "access-request-mac",
|
222
|
+
[ single-value-metadata-attributes ], []>
|
223
|
+
|
224
|
+
authenticated-as = message<"meta", "authenticated-as",
|
225
|
+
[ single-value-metadata-attributes ], []>
|
226
|
+
|
227
|
+
authenticated-by = message<"meta", "authenticated-by",
|
228
|
+
[ single-value-metadata-attributes ], []>
|
229
|
+
|
230
|
+
capability = message<"meta", "capability",
|
231
|
+
[ multi-value-metadata-attributes ],
|
232
|
+
[ ? adm-dom,
|
233
|
+
"name", tstr
|
234
|
+
]>
|
235
|
+
|
236
|
+
device-attribute = message<"meta", "device-attribute",
|
237
|
+
[ multi-value-metadata-attributes ],
|
238
|
+
[ "name", tstr
|
239
|
+
]>
|
240
|
+
|
241
|
+
manufacturer = message<"", "manufacturer", [], tstr>
|
242
|
+
model = message<"", "model", [], tstr>
|
243
|
+
os = message<"", "os", [], tstr>
|
244
|
+
os-version = message<"", "os-version", [], tstr>
|
245
|
+
type = message<"", "type", [],
|
246
|
+
("p2p" / "cve" / "botnet infection" / "worm infection" / "excessive flows" /
|
247
|
+
"behavioral change" / "policy violation" / "other")>
|
248
|
+
discovered-time = message<"", "discovered-time", [], tdate>
|
249
|
+
discoverer-id = message<"", "discoverer-id", [], tstr>
|
250
|
+
discovery-method = message<"", "discovery-method", [], tstr>
|
251
|
+
name = message<"", "name", [], tstr>
|
252
|
+
magnitude = message<"", "magnitude", [], 0..100>
|
253
|
+
confidence = message<"", "confidence", [], 0..100>
|
254
|
+
significance = message<"", "significance", [], ("critical" / "important" / "informational")>
|
255
|
+
information = message<"", "information", [], tstr>
|
256
|
+
vulnerability-uri = message<"", "vulnerability-uri", [], uri>
|
257
|
+
enforcement-action = message<"", "enforcement-action", [], tstr>
|
258
|
+
other-type-definition = message<"", "other-type-definition", [], tstr>
|
259
|
+
enforcement-reason = message<"", "enforcement-reason", [], tstr>
|
260
|
+
start-time = message<"", "start-time", [], tdate>
|
261
|
+
end-time = message<"", "end-time", [], tdate>
|
262
|
+
dhcp-server = message<"", "dhcp-server", [], tstr>
|
263
|
+
vlan = message<"", "vlan", [], uint>
|
264
|
+
vlan-name = message<"", "vlan-name", [], uint>
|
265
|
+
port = message<"", "port", [], uint>
|
266
|
+
location-information = message<"", "location-information",
|
267
|
+
[ "type", tstr,
|
268
|
+
"value", tstr], []>
|
269
|
+
qualifier = message<"", "qualifier", [], tstr>
|
270
|
+
|
271
|
+
device-characteristic = message<"meta", "device-characteristic",
|
272
|
+
[ multi-value-metadata-attributes ],
|
273
|
+
[ ? manufacturer,
|
274
|
+
? model,
|
275
|
+
? os,
|
276
|
+
? os-version,
|
277
|
+
* type,
|
278
|
+
discovered-time,
|
279
|
+
discoverer-id,
|
280
|
+
+ discovery-method
|
281
|
+
]>
|
282
|
+
|
283
|
+
device-ip = message<"meta", "device-ip",
|
284
|
+
[ single-value-metadata-attributes ], [ device, ip-address]>
|
285
|
+
|
286
|
+
discovered-by = message<"meta", "discovered-by",
|
287
|
+
[ single-value-metadata-attributes ], []>
|
288
|
+
|
289
|
+
enforcement-report = message<"meta", "enforcement-report",
|
290
|
+
[ multi-value-metadata-attributes ],
|
291
|
+
[ enforcement-action,
|
292
|
+
other-type-definition,
|
293
|
+
enforcement-reason
|
294
|
+
]>
|
295
|
+
|
296
|
+
event = message<"meta", "event",
|
297
|
+
[ multi-value-metadata-attributes ],
|
298
|
+
[ name,
|
299
|
+
discovered-time,
|
300
|
+
discoverer-id,
|
301
|
+
magnitude,
|
302
|
+
confidence,
|
303
|
+
significance,
|
304
|
+
? type,
|
305
|
+
? other-type-definition,
|
306
|
+
? information,
|
307
|
+
? vulnerability-uri
|
308
|
+
]>
|
309
|
+
|
310
|
+
ip-mac = message<"meta", "ip-mac",
|
311
|
+
[ multi-value-metadata-attributes ],
|
312
|
+
[ ? start-time,
|
313
|
+
? end-time,
|
314
|
+
? dhcp-server
|
315
|
+
]>
|
316
|
+
|
317
|
+
layer2-information = message<"meta", "layer2-information",
|
318
|
+
[ multi-value-metadata-attributes ],
|
319
|
+
[ ? vlan,
|
320
|
+
? vlan-name,
|
321
|
+
? port,
|
322
|
+
? adm-dom
|
323
|
+
]>
|
324
|
+
|
325
|
+
location = message<"meta", "location",
|
326
|
+
[ multi-value-metadata-attributes ],
|
327
|
+
[ discovered-time,
|
328
|
+
discoverer-id,
|
329
|
+
+ location-information
|
330
|
+
]>
|
331
|
+
|
332
|
+
request-for-investigation = message<"meta", "request-for-investigation",
|
333
|
+
[ multi-value-metadata-attributes ],
|
334
|
+
[ ? qualifier ]>
|
335
|
+
|
336
|
+
role = message<"meta", "role",
|
337
|
+
[ multi-value-metadata-attributes ],
|
338
|
+
[ ? adm-dom,
|
339
|
+
name
|
340
|
+
]>
|
341
|
+
|
342
|
+
unexpected-behavior = message<"meta", "unexpected-behavior",
|
343
|
+
[ multi-value-metadata-attributes ],
|
344
|
+
[ discovered-time,
|
345
|
+
discoverer-id,
|
346
|
+
? information,
|
347
|
+
magnitude,
|
348
|
+
? confidence,
|
349
|
+
significance,
|
350
|
+
? type
|
351
|
+
]>
|
352
|
+
|
353
|
+
wlan-security-type = "open" / "wep" / "tkip" / "ccmp" / "bip" / "other"
|
354
|
+
|
355
|
+
ssid = message<"", "ssid", [], tstr>
|
356
|
+
ssid-unicast-security = message<"", "ssid-unicast-security",
|
357
|
+
[ ? other-type-definition ],
|
358
|
+
[ wlan-security-type ]>
|
359
|
+
ssid-group-security = message<"", "ssid-group-security",
|
360
|
+
[ ? other-type-definition ],
|
361
|
+
[ wlan-security-type ]>
|
362
|
+
ssid-management-security = message<"", "ssid-management-security",
|
363
|
+
[ ? other-type-definition ],
|
364
|
+
[ wlan-security-type ]>
|
365
|
+
|
366
|
+
wlan-information = message<"meta", "wlan-information",
|
367
|
+
[ single-value-metadata-attributes ],
|
368
|
+
[ ? ssid,
|
369
|
+
+ ssid-unicast-security,
|
370
|
+
ssid-group-security,
|
371
|
+
+ ssid-management-security
|
372
|
+
]>
|
373
|
+
|
374
|
+
client-time = message<"opmeta", "client-time",
|
375
|
+
[ single-value-metadata-attributes,
|
376
|
+
"current-time", tdate
|
377
|
+
], []>
|
378
|
+
|
379
|
+
; list every capability explicitly?
|
380
|
+
server-capability = message<"opmeta", "server-capability",
|
381
|
+
[ single-value-metadata-attributes,
|
382
|
+
],
|
383
|
+
[ message<"", "capability", [], tstr>,
|
384
|
+
]>
|
385
|
+
|
386
|
+
metadata-list-type = [
|
387
|
+
*(access-request-device / access-request-ip / access-request-mac /
|
388
|
+
authenticated-as / authenticated-by / capability / device-attribute /
|
389
|
+
device-characteristic / device-ip / discovered-by / enforcement-report /
|
390
|
+
event / ip-mac / layer2-information / location / request-for-investigation /
|
391
|
+
role / unexpected-behavior / wlan-information
|
392
|
+
)]
|
data/test/test-cddl.rb
CHANGED
@@ -410,6 +410,35 @@ HERE
|
|
410
410
|
}
|
411
411
|
end
|
412
412
|
|
413
|
+
def test_another_simple_alternative_group
|
414
|
+
parser = CDDL::Parser.new <<HERE
|
415
|
+
test = {
|
416
|
+
bar: int // bar: true
|
417
|
+
}
|
418
|
+
HERE
|
419
|
+
# pp parser.rules
|
420
|
+
10.times {
|
421
|
+
g = parser.generate
|
422
|
+
# pp ["tasag", g]
|
423
|
+
bar = g['bar']
|
424
|
+
assert bar == true || Integer(bar)
|
425
|
+
assert parser.validate(g)
|
426
|
+
refute parser.validate(g.merge(foo: 3), false)
|
427
|
+
refute parser.validate(g.merge(bar: "baz"), false)
|
428
|
+
}
|
429
|
+
end
|
430
|
+
|
431
|
+
|
432
|
+
def test_bad_simple_alternative_group
|
433
|
+
parser = CDDL::Parser.new <<HERE
|
434
|
+
test = {
|
435
|
+
bar: int // true ; no member key in second choice
|
436
|
+
}
|
437
|
+
HERE
|
438
|
+
assert_raise { parser.rules }
|
439
|
+
end
|
440
|
+
|
441
|
+
|
413
442
|
def test_simple_alternative_in_array
|
414
443
|
parser = CDDL::Parser.new <<HERE
|
415
444
|
test = [
|
@@ -450,6 +479,38 @@ HERE
|
|
450
479
|
end
|
451
480
|
|
452
481
|
|
482
|
+
def test_group_choice_in_array2
|
483
|
+
parser = CDDL::Parser.new <<HERE
|
484
|
+
test = [
|
485
|
+
(1 // 2)
|
486
|
+
bar
|
487
|
+
(foob: 3 // boof: 4)
|
488
|
+
(bar // zab: 9, baz: 10)
|
489
|
+
]
|
490
|
+
bar = (5 // 6)
|
491
|
+
HERE
|
492
|
+
# puts parser.ast_debug
|
493
|
+
pp parser.rules
|
494
|
+
10.times {
|
495
|
+
g = parser.generate
|
496
|
+
pp ["gcia", g]
|
497
|
+
assert_equal g.size, (g[3] == 9 ? 5 : 4)
|
498
|
+
assert [1, 2].include? g[0]
|
499
|
+
assert [5, 6].include? g[1]
|
500
|
+
assert [3, 4].include? g[2]
|
501
|
+
assert [5, 6, 9].include? g[3]
|
502
|
+
assert_equal g[4], 10 if g[3] == 9
|
503
|
+
assert parser.validate(g)
|
504
|
+
}
|
505
|
+
refute parser.validate([1, 5, 8, 9], false)
|
506
|
+
refute parser.validate([1, 5, 3], false)
|
507
|
+
assert parser.validate([1, 5, 4, 5])
|
508
|
+
refute parser.validate([1, 5, 4, 9], false)
|
509
|
+
assert parser.validate([1, 5, 4, 9, 10])
|
510
|
+
refute parser.validate([1, 5, 4, 3], false)
|
511
|
+
refute parser.validate([1, 5, 4, 9, 10, 3], false)
|
512
|
+
end
|
513
|
+
|
453
514
|
def test_validate_number_key
|
454
515
|
parser = CDDL::Parser.new <<HERE
|
455
516
|
test = [test1, test2, test3]
|
@@ -901,7 +962,7 @@ a = [a] / 1
|
|
901
962
|
HERE
|
902
963
|
10.times {
|
903
964
|
g = parser.generate
|
904
|
-
pp ["recurse-test1", g]
|
965
|
+
# pp ["recurse-test1", g]
|
905
966
|
assert parser.validate(g)
|
906
967
|
}
|
907
968
|
end
|
@@ -943,11 +1004,31 @@ HERE
|
|
943
1004
|
p parser.rules
|
944
1005
|
10.times {
|
945
1006
|
g = parser.generate
|
946
|
-
|
1007
|
+
pp ["recurse-group-test", g]
|
947
1008
|
assert parser.validate(g)
|
948
1009
|
}
|
949
1010
|
end
|
950
1011
|
|
1012
|
+
|
1013
|
+
def test_group_recursion2
|
1014
|
+
parser = CDDL::Parser.new <<HERE
|
1015
|
+
b = {1: 2, a}
|
1016
|
+
a = (
|
1017
|
+
foo: int
|
1018
|
+
bar: ([+aa] / 1 / 2)
|
1019
|
+
)
|
1020
|
+
aa = {a}
|
1021
|
+
HERE
|
1022
|
+
p parser.rules
|
1023
|
+
10.times {
|
1024
|
+
g = parser.generate
|
1025
|
+
pp ["recurse-group-test2", g]
|
1026
|
+
assert parser.validate(g)
|
1027
|
+
refute parser.validate(g.merge(baz: 3), false)
|
1028
|
+
}
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
|
951
1032
|
def test_group_recursion_fail1
|
952
1033
|
parser = CDDL::Parser.new <<HERE
|
953
1034
|
b = {a}
|
@@ -964,6 +1045,25 @@ HERE
|
|
964
1045
|
a = {b}
|
965
1046
|
b = ()
|
966
1047
|
HERE
|
1048
|
+
# puts "empty_group AST:"
|
1049
|
+
# puts parser.ast_debug
|
1050
|
+
# puts "empty_group RULES:"
|
1051
|
+
# pp parser.rules
|
1052
|
+
assert_equal({}, parser.generate)
|
1053
|
+
assert parser.validate({})
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
|
1057
|
+
def test_empty_group_sp
|
1058
|
+
parser = CDDL::Parser.new <<HERE
|
1059
|
+
a = {b}
|
1060
|
+
b = (
|
1061
|
+
)
|
1062
|
+
HERE
|
1063
|
+
# puts "empty_group_sp AST:"
|
1064
|
+
# puts parser.ast_debug
|
1065
|
+
# puts "empty_group_sp RULES:"
|
1066
|
+
# pp parser.rules
|
967
1067
|
assert_equal({}, parser.generate)
|
968
1068
|
assert parser.validate({})
|
969
1069
|
end
|
@@ -980,4 +1080,31 @@ HERE
|
|
980
1080
|
# assert parser.validate({})
|
981
1081
|
end
|
982
1082
|
|
1083
|
+
def test_group_occur
|
1084
|
+
parser = CDDL::Parser.new <<HERE
|
1085
|
+
a = [1*3 b]
|
1086
|
+
b = (
|
1087
|
+
1, 2
|
1088
|
+
)
|
1089
|
+
HERE
|
1090
|
+
parser2 = CDDL::Parser.new <<HERE
|
1091
|
+
a = [1*3 (1, 2)]
|
1092
|
+
HERE
|
1093
|
+
# puts "empty_group_sp AST:"
|
1094
|
+
# puts parser.ast_debug
|
1095
|
+
# puts "empty_group_sp RULES:"
|
1096
|
+
pp parser.rules
|
1097
|
+
assert_equal parser.rules, parser2.rules
|
1098
|
+
# assert parser.validate({})
|
1099
|
+
10.times {
|
1100
|
+
g = parser2.generate
|
1101
|
+
# pp ["group-occur", g]
|
1102
|
+
assert [2, 4, 6].include? g.size
|
1103
|
+
g.each_slice(2) do |sl|
|
1104
|
+
assert_equal sl, [1, 2]
|
1105
|
+
end
|
1106
|
+
assert parser2.validate(g)
|
1107
|
+
refute parser2.validate(g << 1, false)
|
1108
|
+
}
|
1109
|
+
end
|
983
1110
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cddl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cbor-diag
|
@@ -100,9 +100,12 @@ files:
|
|
100
100
|
- lib/cddl.rb
|
101
101
|
- test-data/7071-concise.cddl
|
102
102
|
- test-data/7071-verbose.cddl
|
103
|
+
- test-data/a.cddl
|
104
|
+
- test-data/b.cddl
|
103
105
|
- test-data/basic_syntax_example.cddl
|
104
106
|
- test-data/cdni-ct.cddl
|
105
107
|
- test-data/dcaf1.cddl
|
108
|
+
- test-data/ifmap-base-2.0v17.cddl
|
106
109
|
- test-data/jcr-ex.cddl
|
107
110
|
- test-data/minimal.cddl
|
108
111
|
- test-data/reused_named_group.cddl
|