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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f6311c506c4a4e5cbf7e7ae7311301a9d4b6c8d
4
- data.tar.gz: e6fdfe83c6aec225ce434ae492a709fd06d0c890
3
+ metadata.gz: 4b41bbfc4b845713489d878733a2c1e51277ce80
4
+ data.tar.gz: 00096ccc572f588b44cd35007ef8795453f57430
5
5
  SHA512:
6
- metadata.gz: c2926569f00e5e7e509b3e6d05271da2c0d79a79eb46e38e97701218fe339113d08a8057369ff3c4b5f02bdd3f5fbb80ebc34875c6767b619ea327f722bf7ce3
7
- data.tar.gz: 3df458899c4ed7890ef68a40b3c64484599b2805084eb9c8eee15789c94c269452c6352ce34d77dd078e612957c29ded13b650520c179dc6fe886f853e2a60e6
6
+ metadata.gz: 5481738cee35fb77e07500fe839b0f9a7c6473309938e098893f6af32cf3a00d5f720061e733211ac1df4f3dcd945cc0dbe3d855920a288e44cd432de01b723e
7
+ data.tar.gz: c3d84ab6506b6620996963e76040af1b097c4886b678317f70598a989fdd5d2a9e82d52119fb49e1e987e0abf9af7a2095addbafcf5592f9db287cd6f7dca3eb
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'cddl'
3
- s.version = '0.4.2'
3
+ s.version = '0.5.0'
4
4
  s.summary = "CDDL generator and validator."
5
5
  s.description = %{A parser, generator, and validator for CDDL}
6
6
  s.add_dependency('cbor-diag')
@@ -1,6 +1,6 @@
1
1
  cddl = S 1*rule
2
2
  rule = typename [genericparm] S "=" S type S
3
- / groupname [genericparm] S "=" S group 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 = "(" S *grpent S ")"
31
- / *grpent
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 ":"
@@ -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, *rule.group.children(: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
- [rule[0], *rule[1..-1].map {|x|
121
- fail rule.inspect if x.size != 1
122
- x[0]
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
- rule = lookup_recurse_grpent(where[1])
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].all? { |r|
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
- nt = n.type || n.bareword.s.type # check for grpchoice later
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.each do |member|
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(:grpent).flat_map {|ch| grpent(ch)}
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)
@@ -0,0 +1,9 @@
1
+ col = {color}
2
+ color =
3
+ ( black: 0,
4
+ red: 1,
5
+ green: 2,)
6
+ //
7
+ ( foo: 4,
8
+ bar: 5,
9
+ baz: 6,)
@@ -0,0 +1,3 @@
1
+ x = (a, b)
2
+ a = ()
3
+ b = //
@@ -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
+ )]
@@ -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
- # pp ["recurse-group-test", g]
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.2
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-04-17 00:00:00.000000000 Z
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