cddl 0.8.15 → 0.8.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/cddl +24 -14
- data/cddl.gemspec +2 -1
- data/lib/cddl.rb +67 -10
- data/test-data/abnf1.cddl +3 -0
- data/test-data/abnf2.cddl +37 -0
- data/test-data/abnf3.cddl +32 -0
- data/test-data/cat-re.cddl +2 -0
- data/test-data/oid.cddl +8 -0
- data/test-data/sasl.cddl +24 -0
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 400024278cc4fce962a5e51e60ba6025ec371cd5768685c0ce10534a06393fa2
|
4
|
+
data.tar.gz: cbac2ff6008501c65984cb816cc95b79a8adc361609c4858ba518c073e317937
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71babdced5f362b46a1877fdb8676faf2efec9594069b9b95c80daecdfb9aad5bf13ca73577437089fb1dd4819506b00311c003699831110fbba464c06d86fad
|
7
|
+
data.tar.gz: 2a29deef318b1c31a830e8937618d776fc439bc6a5b792b7daa79545ed29aedb028f6e78ce3f3b04f36767f21cf38ff349f6251ff3d83103f02c94a124132f34
|
data/bin/cddl
CHANGED
@@ -14,8 +14,8 @@ def usage
|
|
14
14
|
warn "Usage:"
|
15
15
|
warn "#$0 spec.cddl generate [n]"
|
16
16
|
warn "#$0 spec.cddl json-generate [n]"
|
17
|
-
warn "#$0 spec.cddl validate instance.cbor"
|
18
|
-
warn "#$0 spec.cddl validate instance.json"
|
17
|
+
warn "#$0 spec.cddl validate instance.cbor..."
|
18
|
+
warn "#$0 spec.cddl validate instance.json..."
|
19
19
|
exit EX_USAGE
|
20
20
|
end
|
21
21
|
|
@@ -48,6 +48,8 @@ def my_diag(v)
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
retcode = 0
|
52
|
+
|
51
53
|
begin
|
52
54
|
case ARGV[1]
|
53
55
|
when /\A..*p/
|
@@ -85,19 +87,25 @@ begin
|
|
85
87
|
g = parser.generate
|
86
88
|
puts JSON.pretty_generate(g)
|
87
89
|
end
|
88
|
-
when /\Av
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
90
|
+
when /\Av(v)?/
|
91
|
+
verbose = $1
|
92
|
+
ARGV[2..-1].each do |fn|
|
93
|
+
instance = read_arg(fn)
|
94
|
+
instance = if $sequence
|
95
|
+
CBOR.decode("\x9f".b << instance.b << "\xff".b)
|
96
|
+
else
|
97
|
+
CBOR.decode(instance.b) rescue JSON.load(instance)
|
98
|
+
end
|
99
|
+
instance = instance.cbor_clone if $annotate && ENV["EXPERIMENTAL_ANNOTATE"]
|
100
|
+
warn "#{fn}:" if verbose
|
101
|
+
ann = parser.validate(instance)
|
102
|
+
# my_pp ann
|
103
|
+
instance.cbor_add_annotations_from(ann) rescue nil
|
104
|
+
my_diag(instance) if $annotate
|
105
|
+
unless ann
|
106
|
+
retcode = 1
|
107
|
+
end
|
94
108
|
end
|
95
|
-
instance = instance.cbor_clone if $annotate && ENV["EXPERIMENTAL_ANNOTATE"]
|
96
|
-
ann = parser.validate(instance)
|
97
|
-
# my_pp ann
|
98
|
-
instance.cbor_add_annotations_from(ann) rescue nil
|
99
|
-
my_diag(instance) if $annotate
|
100
|
-
exit 1 unless ann
|
101
109
|
else
|
102
110
|
usage
|
103
111
|
end
|
@@ -105,3 +113,5 @@ rescue CDDL::ParseError => e
|
|
105
113
|
warn e.message
|
106
114
|
exit EX_DATAERR
|
107
115
|
end
|
116
|
+
|
117
|
+
exit retcode
|
data/cddl.gemspec
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
2
2
|
s.name = 'cddl'
|
3
|
-
s.version = '0.8.
|
3
|
+
s.version = '0.8.20'
|
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')
|
7
7
|
s.add_dependency('abnc')
|
8
8
|
s.add_dependency('json')
|
9
|
+
s.add_dependency('abnftt')
|
9
10
|
s.add_dependency('regexp-examples') # , '1.1.0')
|
10
11
|
s.add_dependency('colorize')
|
11
12
|
s.files = `git ls-files`.split("\n").grep(/^[a-z]/)
|
data/lib/cddl.rb
CHANGED
@@ -3,6 +3,7 @@ require 'pp'
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'cbor-pure' unless defined?(CBOR::Tagged)
|
5
5
|
require 'regexp-examples'
|
6
|
+
require 'abnftt'
|
6
7
|
require 'colorize'
|
7
8
|
require 'base64'
|
8
9
|
|
@@ -243,12 +244,28 @@ module CDDL
|
|
243
244
|
[rule[0], *rule[1]]
|
244
245
|
end
|
245
246
|
|
247
|
+
def remove_indentation(s)
|
248
|
+
l = s.lines
|
249
|
+
indent = l.grep(/\S/).map {|l| l[/^\s*/].size}.min
|
250
|
+
l.map {|l| l.sub(/^ {0,#{indent}}/, "")}.join
|
251
|
+
end
|
252
|
+
|
246
253
|
# Memoize a bit here
|
247
254
|
|
248
255
|
REGEXP_FOR_STRING = Hash.new {|h, k|
|
249
256
|
h[k] = Regexp.new("\\A#{k}\\z")
|
250
257
|
}
|
251
258
|
|
259
|
+
ABNF_PARSER_FOR_STRING = Hash.new {|h, k|
|
260
|
+
grammar = "cddl-t0p--1eve1-f0r--abnf = " << k # XXX
|
261
|
+
h[k] = ABNF.from_abnf(grammar)
|
262
|
+
}
|
263
|
+
|
264
|
+
ABNF_ENCODING_FOR_CONOP = {
|
265
|
+
abnf: Encoding::UTF_8,
|
266
|
+
abnfb: Encoding::BINARY
|
267
|
+
}
|
268
|
+
|
252
269
|
def generate
|
253
270
|
@recursion = 0
|
254
271
|
generate1(rules)
|
@@ -393,7 +410,7 @@ module CDDL
|
|
393
410
|
when :anno
|
394
411
|
target = where[2]
|
395
412
|
control = where[3]
|
396
|
-
case where[1]
|
413
|
+
case conop = where[1]
|
397
414
|
when :size
|
398
415
|
should_be_int = generate1(control)
|
399
416
|
unless (Array === target && target[0] == :prim && [0, 2, 3].include?(target[1])) && Integer === should_be_int && should_be_int >= 0
|
@@ -441,9 +458,10 @@ module CDDL
|
|
441
458
|
generate1(target, inmap)
|
442
459
|
when :feature
|
443
460
|
generate1(target, inmap)
|
444
|
-
when :cat
|
461
|
+
when :cat, :bat
|
445
462
|
lhs = generate1(target, inmap)
|
446
463
|
rhs = generate1(control)
|
464
|
+
rhs = remove_indentation(rhs) if conop == :bat
|
447
465
|
begin
|
448
466
|
lhs + rhs
|
449
467
|
rescue Exception => e
|
@@ -477,7 +495,7 @@ module CDDL
|
|
477
495
|
content = Integer(content)
|
478
496
|
case target[1]
|
479
497
|
when 0
|
480
|
-
case
|
498
|
+
case conop
|
481
499
|
when :lt
|
482
500
|
rand(0...content)
|
483
501
|
when :le
|
@@ -504,12 +522,25 @@ module CDDL
|
|
504
522
|
fail "Don't know yet how to generate #{where}"
|
505
523
|
end
|
506
524
|
REGEXP_FOR_STRING[regexp].random_example(max_repeater_variance: 5)
|
525
|
+
when :abnf, :abnfb
|
526
|
+
grammar = generate1(control)
|
527
|
+
bytes = true if target == [:prim, 2]
|
528
|
+
bytes = false if target == [:prim, 3]
|
529
|
+
unless !bytes.nil? && String === grammar
|
530
|
+
fail "Don't know yet how to generate #{where}"
|
531
|
+
end
|
532
|
+
out = ABNF_PARSER_FOR_STRING[grammar].generate
|
533
|
+
if conop == :abnfb
|
534
|
+
out = out.codepoints.pack("C*")
|
535
|
+
end
|
536
|
+
enc = bytes ? Encoding::BINARY : Encoding::UTF_8
|
537
|
+
out.force_encoding(enc)
|
507
538
|
when :cbor, :cborseq
|
508
539
|
unless target == [:prim, 2]
|
509
540
|
fail "Don't know yet how to generate #{where}"
|
510
541
|
end
|
511
542
|
content = CBOR::encode(generate1(control))
|
512
|
-
if
|
543
|
+
if conop == :cborseq
|
513
544
|
# remove the first head
|
514
545
|
n = case content.getbyte(0) - (4 << 5)
|
515
546
|
when 0..23; 1
|
@@ -527,7 +558,7 @@ module CDDL
|
|
527
558
|
content = generate1(target)
|
528
559
|
if validate1(content, control)
|
529
560
|
return content
|
530
|
-
elsif
|
561
|
+
elsif conop == :within
|
531
562
|
warn "*** #{content.inspect} meets #{target.inspect} but not #{control.inspect}"
|
532
563
|
end
|
533
564
|
end
|
@@ -568,7 +599,7 @@ module CDDL
|
|
568
599
|
elsif t[0] == :anno
|
569
600
|
_, conop, target, control = t
|
570
601
|
# warn ["EXV0", conop, target, control].inspect
|
571
|
-
if conop == :cat || conop == :plus
|
602
|
+
if conop == :cat || conop == :plus || conop == :bat
|
572
603
|
ok1, v1, vt1 = extract_value(target)
|
573
604
|
ok2, v2, vt2 = extract_value(control)
|
574
605
|
# warn ["EXV", ok1, v1, vt1, ok2, v2, vt2].inspect
|
@@ -578,6 +609,7 @@ module CDDL
|
|
578
609
|
elsif vt1 == Float
|
579
610
|
[true, v1 + v2, vt1] if vt2 == Integer || vt2 == Float
|
580
611
|
else
|
612
|
+
v2 = remove_indentation(v2) if conop == :bat
|
581
613
|
[true, v1 + v2, vt1] if vt1 == vt2
|
582
614
|
end
|
583
615
|
end rescue nil
|
@@ -606,7 +638,10 @@ module CDDL
|
|
606
638
|
if warn
|
607
639
|
if result
|
608
640
|
if $features != {}
|
609
|
-
|
641
|
+
ok = ENV["CDDL_FEATURE_OK"] and ok = ok.split(/,\s*/) or ok = []
|
642
|
+
# warn([:OK, ok, $features].inspect)
|
643
|
+
features = $features.reject {|k, v| ok.include? k.to_s }
|
644
|
+
warn "** Features potentially used: #{features.map {|k, v| "#{k}: #{v.keys}"}.join(", ")}" if features != {}
|
610
645
|
end
|
611
646
|
else
|
612
647
|
warn "CDDL validation failure (#{result.inspect} for #{d.inspect}):"
|
@@ -619,7 +654,7 @@ module CDDL
|
|
619
654
|
|
620
655
|
def validate_result(check)
|
621
656
|
check || (
|
622
|
-
@last_message
|
657
|
+
@last_message << yield
|
623
658
|
false
|
624
659
|
)
|
625
660
|
end
|
@@ -652,7 +687,9 @@ module CDDL
|
|
652
687
|
ann.concat(ann2)
|
653
688
|
end
|
654
689
|
if occ < s
|
655
|
-
|
690
|
+
# warn "*** lme #{@last_message.encoding} #{@last_message}"
|
691
|
+
# warn "*** #{"\noccur #{occ} < #{s}, not reached at #{i} in array #{d} for #{where}".encoding}"
|
692
|
+
@last_message << "\noccur #{occ} < #{s}, not reached at #{i} in array #{d} for #{where}"
|
656
693
|
return [false, ann]
|
657
694
|
end
|
658
695
|
end
|
@@ -817,6 +854,7 @@ module CDDL
|
|
817
854
|
# warn ["ANNO0", ok1, v1, vt1, ok2, v2, vt2, d].inspect
|
818
855
|
if ok1 && ok2
|
819
856
|
v2 = Integer(v2) if vt1 == Integer
|
857
|
+
v2 = remove_indentation(v2) if conop == :bat
|
820
858
|
# warn ["ANNO", ok1, v1, vt1, ok2, v2, vt2, d].inspect
|
821
859
|
[] if d == v1 + v2 # XXX Focus ArgumentError
|
822
860
|
end
|
@@ -893,6 +931,24 @@ module CDDL
|
|
893
931
|
end
|
894
932
|
end
|
895
933
|
)
|
934
|
+
when :abnf, :abnfb
|
935
|
+
ann if (
|
936
|
+
if String === d
|
937
|
+
ok, v, vt = extract_value(control)
|
938
|
+
if ok && vt == String
|
939
|
+
begin
|
940
|
+
ABNF_PARSER_FOR_STRING[v].validate(
|
941
|
+
d.dup.force_encoding(ABNF_ENCODING_FOR_CONOP[conop]).codepoints.pack("U*")
|
942
|
+
)
|
943
|
+
true
|
944
|
+
rescue => e
|
945
|
+
# warn "*** #{e}" # XXX
|
946
|
+
@last_message = e.to_s.force_encoding(Encoding::UTF_8)
|
947
|
+
nil
|
948
|
+
end
|
949
|
+
end
|
950
|
+
end
|
951
|
+
)
|
896
952
|
when :cbor
|
897
953
|
ann if validate1((CBOR::decode(d) rescue :BAD_CBOR), control)
|
898
954
|
when :cborseq
|
@@ -1247,7 +1303,8 @@ module CDDL
|
|
1247
1303
|
BRACE = {"{" => :map, "[" => :array}
|
1248
1304
|
RANGE_EXCLUDE_END = {".." => false, "..." => true}
|
1249
1305
|
SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp, :cbor, :cborseq, :within, :and,
|
1250
|
-
:default, :lt, :le, :gt, :ge, :eq, :ne,
|
1306
|
+
:default, :lt, :le, :gt, :ge, :eq, :ne,
|
1307
|
+
:feature, :abnf, :abnfb, :bat, :cat, :plus]
|
1251
1308
|
|
1252
1309
|
def type1(n, canbegroup = false)
|
1253
1310
|
# puts "NVALUE #{n.value.inspect}"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
start = [Tag0, Tag1004]
|
2
|
+
|
3
|
+
; for draft-ietf-cbor-date-tag
|
4
|
+
Tag1004 = #6.1004(text .abnf full-date)
|
5
|
+
; for RFC 7049
|
6
|
+
Tag0 = #6.0(text .abnf date-time)
|
7
|
+
|
8
|
+
full-date = "full-date" .cat rfc3339
|
9
|
+
date-time = "date-time" .cat rfc3339
|
10
|
+
|
11
|
+
; Note the trick of idiomatically starting with a newline, separating
|
12
|
+
; off the element in the .cat from the rule-list
|
13
|
+
rfc3339 = '
|
14
|
+
date-fullyear = 4DIGIT
|
15
|
+
date-month = 2DIGIT ; 01-12
|
16
|
+
date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
|
17
|
+
; month/year
|
18
|
+
time-hour = 2DIGIT ; 00-23
|
19
|
+
time-minute = 2DIGIT ; 00-59
|
20
|
+
time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap sec
|
21
|
+
; rules
|
22
|
+
time-secfrac = "." 1*DIGIT
|
23
|
+
time-numoffset = ("+" / "-") time-hour ":" time-minute
|
24
|
+
time-offset = "Z" / time-numoffset
|
25
|
+
|
26
|
+
partial-time = time-hour ":" time-minute ":" time-second
|
27
|
+
[time-secfrac]
|
28
|
+
full-date = date-fullyear "-" date-month "-" date-mday
|
29
|
+
full-time = partial-time time-offset
|
30
|
+
|
31
|
+
date-time = full-date "T" full-time
|
32
|
+
' .cat rfc5234-core
|
33
|
+
|
34
|
+
rfc5234-core = '
|
35
|
+
DIGIT = %x30-39 ; 0-9
|
36
|
+
; abbreviated here
|
37
|
+
'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
start = [tt, tb, bt, bb]
|
2
|
+
|
3
|
+
|
4
|
+
tt = text .abnf '4DIGIT 1FOO
|
5
|
+
DIGIT = %x30-39 ; 0-9
|
6
|
+
FOO = %xc0-cf
|
7
|
+
'
|
8
|
+
tb = text .abnfb '4DIGIT 1FOO
|
9
|
+
DIGIT = %x30-39 ; 0-9
|
10
|
+
FOO = %xc0-cf
|
11
|
+
'
|
12
|
+
bt = bytes .abnf '4DIGIT 1FOO
|
13
|
+
DIGIT = %x30-39 ; 0-9
|
14
|
+
FOO = %xc0-cf
|
15
|
+
'
|
16
|
+
bb = bytes .abnfb '4DIGIT 1FOO
|
17
|
+
DIGIT = %x30-39 ; 0-9
|
18
|
+
FOO = %xc0-cf
|
19
|
+
'
|
20
|
+
|
21
|
+
; ["7408\xC6", "7073\xC3", h'30383131CD', h'32363738CD']
|
22
|
+
; ["5892\u00ca", "2145\u00c6", h'33333338C38B', h'31343033C388']
|
23
|
+
|
24
|
+
|
25
|
+
; ** ENCOED UTF-8
|
26
|
+
; ** ENCOED UTF-8
|
27
|
+
; ** ENCOED UTF-8
|
28
|
+
; ** ENCOED UTF-8
|
29
|
+
; ["5845\u00c6", "9329\u00cb", h'38393538C389', h'33343230C386']
|
30
|
+
|
31
|
+
|
32
|
+
; ["1066\u00cc", "9253\xC9", h'38333533C38A', h'32373337C4']
|
data/test-data/oid.cddl
ADDED
data/test-data/sasl.cddl
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
message = text .abnfb ("message" .cat rfc4505)
|
2
|
+
|
3
|
+
rfc4505 = '
|
4
|
+
message = [ email / token ]
|
5
|
+
;; to be prepared in accordance with Section 3
|
6
|
+
|
7
|
+
UTF1 = %x00-3F / %x41-7F ;; less "@" (U+0040)
|
8
|
+
UTF2 = %xC2-DF UTF0
|
9
|
+
UTF3 = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) /
|
10
|
+
%xED %x80-9F UTF0 / %xEE-EF 2(UTF0)
|
11
|
+
UTF4 = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) /
|
12
|
+
%xF4 %x80-8F 2(UTF0)
|
13
|
+
UTF0 = %x80-BF
|
14
|
+
|
15
|
+
TCHAR = UTF1 / UTF2 / UTF3 / UTF4
|
16
|
+
;; any UTF-8 encoded Unicode character
|
17
|
+
;; except "@" (U+0040)
|
18
|
+
|
19
|
+
email = "too@much.work"; for this example
|
20
|
+
;email = addr-spec
|
21
|
+
;; as defined in [IMAIL]
|
22
|
+
|
23
|
+
token = 1*255TCHAR
|
24
|
+
'
|
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.8.
|
4
|
+
version: 0.8.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cbor-diag
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: abnftt
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: regexp-examples
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,6 +114,9 @@ files:
|
|
100
114
|
- test-data/7807.cddl
|
101
115
|
- test-data/a.cddl
|
102
116
|
- test-data/abignum.cddl
|
117
|
+
- test-data/abnf1.cddl
|
118
|
+
- test-data/abnf2.cddl
|
119
|
+
- test-data/abnf3.cddl
|
103
120
|
- test-data/ambig.cddl
|
104
121
|
- test-data/b.cddl
|
105
122
|
- test-data/badaddr.cddl
|
@@ -107,6 +124,7 @@ files:
|
|
107
124
|
- test-data/bpv7.cddl
|
108
125
|
- test-data/bpv7a.cddl
|
109
126
|
- test-data/bpv7b.cddl
|
127
|
+
- test-data/cat-re.cddl
|
110
128
|
- test-data/cdni-ct.cddl
|
111
129
|
- test-data/coral.cddl
|
112
130
|
- test-data/coral1.cddl
|
@@ -148,8 +166,10 @@ files:
|
|
148
166
|
- test-data/mon-val.cddl
|
149
167
|
- test-data/multipart-ct.cddl
|
150
168
|
- test-data/named-group.cddl
|
169
|
+
- test-data/oid.cddl
|
151
170
|
- test-data/patch1.cddl
|
152
171
|
- test-data/reused_named_group.cddl
|
172
|
+
- test-data/sasl.cddl
|
153
173
|
- test-data/sequence.cddl
|
154
174
|
- test-data/structure.cddl
|
155
175
|
- test-data/test-gen.cddl
|
@@ -181,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
201
|
- !ruby/object:Gem::Version
|
182
202
|
version: '0'
|
183
203
|
requirements: []
|
184
|
-
rubygems_version: 3.
|
204
|
+
rubygems_version: 3.2.3
|
185
205
|
signing_key:
|
186
206
|
specification_version: 4
|
187
207
|
summary: CDDL generator and validator.
|