cddl 0.9.3 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cddl.gemspec +2 -1
- data/lib/cddl.rb +141 -22
- data/test/test-cddl.rb +2 -2
- data/test-data/b64c.cddl +1 -0
- data/test-data/b64u.cddl +1 -0
- data/test-data/base32.cddl +1 -0
- data/test-data/base32hex.cddl +1 -0
- data/test-data/decimal.cddl +1 -0
- data/test-data/decimal2.cddl +1 -0
- data/test-data/hex.cddl +1 -0
- data/test-data/hexlc.cddl +1 -0
- data/test-data/hexuc.cddl +1 -0
- data/test-data/join.cddl +1 -0
- data/test-data/joini.cddl +1 -0
- data/test-data/joinx.cddl +1 -0
- data/test-data/json.cddl +1 -0
- data/test-data/json2.cddl +1 -0
- metadata +31 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33adef2ddb191ca70e7ad3742684cea679e675fe0169a139c9fa5bcc59abfaa6
|
4
|
+
data.tar.gz: 7b7b7d2cd0623645d6dca87c5c7a8a3d40540e7eec390411e9cbf3adcc6f7c9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4a8ccd11e9dbf1b0ebf2541c03691a94a8430538fbe81db3bd178a2fab1732626114689d305048e88fb54c3336f0e95853c86f8336586d722df90639f82efa6
|
7
|
+
data.tar.gz: 1c6494a0fa4ead8ea548f61f3af5595dde99707359ce8aa8695c074288248334849f2452cae52620541bb762c9cf3979b159f415a1b787009d1061df54d849b5
|
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.
|
3
|
+
s.version = '0.10.2'
|
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')
|
@@ -9,6 +9,7 @@ spec = Gem::Specification.new do |s|
|
|
9
9
|
s.add_dependency('abnftt')
|
10
10
|
s.add_dependency('regexp-examples') # , '1.1.0')
|
11
11
|
s.add_dependency('colorize')
|
12
|
+
s.add_dependency('base32', '~> 0.3')
|
12
13
|
s.files = `git ls-files`.split("\n").grep(/^[a-z]/)
|
13
14
|
s.files = Dir['lib/**/*.rb'] + %w(cddl.gemspec) + Dir['data/**/*.abnf'] + Dir['data/**/*.cddl'] + Dir['test-data/**/*.cddl'] + Dir['test/**/*.rb']
|
14
15
|
s.require_path = 'lib'
|
data/lib/cddl.rb
CHANGED
@@ -6,6 +6,7 @@ require 'regexp-examples'
|
|
6
6
|
require 'abnftt'
|
7
7
|
require 'colorize'
|
8
8
|
require 'base64'
|
9
|
+
require 'base32'
|
9
10
|
|
10
11
|
module CDDL
|
11
12
|
|
@@ -22,6 +23,20 @@ module CDDL
|
|
22
23
|
|
23
24
|
class Parser
|
24
25
|
|
26
|
+
FEATURE_REJECT_RE = /\A\^/
|
27
|
+
# CDDL_FEATURE_OK=cbor,^json
|
28
|
+
CDDL_FEATURE_OK, CDDL_FEATURE_REJECT =
|
29
|
+
if ok = ENV["CDDL_FEATURE_OK"]
|
30
|
+
ok.split(/,\s*/)
|
31
|
+
.partition{|s| s[0] !~ FEATURE_REJECT_RE}
|
32
|
+
.map {|l| Hash[l.map {|feature|
|
33
|
+
[feature.sub(FEATURE_REJECT_RE, ''),
|
34
|
+
true]}]}
|
35
|
+
else
|
36
|
+
[{}, {}]
|
37
|
+
end
|
38
|
+
|
39
|
+
|
25
40
|
class BackTrack < Exception; end
|
26
41
|
|
27
42
|
def initialize(source_text)
|
@@ -130,7 +145,7 @@ module CDDL
|
|
130
145
|
if subtree[0] == :type1 && subtree[1..-1].all? {|x| x[0] == :int}
|
131
146
|
if enumname = subtree.cbor_annotations rescue nil
|
132
147
|
enumname = cname(enumname.first)
|
133
|
-
subtree[1..-1].each do |x|
|
148
|
+
subtree[1..-1].each do |x|
|
134
149
|
if memname = x.cbor_annotations
|
135
150
|
memname = "#{enumname}_#{cname(memname.first)}"
|
136
151
|
add.(memname, x[1].to_s)
|
@@ -459,6 +474,11 @@ module CDDL
|
|
459
474
|
end
|
460
475
|
generate1(target, inmap)
|
461
476
|
when :feature
|
477
|
+
feature, = extract_feature(control, nil)
|
478
|
+
# warn "@@@ GENFEAT #{feature.inspect} #{CDDL_FEATURE_REJECT[feature].inspect}"
|
479
|
+
if CDDL_FEATURE_REJECT[feature]
|
480
|
+
fail BackTrack.new("Feature '#{feature}' rejected")
|
481
|
+
end
|
462
482
|
generate1(target, inmap)
|
463
483
|
when :cat, :det
|
464
484
|
lhs = generate1(target, inmap)
|
@@ -559,6 +579,51 @@ module CDDL
|
|
559
579
|
content[0...n] = ''
|
560
580
|
end
|
561
581
|
content
|
582
|
+
when :json
|
583
|
+
unless target == [:prim, 3]
|
584
|
+
fail "Don't know yet how to generate #{where}"
|
585
|
+
end
|
586
|
+
content = JSON::dump(generate1(control))
|
587
|
+
content
|
588
|
+
when :decimal
|
589
|
+
unless target == [:prim, 3]
|
590
|
+
fail "Don't know yet how to generate #{where}"
|
591
|
+
end
|
592
|
+
content = Integer(generate1(control)).to_s
|
593
|
+
content
|
594
|
+
when :join
|
595
|
+
content = generate1(control)
|
596
|
+
unless Array === content &&
|
597
|
+
content.all? {|x| String === x &&
|
598
|
+
((target == [:prim, 2] && x.encoding == Encoding::BINARY) ||
|
599
|
+
(target == [:prim, 3] && x.encoding != Encoding::BINARY))}
|
600
|
+
fail "Don't know yet how to generate #{where}"
|
601
|
+
end
|
602
|
+
content = content.join
|
603
|
+
content
|
604
|
+
when :b64u, :b64c, :b32, :h32, :hex, :hexlc, :hexuc
|
605
|
+
content = generate1(control)
|
606
|
+
unless String === content
|
607
|
+
fail "Don't know yet how to generate #{where}"
|
608
|
+
end
|
609
|
+
content = case conop
|
610
|
+
when :b64u
|
611
|
+
Base64.urlsafe_encode64(content, padding: false)
|
612
|
+
when :b64c
|
613
|
+
Base64.strict_encode64(content)
|
614
|
+
when :b32
|
615
|
+
Base32.table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
616
|
+
Base32.encode(content).gsub("=", "")
|
617
|
+
when :h32
|
618
|
+
Base32.table = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
|
619
|
+
Base32.encode(content).gsub("=", "")
|
620
|
+
when :hex, :hexuc
|
621
|
+
content.unpack("H*")[0].upcase
|
622
|
+
when :hexlc
|
623
|
+
content.unpack("H*")[0]
|
624
|
+
else fail "Cannot happen"
|
625
|
+
end
|
626
|
+
content
|
562
627
|
when :within, :and
|
563
628
|
32.times do
|
564
629
|
content = generate1(target)
|
@@ -636,6 +701,25 @@ module CDDL
|
|
636
701
|
}]
|
637
702
|
end
|
638
703
|
|
704
|
+
def extract_feature(control, d)
|
705
|
+
ok, v, vt = extract_value(control)
|
706
|
+
if ok
|
707
|
+
nm = v
|
708
|
+
det = d
|
709
|
+
warn "*** feature controller should be a string: #{control.inspect}" unless String == vt
|
710
|
+
else
|
711
|
+
ok, *v = extract_array(control)
|
712
|
+
if ok && v.size == 2
|
713
|
+
nm = v[0][0]
|
714
|
+
det = v[1][0]
|
715
|
+
warn "*** first element of feature controller should be a string: #{control.inspect}" unless String === nm
|
716
|
+
else
|
717
|
+
warn "*** feature controller not implemented: #{control.inspect}"
|
718
|
+
end
|
719
|
+
end
|
720
|
+
[nm, det]
|
721
|
+
end
|
722
|
+
|
639
723
|
def validate_diag
|
640
724
|
[@last_data, @last_rule, @last_message]
|
641
725
|
end
|
@@ -647,9 +731,8 @@ module CDDL
|
|
647
731
|
if warn
|
648
732
|
if result
|
649
733
|
if $features != {}
|
650
|
-
|
651
|
-
# warn
|
652
|
-
features = $features.reject {|k, v| ok.include? k.to_s }
|
734
|
+
features = $features.reject {|k, v| CDDL_FEATURE_OK[k.to_s] }
|
735
|
+
# warn "@@@ FEAT #{CDDL_FEATURE_OK.inspect} #{CDDL_FEATURE_REJECT.inspect}"
|
653
736
|
warn "** Features potentially used (#$fn): #{features.map {|k, v| "#{k}: #{v.keys}"}.join(", ")}" if features != {}
|
654
737
|
end
|
655
738
|
else
|
@@ -915,23 +998,9 @@ module CDDL
|
|
915
998
|
end
|
916
999
|
ann
|
917
1000
|
when :feature
|
918
|
-
|
919
|
-
if ok
|
920
|
-
nm = v
|
921
|
-
det = d
|
922
|
-
warn "*** feature controller should be a string: #{control.inspect}" unless String == vt
|
923
|
-
else
|
924
|
-
ok, *v = extract_array(control)
|
925
|
-
if ok && v.size == 2
|
926
|
-
nm = v[0][0]
|
927
|
-
det = v[1][0]
|
928
|
-
warn "*** first element of feature controller should be a string: #{control.inspect}" unless String === nm
|
929
|
-
else
|
930
|
-
warn "*** feature controller not implemented: #{control.inspect}"
|
931
|
-
end
|
932
|
-
end
|
1001
|
+
nm, det = extract_feature(control, d)
|
933
1002
|
$features[nm][det] = true
|
934
|
-
ann
|
1003
|
+
ann if !CDDL_FEATURE_REJECT[nm]
|
935
1004
|
when :lt, :le, :gt, :ge, :eq, :ne
|
936
1005
|
op = OPERATORS[conop]
|
937
1006
|
ok, v, _vt = extract_value(control)
|
@@ -971,6 +1040,53 @@ module CDDL
|
|
971
1040
|
ann if validate1((CBOR::decode(d) rescue :BAD_CBOR), control)
|
972
1041
|
when :cborseq
|
973
1042
|
ann if validate1((CBOR::decode("\x9f".b << d << "\xff".b) rescue :BAD_CBOR), control)
|
1043
|
+
when :json
|
1044
|
+
ann if validate1((JSON::load(d) rescue :BAD_JSON), control)
|
1045
|
+
when :decimal
|
1046
|
+
ann if (
|
1047
|
+
if /\A0|-?[1-9][0-9]*\z/ === d
|
1048
|
+
validate1((d.to_i rescue :BAD_JSON), control)
|
1049
|
+
end
|
1050
|
+
)
|
1051
|
+
when :join
|
1052
|
+
ok, *v = extract_array(control)
|
1053
|
+
# warn "@@@JJJ@@@ #{ok.inspect} #{v.inspect}"
|
1054
|
+
if ok
|
1055
|
+
expected = v.map {|ve|
|
1056
|
+
fail "Not a string in #{where}" unless String === ve[0]
|
1057
|
+
ve[0]
|
1058
|
+
}.join
|
1059
|
+
ann if d == expected
|
1060
|
+
else
|
1061
|
+
fail "Don't know yet how to validate against #{where}"
|
1062
|
+
end
|
1063
|
+
when :b64u, :b64c, :b32, :h32, :hex, :hexlc, :hexuc
|
1064
|
+
ann if (
|
1065
|
+
String === d && (
|
1066
|
+
decoded = case conop
|
1067
|
+
when :b64u
|
1068
|
+
/=/ !~ d &&
|
1069
|
+
Base64.urlsafe_decode64(d)
|
1070
|
+
when :b64c
|
1071
|
+
Base64.strict_decode64(d)
|
1072
|
+
when :b32
|
1073
|
+
/=/ !~ d &&
|
1074
|
+
(Base32.table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567") &&
|
1075
|
+
Base32.decode(d)
|
1076
|
+
when :h32
|
1077
|
+
/=/ !~ d &&
|
1078
|
+
(Base32.table = "0123456789ABCDEFGHIJKLMNOPQRSTUV") &&
|
1079
|
+
Base32.decode(d)
|
1080
|
+
when :hex
|
1081
|
+
/\A[0-9a-fA-F]*\z/ =~ d && [d].pack("H*")
|
1082
|
+
when :hexuc
|
1083
|
+
/\A[0-9A-F]*\z/ =~ d && [d].pack("H*")
|
1084
|
+
when :hexlc
|
1085
|
+
/\A[0-9a-f]*\z/ =~ d && [d].pack("H*")
|
1086
|
+
else fail "Cannot happen"
|
1087
|
+
end
|
1088
|
+
) && validate1(decoded.b, control)
|
1089
|
+
)
|
974
1090
|
when :within
|
975
1091
|
if validate1(d, control)
|
976
1092
|
ann
|
@@ -1120,7 +1236,7 @@ module CDDL
|
|
1120
1236
|
s = n.to_s
|
1121
1237
|
if s[-1] == "'"
|
1122
1238
|
bsqual, *parts = s.split("'", -1)
|
1123
|
-
if parts[-1] != ""
|
1239
|
+
if parts[-1] != ""
|
1124
1240
|
warn "*** Problem decoding byte string #{s.inspect}"
|
1125
1241
|
end
|
1126
1242
|
bsval = parts[0...-1].join("'").gsub(/\\(.)/){$1}
|
@@ -1327,7 +1443,10 @@ module CDDL
|
|
1327
1443
|
RANGE_EXCLUDE_END = {".." => false, "..." => true}
|
1328
1444
|
SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp, :cbor, :cborseq, :within, :and,
|
1329
1445
|
:default, :lt, :le, :gt, :ge, :eq, :ne,
|
1330
|
-
:feature, :abnf, :abnfb, :det, :cat, :plus
|
1446
|
+
:feature, :abnf, :abnfb, :det, :cat, :plus,
|
1447
|
+
:json, :decimal, :join,
|
1448
|
+
:b64u, :b64c, :b32, :h32, :hex, :hexlc, :hexuc,
|
1449
|
+
]
|
1331
1450
|
|
1332
1451
|
def type1(n, canbegroup = false)
|
1333
1452
|
# puts "NVALUE #{n.value.inspect}"
|
data/test/test-cddl.rb
CHANGED
@@ -275,7 +275,7 @@ b = (
|
|
275
275
|
(x: int // y: int), z: int
|
276
276
|
)
|
277
277
|
HERE
|
278
|
-
|
278
|
+
refute parser.validate_for_test({}, false)
|
279
279
|
assert parser.validate_for_test({"x" => 2, "z" => 1})
|
280
280
|
assert parser.validate_for_test({"y" => 1, "z" => 2})
|
281
281
|
refute parser.validate_for_test({"z" => 1}, false)
|
@@ -293,7 +293,7 @@ b = ( z: int
|
|
293
293
|
(x: int // y: int)
|
294
294
|
)
|
295
295
|
HERE
|
296
|
-
|
296
|
+
refute parser.validate_for_test({}, false)
|
297
297
|
assert parser.validate_for_test({"x" => 2, "z" => 1})
|
298
298
|
assert parser.validate_for_test({"y" => 1, "z" => 2})
|
299
299
|
refute parser.validate_for_test({"z" => 1}, false)
|
data/test-data/b64c.cddl
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
a = text .b64c 'mnoabcd'
|
data/test-data/b64u.cddl
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
a = text .b64u 'mnoabcd'
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .b32 'mnoabcd'
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .h32 'mnoabcd'
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .decimal uint
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .decimal 4711
|
data/test-data/hex.cddl
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
a = text .hex 'mnoabcd'
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .hexlc 'mnoabcd'
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .hexuc 'mnoabcd'
|
data/test-data/join.cddl
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
a = text .join (["a", "b", "c"])
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .join (["a", "b", 3])
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .join (["a", "b", text])
|
data/test-data/json.cddl
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
a = text .json ([4, uint .size 1, {"a": "b"}])
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .json ([4, uint .size 2, {"a": "b"}])
|
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.10.2
|
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: 2023-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cbor-diag
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: base32
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.3'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.3'
|
97
111
|
description: A parser, generator, and validator for CDDL
|
98
112
|
email: cabo@tzi.org
|
99
113
|
executables:
|
@@ -119,7 +133,11 @@ files:
|
|
119
133
|
- test-data/abnf3.cddl
|
120
134
|
- test-data/ambig.cddl
|
121
135
|
- test-data/b.cddl
|
136
|
+
- test-data/b64c.cddl
|
137
|
+
- test-data/b64u.cddl
|
122
138
|
- test-data/badaddr.cddl
|
139
|
+
- test-data/base32.cddl
|
140
|
+
- test-data/base32hex.cddl
|
123
141
|
- test-data/basic_syntax_example.cddl
|
124
142
|
- test-data/bat.cddl
|
125
143
|
- test-data/bpv7.cddl
|
@@ -135,6 +153,8 @@ files:
|
|
135
153
|
- test-data/cose.cddl
|
136
154
|
- test-data/dcaf.cddl
|
137
155
|
- test-data/dcaf1.cddl
|
156
|
+
- test-data/decimal.cddl
|
157
|
+
- test-data/decimal2.cddl
|
138
158
|
- test-data/det1.cddl
|
139
159
|
- test-data/dotsize.cddl
|
140
160
|
- test-data/extractor-demo.cddl
|
@@ -148,6 +168,9 @@ files:
|
|
148
168
|
- test-data/grasp-09.cddl
|
149
169
|
- test-data/grasp-v1.cddl
|
150
170
|
- test-data/grasp-v2X.cddl
|
171
|
+
- test-data/hex.cddl
|
172
|
+
- test-data/hexlc.cddl
|
173
|
+
- test-data/hexuc.cddl
|
151
174
|
- test-data/homenet-de.cddl
|
152
175
|
- test-data/homenet-fe.cddl
|
153
176
|
- test-data/ifmap-base-2.0v17.cddl
|
@@ -157,6 +180,11 @@ files:
|
|
157
180
|
- test-data/jcr-ex.cddl
|
158
181
|
- test-data/jim-cut-2.cddl
|
159
182
|
- test-data/jim-cut.cddl
|
183
|
+
- test-data/join.cddl
|
184
|
+
- test-data/joini.cddl
|
185
|
+
- test-data/joinx.cddl
|
186
|
+
- test-data/json.cddl
|
187
|
+
- test-data/json2.cddl
|
160
188
|
- test-data/jsoniodef.cddl
|
161
189
|
- test-data/kevin5.cddl
|
162
190
|
- test-data/lint1.cddl
|
@@ -217,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
217
245
|
- !ruby/object:Gem::Version
|
218
246
|
version: '0'
|
219
247
|
requirements: []
|
220
|
-
rubygems_version: 3.
|
248
|
+
rubygems_version: 3.4.2
|
221
249
|
signing_key:
|
222
250
|
specification_version: 4
|
223
251
|
summary: CDDL generator and validator.
|