cddl 0.8.1 → 0.8.12
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 +5 -5
- data/bin/cddl +7 -3
- data/cddl.gemspec +2 -1
- data/data/cddl.abnf +8 -2
- data/lib/cddl.rb +101 -28
- data/test/test-cddl.rb +101 -2
- data/test-data/7807.cddl +14 -0
- data/test-data/abignum.cddl +1 -0
- data/test-data/ambig.cddl +2 -0
- data/test-data/badaddr.cddl +1 -0
- data/test-data/bpv7.cddl +136 -0
- data/test-data/bpv7a.cddl +181 -0
- data/test-data/bpv7b.cddl +167 -0
- data/test-data/coral.cddl +10 -0
- data/test-data/coral1.cddl +5 -0
- data/test-data/coral2.cddl +7 -0
- data/test-data/coral3.cddl +7 -0
- data/test-data/dotsize.cddl +7 -0
- data/test-data/feat1.cddl +4 -0
- data/test-data/foo.cddl +1 -0
- data/test-data/grasp-09.cddl +108 -0
- data/test-data/jim-cut-2.cddl +11 -0
- data/test-data/jim-cut.cddl +12 -0
- data/test-data/jsoniodef.cddl +719 -0
- data/test-data/kevin5.cddl +5 -0
- data/test-data/map-group.cddl +13 -0
- data/test-data/mapkey.cddl +2 -0
- data/test-data/mdl-ble.cddl +9 -0
- data/test-data/mdl-deve.cddl +54 -0
- data/test-data/mdl-dp.cddl +11 -0
- data/test-data/mdl-mso.cddl +20 -0
- data/test-data/mdl-request.cddl +26 -0
- data/test-data/mdl-response.cddl +66 -0
- data/test-data/mdl.cddl +11 -0
- data/test-data/mon-val.cddl +1 -0
- data/test-data/multipart-ct.cddl +2 -0
- data/test-data/named-group.cddl +7 -0
- data/test-data/test-gen.cddl +3 -0
- data/test-data/toerless0.cddl +14 -0
- data/test-data/toerless1.cddl +11 -0
- metadata +40 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 2ede21b4292e6f546745029c7a071eb1af1259366e676d90e19f400dfe089d7a
|
|
4
|
+
data.tar.gz: 57ed90f75d58941bd28c5afef7d5eb29eea5d5483a6a3b2c4fc65d49df0370aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65de704e842bb6d48265e7024922edf0406d6cb521d2977b07db2926d396b8b2d6bdc103619d579b861cb53b8914b4383e25c2e610e86f7b4d88d89983a64dff
|
|
7
|
+
data.tar.gz: c0919845b3ee5bba3b2a5d77f9e182a4a9f1904f187843501abf29954d37033d62f1cfd50545865ba878c92583f26151f9024dc1093c0d4607442038b36008b0
|
data/bin/cddl
CHANGED
|
@@ -7,13 +7,16 @@ require 'json'
|
|
|
7
7
|
|
|
8
8
|
Encoding.default_external = "UTF-8" # wake up, smell the coffee
|
|
9
9
|
|
|
10
|
+
EX_USAGE = 64
|
|
11
|
+
EX_DATAERR = 65
|
|
12
|
+
|
|
10
13
|
def usage
|
|
11
14
|
warn "Usage:"
|
|
12
15
|
warn "#$0 spec.cddl generate [n]"
|
|
13
16
|
warn "#$0 spec.cddl json-generate [n]"
|
|
14
17
|
warn "#$0 spec.cddl validate instance.cbor"
|
|
15
18
|
warn "#$0 spec.cddl validate instance.json"
|
|
16
|
-
exit
|
|
19
|
+
exit EX_USAGE
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def read_arg(arg)
|
|
@@ -21,7 +24,7 @@ def read_arg(arg)
|
|
|
21
24
|
STDIN.read
|
|
22
25
|
else
|
|
23
26
|
usage unless arg
|
|
24
|
-
File.read(arg)
|
|
27
|
+
File.read(arg, mode: "rb")
|
|
25
28
|
end
|
|
26
29
|
end
|
|
27
30
|
|
|
@@ -86,10 +89,11 @@ begin
|
|
|
86
89
|
# my_pp ann
|
|
87
90
|
instance.cbor_add_annotations_from(ann) rescue nil
|
|
88
91
|
my_diag(instance) if $annotate
|
|
92
|
+
exit 1 unless ann
|
|
89
93
|
else
|
|
90
94
|
usage
|
|
91
95
|
end
|
|
92
96
|
rescue CDDL::ParseError => e
|
|
93
97
|
warn e.message
|
|
94
|
-
exit
|
|
98
|
+
exit EX_DATAERR
|
|
95
99
|
end
|
data/cddl.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'cddl'
|
|
3
|
-
s.version = '0.8.
|
|
3
|
+
s.version = '0.8.12'
|
|
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')
|
|
@@ -19,3 +19,4 @@ spec = Gem::Specification.new do |s|
|
|
|
19
19
|
s.homepage = "http://github.com/cabo/cddl"
|
|
20
20
|
s.license = 'MIT'
|
|
21
21
|
end
|
|
22
|
+
|
data/data/cddl.abnf
CHANGED
|
@@ -16,6 +16,7 @@ type1 = type2 [S (rangeop / annotator) S type2]
|
|
|
16
16
|
/ "#" "6" ["." uint] "(" S type S ")" ; note no space!
|
|
17
17
|
/ "#" DIGIT ["." uint] ; major/ai
|
|
18
18
|
/ "#" ; any
|
|
19
|
+
/ "~" S typename [genericarg]
|
|
19
20
|
/ "{" S group S "}"
|
|
20
21
|
/ "[" S group S "]"
|
|
21
22
|
/ "&" S "(" S group S ")"
|
|
@@ -49,8 +50,10 @@ occur = [uint] "*" [uint]
|
|
|
49
50
|
/ "+"
|
|
50
51
|
/ "?"
|
|
51
52
|
|
|
52
|
-
uint =
|
|
53
|
-
/
|
|
53
|
+
uint = DIGIT1 *DIGIT
|
|
54
|
+
/ "0x" 1*HEXDIG
|
|
55
|
+
/ "0b" 1*BINDIG
|
|
56
|
+
/ "0"
|
|
54
57
|
|
|
55
58
|
value = number
|
|
56
59
|
/ text
|
|
@@ -77,6 +80,9 @@ ALPHA = %x41-5A / %x61-7A
|
|
|
77
80
|
EALPHA = %x41-5A / %x61-7A / "@" / "_" / "$"
|
|
78
81
|
DIGIT = %x30-39
|
|
79
82
|
DIGIT1 = %x31-39
|
|
83
|
+
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
|
|
84
|
+
BINDIG = %x30-31
|
|
85
|
+
|
|
80
86
|
S = *WS
|
|
81
87
|
WS = SP / NL
|
|
82
88
|
SP = %x20
|
data/lib/cddl.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'pathname'
|
|
|
4
4
|
require 'cbor-pure' unless defined?(CBOR::Tagged)
|
|
5
5
|
require 'regexp-examples'
|
|
6
6
|
require 'colorize'
|
|
7
|
+
require 'base64'
|
|
7
8
|
|
|
8
9
|
module CDDL
|
|
9
10
|
|
|
@@ -14,7 +15,7 @@ module CDDL
|
|
|
14
15
|
|
|
15
16
|
MANY = Float::INFINITY
|
|
16
17
|
|
|
17
|
-
MAX_RECURSE =
|
|
18
|
+
MAX_RECURSE = 128 # XXX
|
|
18
19
|
|
|
19
20
|
class ParseError < ArgumentError; end
|
|
20
21
|
|
|
@@ -319,7 +320,8 @@ module CDDL
|
|
|
319
320
|
end
|
|
320
321
|
when :member
|
|
321
322
|
st = where[1]
|
|
322
|
-
|
|
323
|
+
fudge = 4 * (1 - (@recursion / MAX_RECURSE.to_f))**3 # get less generate-happy with more recursion
|
|
324
|
+
en = [where[2], [st, fudge].max].min # truncate to fudge unless must be more
|
|
323
325
|
st += rand(en + 1 - st) if en != st
|
|
324
326
|
kr = where[3]
|
|
325
327
|
vr = where[4]
|
|
@@ -327,8 +329,12 @@ module CDDL
|
|
|
327
329
|
unless kr
|
|
328
330
|
case vr[0]
|
|
329
331
|
when :grpent
|
|
330
|
-
fail "grpent in map #{vr.inspect}" unless vr.size == 2
|
|
331
|
-
g = Array.new(st) {
|
|
332
|
+
# fail "grpent in map #{vr.inspect}" unless vr.size == 2
|
|
333
|
+
g = Array.new(st) {
|
|
334
|
+
vr[1..-1].map{ |vrx|
|
|
335
|
+
generate1(vrx, true)
|
|
336
|
+
}.flatten(1)
|
|
337
|
+
}.flatten(1)
|
|
332
338
|
# warn "GGG #{g.inspect}"
|
|
333
339
|
return g
|
|
334
340
|
when :grpchoice
|
|
@@ -348,7 +354,7 @@ module CDDL
|
|
|
348
354
|
fail BackTrack.new("Need #{where[1]}..#{where[2]} of these: #{[kr, vr].inspect}") unless where[1] == 0
|
|
349
355
|
[]
|
|
350
356
|
end
|
|
351
|
-
when :text, :int, :float
|
|
357
|
+
when :text, :int, :float, :bytes
|
|
352
358
|
where[1]
|
|
353
359
|
when :range
|
|
354
360
|
rand(where[1])
|
|
@@ -390,15 +396,19 @@ module CDDL
|
|
|
390
396
|
case where[1]
|
|
391
397
|
when :size
|
|
392
398
|
should_be_int = generate1(control)
|
|
393
|
-
unless (target
|
|
399
|
+
unless (Array === target && target[0] == :prim && [0, 2, 3].include?(target[1])) && Integer === should_be_int && should_be_int >= 0
|
|
394
400
|
fail "Don't know yet how to generate #{where}"
|
|
395
401
|
end
|
|
396
402
|
s = Random.new.bytes(should_be_int)
|
|
397
|
-
|
|
403
|
+
case target[1]
|
|
404
|
+
when 0
|
|
398
405
|
# silently restrict to what we can put into a uint
|
|
399
406
|
s[0...8].bytes.inject(0) {|a, b| a << 8 | b }
|
|
400
|
-
|
|
407
|
+
when 2
|
|
401
408
|
s
|
|
409
|
+
when 3
|
|
410
|
+
Base64.urlsafe_encode64(s)[0...should_be_int]
|
|
411
|
+
# XXX generate word a la w = gen_word
|
|
402
412
|
end
|
|
403
413
|
when :bits
|
|
404
414
|
set_of_bits = Array.new(10) { generate1(control) } # XXX: ten?
|
|
@@ -429,6 +439,8 @@ module CDDL
|
|
|
429
439
|
$default_warned = true
|
|
430
440
|
end
|
|
431
441
|
generate1(target, inmap)
|
|
442
|
+
when :feature
|
|
443
|
+
generate1(target, inmap)
|
|
432
444
|
when :eq
|
|
433
445
|
content = generate1(control)
|
|
434
446
|
if validate1(content, where)
|
|
@@ -517,7 +529,7 @@ module CDDL
|
|
|
517
529
|
end
|
|
518
530
|
end
|
|
519
531
|
|
|
520
|
-
VALUE_TYPE = {text: String, int: Integer, float: Float}
|
|
532
|
+
VALUE_TYPE = {text: String, bytes: String, int: Integer, float: Float}
|
|
521
533
|
SIMPLE_VALUE = {
|
|
522
534
|
[:prim, 7, 20] => [true, false, :bool],
|
|
523
535
|
[:prim, 7, 21] => [true, true, :bool],
|
|
@@ -525,7 +537,7 @@ module CDDL
|
|
|
525
537
|
[:prim, 7, 23] => [true, :undefined, :undefined],
|
|
526
538
|
}
|
|
527
539
|
|
|
528
|
-
def extract_value(t)
|
|
540
|
+
def extract_value(t) # []
|
|
529
541
|
if vt = VALUE_TYPE[t[0]]
|
|
530
542
|
[true, t[1], vt]
|
|
531
543
|
elsif v = SIMPLE_VALUE[t]
|
|
@@ -541,11 +553,17 @@ module CDDL
|
|
|
541
553
|
|
|
542
554
|
def validate(d, warn=true)
|
|
543
555
|
@recursion = 0
|
|
556
|
+
$features = Hash.new {|h, k| h[k] = {}}
|
|
544
557
|
result = validate1a(d, rules)
|
|
545
|
-
|
|
546
|
-
if
|
|
558
|
+
if warn
|
|
559
|
+
if result
|
|
560
|
+
if $features != {}
|
|
561
|
+
warn "** Features potentially used: #{$features.map {|k, v| "#{k}: #{v.keys}"}.join(", ")}"
|
|
562
|
+
end
|
|
563
|
+
else
|
|
547
564
|
warn "CDDL validation failure (#{result.inspect} for #{d.inspect}):"
|
|
548
565
|
PP::pp(validate_diag, STDERR)
|
|
566
|
+
puts(validate_diag.cbor_diagnostic)
|
|
549
567
|
end
|
|
550
568
|
end
|
|
551
569
|
result
|
|
@@ -660,7 +678,7 @@ module CDDL
|
|
|
660
678
|
# this is mostly quadratic; let's do the linear thing if possible
|
|
661
679
|
simple, simpleval = extract_value(k)
|
|
662
680
|
if simple
|
|
663
|
-
|
|
681
|
+
puts "SIMPLE: #{d_check.inspect} #{simpleval}" if ENV["CDDL_TRACE"]
|
|
664
682
|
# add occurrence check; check that val is present in the first place
|
|
665
683
|
actual = d.fetch(simpleval, :not_found)
|
|
666
684
|
if actual == :not_found
|
|
@@ -672,7 +690,7 @@ module CDDL
|
|
|
672
690
|
end
|
|
673
691
|
end
|
|
674
692
|
else
|
|
675
|
-
|
|
693
|
+
puts "COMPLEX: #{k.inspect} #{simple.inspect} #{simpleval.inspect}" if ENV["CDDL_TRACE"]
|
|
676
694
|
keys = d_check.keys
|
|
677
695
|
ta, keys = keys.partition{ |key| validate1(key, k)}
|
|
678
696
|
# XXX check ta.size against s/e
|
|
@@ -735,9 +753,12 @@ module CDDL
|
|
|
735
753
|
idx, ann = validate_forward(d, 0, where)
|
|
736
754
|
ann if validate_result(idx == d.size) { "#{validate_diag.inspect} -- cannot complete (#{idx}, #{d.size}) array #{d} for #{where}" }
|
|
737
755
|
end
|
|
738
|
-
when :
|
|
756
|
+
when :int, :float
|
|
739
757
|
_, v = extract_value(where)
|
|
740
758
|
[] if d == v
|
|
759
|
+
when :text, :bytes
|
|
760
|
+
_, v = extract_value(where)
|
|
761
|
+
[] if d == v && ((d.encoding == Encoding::BINARY) == (v.encoding == Encoding::BINARY))
|
|
741
762
|
when :range
|
|
742
763
|
[] if where[2] === d && where[1].include?(d)
|
|
743
764
|
when :anno
|
|
@@ -783,6 +804,10 @@ module CDDL
|
|
|
783
804
|
$default_warned = true
|
|
784
805
|
end
|
|
785
806
|
ann
|
|
807
|
+
when :feature
|
|
808
|
+
ok, v, vt = extract_value(control)
|
|
809
|
+
$features[v][d] = true
|
|
810
|
+
ann
|
|
786
811
|
when :lt, :le, :gt, :ge, :eq, :ne
|
|
787
812
|
op = OPERATORS[where[1]]
|
|
788
813
|
ok, v, _vt = extract_value(control)
|
|
@@ -831,6 +856,14 @@ module CDDL
|
|
|
831
856
|
when 3
|
|
832
857
|
String === d && d.encoding != Encoding::BINARY # cheat
|
|
833
858
|
when 6
|
|
859
|
+
if Integer === d
|
|
860
|
+
t = 2 # assuming only 2/3 match an Integer
|
|
861
|
+
if d < 0
|
|
862
|
+
d = ~d
|
|
863
|
+
t = 3
|
|
864
|
+
end
|
|
865
|
+
d = CBOR::Tagged.new(t, d == 0 ? "".b : d.digits(256).reverse!.pack("C*"))
|
|
866
|
+
end
|
|
834
867
|
CBOR::Tagged === d && d.tag == where[2] && validate1a(d.data, where[3])
|
|
835
868
|
when 7
|
|
836
869
|
t, v = extract_value(where)
|
|
@@ -942,14 +975,34 @@ module CDDL
|
|
|
942
975
|
def value(n)
|
|
943
976
|
# cheat:
|
|
944
977
|
# warn n
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
978
|
+
s = n.to_s
|
|
979
|
+
if s[-1] == "'"
|
|
980
|
+
parts = s.split("'", 3)
|
|
981
|
+
if parts[2] != "" || parts[1] =~ /\\/
|
|
982
|
+
warn "*** Can't handle backslashes in #{s.inspect} yet"
|
|
983
|
+
end
|
|
984
|
+
[:bytes,
|
|
985
|
+
case parts[0]
|
|
986
|
+
when ""
|
|
987
|
+
parts[1].b
|
|
988
|
+
when "h"
|
|
989
|
+
parts[1].gsub(/\s/, "").chars.each_slice(2).map{ |x| Integer(x.join, 16).chr("BINARY") }.join.b
|
|
990
|
+
when "b64"
|
|
991
|
+
Base64.urlsafe_decode64(parts[1])
|
|
992
|
+
else
|
|
993
|
+
warn "*** Can't handle byte string type #{parts[0].inspect} yet"
|
|
994
|
+
end
|
|
995
|
+
]
|
|
996
|
+
else
|
|
997
|
+
val = eval(n.to_s)
|
|
998
|
+
# warn val
|
|
999
|
+
case val
|
|
1000
|
+
when Integer; [:int, val]
|
|
1001
|
+
when Numeric; [:float, val]
|
|
1002
|
+
when String; [:text, val.force_encoding(Encoding::UTF_8)]
|
|
1003
|
+
else fail "huh? value #{val.inspect}"
|
|
1004
|
+
end
|
|
1005
|
+
end
|
|
953
1006
|
end
|
|
954
1007
|
|
|
955
1008
|
def workaround1(n)
|
|
@@ -988,7 +1041,7 @@ module CDDL
|
|
|
988
1041
|
fail [n, n.children, mk, mk.children].inspect
|
|
989
1042
|
end
|
|
990
1043
|
name = bw.to_s
|
|
991
|
-
[[:member, *occ, [:text, name], type(nt)]]
|
|
1044
|
+
[[:member, *occ, [:text, name.force_encoding(Encoding::UTF_8)], type(nt)]]
|
|
992
1045
|
end
|
|
993
1046
|
else
|
|
994
1047
|
t = if nbw = nt.bareword
|
|
@@ -1000,8 +1053,8 @@ module CDDL
|
|
|
1000
1053
|
else
|
|
1001
1054
|
type(nt, true) # type can actually be a group here!
|
|
1002
1055
|
end
|
|
1003
|
-
|
|
1004
|
-
if t[0] == :grpent && (
|
|
1056
|
+
pp ["t is", t] if ENV["CDDL_TRACE"]
|
|
1057
|
+
if t[0] == :grpent && (occ == [1, 1])
|
|
1005
1058
|
# go through the members here and multiply the occs
|
|
1006
1059
|
t1 = t[1..-1].flatten(1)
|
|
1007
1060
|
if t1[0] == :recurse_grpent
|
|
@@ -1116,7 +1169,7 @@ module CDDL
|
|
|
1116
1169
|
end
|
|
1117
1170
|
when :recurse_grpent # XXX we don't have the entry yet
|
|
1118
1171
|
when :member
|
|
1119
|
-
fail "map entry without member key given: #{member}" unless member[3] || member[4][0] == :grpent || member[4][0] == :grpchoice
|
|
1172
|
+
fail "map entry #{member.inspect} without member key given: #{member}" unless member[3] || member[4][0] == :grpent || member[4][0] == :grpchoice
|
|
1120
1173
|
else
|
|
1121
1174
|
fail ["type1 member", member].inspect unless member[0] == :member
|
|
1122
1175
|
end
|
|
@@ -1126,7 +1179,7 @@ module CDDL
|
|
|
1126
1179
|
BRACE = {"{" => :map, "[" => :array}
|
|
1127
1180
|
RANGE_EXCLUDE_END = {".." => false, "..." => true}
|
|
1128
1181
|
SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp, :cbor, :cborseq, :within, :and,
|
|
1129
|
-
:default, :lt, :le, :gt, :ge, :eq, :ne]
|
|
1182
|
+
:default, :lt, :le, :gt, :ge, :eq, :ne, :feature]
|
|
1130
1183
|
|
|
1131
1184
|
def type1(n, canbegroup = false)
|
|
1132
1185
|
# puts "NVALUE #{n.value.inspect}"
|
|
@@ -1188,6 +1241,26 @@ module CDDL
|
|
|
1188
1241
|
v
|
|
1189
1242
|
}
|
|
1190
1243
|
]
|
|
1244
|
+
when /\A~/
|
|
1245
|
+
if tn = n.typename
|
|
1246
|
+
s = type_recall(tn.to_s, false, n.genericarg).flatten(1)
|
|
1247
|
+
else
|
|
1248
|
+
fail "No typename in unwrap #{n}"
|
|
1249
|
+
end
|
|
1250
|
+
if s[0] != :type1
|
|
1251
|
+
fail [:UNWRAPs0, s].inspect
|
|
1252
|
+
end
|
|
1253
|
+
case s[1]
|
|
1254
|
+
when :map, :array
|
|
1255
|
+
[:grpent, s[2..-1]]
|
|
1256
|
+
when :prim
|
|
1257
|
+
if s[2] != 6
|
|
1258
|
+
fail [:UNWRAPs2, s].inspect
|
|
1259
|
+
end
|
|
1260
|
+
s[4] # check :type1?
|
|
1261
|
+
else
|
|
1262
|
+
fail [:UNWRAPs1, s].inspect
|
|
1263
|
+
end
|
|
1191
1264
|
else
|
|
1192
1265
|
"unimplemented #{n}"
|
|
1193
1266
|
end
|
data/test/test-cddl.rb
CHANGED
|
@@ -59,9 +59,9 @@ class TestABNF < Test::Unit::TestCase
|
|
|
59
59
|
|
|
60
60
|
def test_generate_hex_bin
|
|
61
61
|
parser = CDDL::Parser.new <<HERE
|
|
62
|
-
test = [0x4711, 0b1011001110001111000]
|
|
62
|
+
test = [0x4711, 0xabcDEF, 0b1011001110001111000]
|
|
63
63
|
HERE
|
|
64
|
-
assert_equal [0x4711, 0b1011001110001111000], parser.generate
|
|
64
|
+
assert_equal [0x4711, 0xabcDEF, 0b1011001110001111000], parser.generate
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def test_generate_le
|
|
@@ -171,6 +171,57 @@ HERE
|
|
|
171
171
|
assert parser.validate_for_test(true)
|
|
172
172
|
end
|
|
173
173
|
|
|
174
|
+
def test_validate_bignum
|
|
175
|
+
parser = CDDL::Parser.new <<HERE
|
|
176
|
+
test = bigint
|
|
177
|
+
HERE
|
|
178
|
+
assert parser.validate_for_test(2**4711)
|
|
179
|
+
assert parser.validate_for_test(-2**815)
|
|
180
|
+
assert parser.validate_for_test(1)
|
|
181
|
+
assert parser.validate_for_test(0)
|
|
182
|
+
assert parser.validate_for_test(-11)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def test_aaaaaaaa_invalidate_bignum
|
|
186
|
+
parser = CDDL::Parser.new <<HERE
|
|
187
|
+
test = bignint
|
|
188
|
+
HERE
|
|
189
|
+
refute parser.validate_for_test(2**4711, false)
|
|
190
|
+
assert parser.validate_for_test(-2**815)
|
|
191
|
+
refute parser.validate_for_test(1, false)
|
|
192
|
+
refute parser.validate_for_test(0, false)
|
|
193
|
+
assert parser.validate_for_test(-11)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def test_aaaaaaaa_validate_bignum0b
|
|
198
|
+
parser = CDDL::Parser.new <<HERE
|
|
199
|
+
test = #6.2("")
|
|
200
|
+
HERE
|
|
201
|
+
refute parser.validate_for_test(1, false)
|
|
202
|
+
refute parser.validate_for_test(0, false)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def test_aaaaaaaa_validate_bignum0
|
|
207
|
+
parser = CDDL::Parser.new <<HERE
|
|
208
|
+
test = #6.2(h'')
|
|
209
|
+
HERE
|
|
210
|
+
assert parser.validate_for_test(0)
|
|
211
|
+
refute parser.validate_for_test(1, false)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def test_aaaaaaaa_validate_bignum1
|
|
216
|
+
parser = CDDL::Parser.new <<HERE
|
|
217
|
+
test = #6.2(h'01')
|
|
218
|
+
HERE
|
|
219
|
+
assert parser.validate_for_test(1)
|
|
220
|
+
refute parser.validate_for_test(0, false)
|
|
221
|
+
refute parser.validate_for_test(2, false)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
|
|
174
225
|
def test_validate_a
|
|
175
226
|
parser = CDDL::Parser.new <<HERE
|
|
176
227
|
test = [* one: 1]
|
|
@@ -202,6 +253,54 @@ HERE
|
|
|
202
253
|
assert parser.validate_for_test({"one" => 1, "two" => 1}, false)
|
|
203
254
|
end
|
|
204
255
|
|
|
256
|
+
def test_validate_a_nontrivial_group_map
|
|
257
|
+
parser = CDDL::Parser.new <<HERE
|
|
258
|
+
test = {* (text => 1, text => 2)}
|
|
259
|
+
HERE
|
|
260
|
+
assert parser.validate_for_test({})
|
|
261
|
+
assert parser.validate_for_test({"one" => 2, "two" => 1})
|
|
262
|
+
assert parser.validate_for_test({"one" => 1, "two" => 2})
|
|
263
|
+
refute parser.validate_for_test({"one" => 1}, false)
|
|
264
|
+
assert parser.validate_for_test({"one" => 1, "two" => 2, "uno" => 1, "due" => 2})
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def test_murray
|
|
269
|
+
parser = CDDL::Parser.new <<HERE
|
|
270
|
+
a = {
|
|
271
|
+
b
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
b = (
|
|
275
|
+
(x: int // y: int), z: int
|
|
276
|
+
)
|
|
277
|
+
HERE
|
|
278
|
+
assert parser.validate_for_test({})
|
|
279
|
+
assert parser.validate_for_test({"x" => 2, "z" => 1})
|
|
280
|
+
assert parser.validate_for_test({"y" => 1, "z" => 2})
|
|
281
|
+
refute parser.validate_for_test({"z" => 1}, false)
|
|
282
|
+
assert parser.validate_for_test({"one" => 1, "two" => 2, "uno" => 1, "due" => 2})
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def test_murray_workaround
|
|
287
|
+
parser = CDDL::Parser.new <<HERE
|
|
288
|
+
a = {
|
|
289
|
+
b
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
b = ( z: int
|
|
293
|
+
(x: int // y: int)
|
|
294
|
+
)
|
|
295
|
+
HERE
|
|
296
|
+
assert parser.validate_for_test({})
|
|
297
|
+
assert parser.validate_for_test({"x" => 2, "z" => 1})
|
|
298
|
+
assert parser.validate_for_test({"y" => 1, "z" => 2})
|
|
299
|
+
refute parser.validate_for_test({"z" => 1}, false)
|
|
300
|
+
assert parser.validate_for_test({"one" => 1, "two" => 2, "uno" => 1, "due" => 2})
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
|
|
205
304
|
def test_validate_a_string
|
|
206
305
|
parser = CDDL::Parser.new <<HERE
|
|
207
306
|
test = [* one: "one"]
|
data/test-data/7807.cddl
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
coap-problem-details = {
|
|
2
|
+
type => uint,
|
|
3
|
+
? title => text,
|
|
4
|
+
? response-code => bstr .size 1,
|
|
5
|
+
? detail => text,
|
|
6
|
+
? instance => uri,
|
|
7
|
+
* $$coap-problem-details-extension,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type = 0
|
|
11
|
+
title = 1
|
|
12
|
+
response-code = 2
|
|
13
|
+
detail = 3
|
|
14
|
+
instance = 4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
abignum = unsigned
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
badaddr = text .regexp "[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]"
|
data/test-data/bpv7.cddl
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
start = bundle
|
|
2
|
+
|
|
3
|
+
dtn-time = uint
|
|
4
|
+
|
|
5
|
+
creation-timestamp = [dtn-time, sequence: uint]
|
|
6
|
+
|
|
7
|
+
eid-generic = [uri-code, SSP: any]
|
|
8
|
+
|
|
9
|
+
uri-code = uint
|
|
10
|
+
|
|
11
|
+
eid = eid-choice .within eid-generic
|
|
12
|
+
|
|
13
|
+
eid-choice /= [dtn-code, SSP: (text / 0)]
|
|
14
|
+
|
|
15
|
+
dtn-code = 1 ; TBD
|
|
16
|
+
|
|
17
|
+
eid-choice /= [ipn-code, SSP: [nodenum: uint, servicenum: uint]]
|
|
18
|
+
|
|
19
|
+
ipn-code = 2 ; TBD
|
|
20
|
+
|
|
21
|
+
bundle-control-flags = uint .bits bundleflagbits
|
|
22
|
+
|
|
23
|
+
bundleflagbits = &(
|
|
24
|
+
|
|
25
|
+
reserved: 15
|
|
26
|
+
|
|
27
|
+
reserved: 14
|
|
28
|
+
|
|
29
|
+
reserved: 13
|
|
30
|
+
|
|
31
|
+
bundle-deletion-status-reports-are-requested: 12
|
|
32
|
+
|
|
33
|
+
bundle-delivery-status-reports-are-requested: 11
|
|
34
|
+
|
|
35
|
+
bundle-forwarding-status-reports-are-requested: 10
|
|
36
|
+
|
|
37
|
+
reserved: 9
|
|
38
|
+
|
|
39
|
+
bundle-reception-status-reports-are-requested: 8
|
|
40
|
+
|
|
41
|
+
bundle-contains-a-Manifest-block: 7
|
|
42
|
+
|
|
43
|
+
status-time-is-requested-in-all-status-reports: 6
|
|
44
|
+
|
|
45
|
+
user-application-acknowledgement-is-requested: 5
|
|
46
|
+
|
|
47
|
+
reserved: 4
|
|
48
|
+
|
|
49
|
+
reserved: 3
|
|
50
|
+
|
|
51
|
+
bundle-must-not-be-fragmented: 2
|
|
52
|
+
|
|
53
|
+
payload-is-an-administrative-record: 1
|
|
54
|
+
|
|
55
|
+
bundle-is-a-fragment: 0
|
|
56
|
+
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
crc = bytes
|
|
60
|
+
|
|
61
|
+
block-control-flags = uint .bits blockflagbits
|
|
62
|
+
|
|
63
|
+
blockflagbits = &(
|
|
64
|
+
|
|
65
|
+
reserved: 7
|
|
66
|
+
|
|
67
|
+
reserved: 6
|
|
68
|
+
|
|
69
|
+
reserved: 5
|
|
70
|
+
|
|
71
|
+
reserved: 4
|
|
72
|
+
|
|
73
|
+
bundle-must-be-deleted-if-block-cannot-be-processed: 3
|
|
74
|
+
|
|
75
|
+
status-report-must-be-transmitted-if-block-cannot-be-processed: 2
|
|
76
|
+
|
|
77
|
+
block-must-be-removed-from-bundle-if-it-cannot-be-processed: 1
|
|
78
|
+
|
|
79
|
+
block-must-be-replicated-in-every-fragment: 0
|
|
80
|
+
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
bundle = [primary-block, *extension-block, payload-block]
|
|
84
|
+
|
|
85
|
+
primary-block = [
|
|
86
|
+
|
|
87
|
+
version: 7,
|
|
88
|
+
|
|
89
|
+
bundle-control-flags,
|
|
90
|
+
|
|
91
|
+
crc-type: uint,
|
|
92
|
+
|
|
93
|
+
destination: eid,
|
|
94
|
+
|
|
95
|
+
source-node: eid,
|
|
96
|
+
|
|
97
|
+
report-to: eid,
|
|
98
|
+
|
|
99
|
+
creation-timestamp,
|
|
100
|
+
|
|
101
|
+
lifetime: uint,
|
|
102
|
+
|
|
103
|
+
? fragment-offset: uint,
|
|
104
|
+
|
|
105
|
+
? total-application-data-length: uint,
|
|
106
|
+
|
|
107
|
+
? crc,
|
|
108
|
+
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
canonical-block = [
|
|
112
|
+
|
|
113
|
+
block-type-code: uint,
|
|
114
|
+
|
|
115
|
+
canonical-block-common,
|
|
116
|
+
|
|
117
|
+
? crc
|
|
118
|
+
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
canonical-block-common = (
|
|
122
|
+
|
|
123
|
+
block-number: uint,
|
|
124
|
+
|
|
125
|
+
block-control-flags,
|
|
126
|
+
|
|
127
|
+
crc-type: uint,
|
|
128
|
+
|
|
129
|
+
block-type-specific-data: bytes
|
|
130
|
+
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
payload-block = ([block-type-code: 1, canonical-block-common, ?crc]) .within canonical-block
|
|
135
|
+
|
|
136
|
+
extension-block = ([block-type-code: (uint .ne 1), canonical-block-common, ?crc]) .within canonical-block
|