cddlc 0.3.5 → 0.4.1

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
  SHA256:
3
- metadata.gz: 6d01061fd86124e6e68aae0a7ef043d23c9a2211992f9421e9333c50d8a870ee
4
- data.tar.gz: 7efe567eeca90c756dac4354791583cae6da812b05eaf4074dfb953f71d09adb
3
+ metadata.gz: 0cf26993bc0f0556758da6e5567849461b1b6e2779c02e7a1bf8be89f3466747
4
+ data.tar.gz: 6d3a7a675a37815fc23fe4cbbe786698fc996cb6b7bb9cbfec5572bb74d50520
5
5
  SHA512:
6
- metadata.gz: c051e4c6c4e319e223dc8126512ffe8c7368b985735c8b15b34ac3ae5dad183f7f80f74e3a4b90f1679877472c8c5a0968f38d73994fc4e3dbb8669a39938c09
7
- data.tar.gz: 29fce82dbdfd0bf5e14184b8445d3281a648fdd3f1fb982e37020317c23b94100449d21fed9a609a2f041fdc4a035c7842e23f861b5730480f9a828963122fef
6
+ metadata.gz: cbbbd25e3cbd37740b856de841a844ce644ef5efc9a97e9966714810db7fb3b070821774a7da17a0d8e20c2047c591de0579d16ba5a12bf8b399578275862a21
7
+ data.tar.gz: 2fb8b0946855f67c1e6a17f13837cf6484bdc69e01e5f353c8815ceb9ca09f1fc42a5ac02c8449d79973ccac7b205b845716c48314668da9f76bbff986a63b16
data/bin/cddlc CHANGED
@@ -44,7 +44,7 @@ require 'ostruct'
44
44
  $options = OpenStruct.new
45
45
  begin
46
46
  op = OptionParser.new do |opts|
47
- opts.banner = "Usage: cddlc.rb [options] [-e cddl | file.cddl... | -]"
47
+ opts.banner = "Usage: cddlc [options] [-e cddl | file.cddl... | -]"
48
48
 
49
49
  opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
50
50
  $options.verbose = v
@@ -64,7 +64,23 @@ begin
64
64
  opts.on("-2", "--[no-]cddl2", "Perform some CDDL 2.0 processing") do |v|
65
65
  $options.cddl2 = v
66
66
  end
67
- opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :const, :enum, :cddl], "Target format") do |v|
67
+ opts.on("-c", "--cbor-validate=FILE", "Validate CBOR file against CDDL grammar") do |v|
68
+ $options.validate = v
69
+ $options.source_format = :cbor
70
+ end
71
+ opts.on("-j", "--json-validate=FILE", "Validate JSON file against CDDL grammar") do |v|
72
+ $options.validate = v
73
+ $options.source_format = :json
74
+ end
75
+ opts.on("-d", "--diag-validate=FILE", "Validate EDN file against CDDL grammar") do |v|
76
+ $options.validate = v
77
+ $options.source_format = :diag
78
+ end
79
+ opts.on("--test", "Validate embedded EDN against CDDL grammar") do |v|
80
+ $options.validate = v
81
+ $options.source_format = :embedded
82
+ end
83
+ opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :const, :enum, :cddl, :diag, :edn, :cbor], "Target format") do |v|
68
84
  $options.target = v
69
85
  end
70
86
  opts.on("-sRULE", "--start=RULE", String, "Start rule name") do |v|
@@ -73,6 +89,9 @@ begin
73
89
  opts.on("-eCDDL", "CDDL model on command line") do |v|
74
90
  $options.model = v
75
91
  end
92
+ opts.on("--[no-]prelude", "Add (default)/do not add prelude") do |v|
93
+ $options.prelude = v
94
+ end
76
95
  opts.on("-iIMPORT", "--import=IMPORT", String, "Import [namespace=]reference") do |v|
77
96
  $options.import ||= []
78
97
  $options.import << v
@@ -83,11 +102,13 @@ begin
83
102
  end
84
103
  end
85
104
  op.parse!
86
- rescue Exception => e
105
+ rescue StandardError => e
87
106
  warn e
88
107
  exit 1
89
108
  end
90
109
 
110
+ $options.prelude = true if $options.validate # XXX
111
+
91
112
  if ($options.expand_generics || $options.flattening) && !$options.rules
92
113
  warn "** can't expand or flatten in tree; adding -r flag"
93
114
  $options.rules = true
@@ -131,8 +152,16 @@ else
131
152
  cddl_file << ARGF.read
132
153
  end
133
154
 
155
+ if $options.validate
156
+ $options.expand_generics = true # for now
157
+ $options.rules = true
158
+ # manually select -f/--flattening if desired
159
+ end
134
160
 
135
161
  cddl = CDDL.from_cddl(cddl_file)
162
+ if $options.prelude
163
+ cddl.rules.merge! cddl.prelude.rules
164
+ end
136
165
  result = if $options.rules
137
166
  if $options.expand_generics
138
167
  require_relative "../lib/processor/cddl-expander.rb"
@@ -150,6 +179,77 @@ result = if $options.rules
150
179
 
151
180
  warn "** can't note undefined for target != cddl" if $options.note_undefined && $options.target != :cddl
152
181
 
182
+ embedded = $options.source_format == :embedded
183
+
184
+ def parse_diag(data)
185
+ require 'cbor-diag-parser'
186
+ parser = CBOR_DIAGParser.new
187
+ if result = parser.parse(data)
188
+ result.to_rb
189
+ else
190
+ warn "*** can't parse #{data}"
191
+ warn "*** #{parser.failure_reason}"
192
+ exit 1
193
+ end
194
+ end
195
+
196
+ if fn = $options.validate
197
+ require "cbor-pure"
198
+ require "validator/validate"
199
+ data = fn == "-" ? STDIN.read : File.binread(fn) unless embedded
200
+ items = case $options.source_format
201
+ in :cbor
202
+ [[CBOR.decode(data), true]]
203
+ in :json
204
+ [[JSON.load(data), true]]
205
+ in :diag # XXX move to EDN, take diag2x options
206
+ [[parse_diag(data), true]]
207
+ in :embedded
208
+ input = cddl_file.lines(chomp: true)
209
+ tests = []
210
+ input.each do |l|
211
+ case l
212
+ when /\A;;([-+:]p?)\s*(.*)\z/
213
+ disc = $1
214
+ payload = $2
215
+ if disc == ':'
216
+ if t = tests[-1]
217
+ t[1] << payload
218
+ else
219
+ warn "*** : to what? #{l}"
220
+ end
221
+ else
222
+ tests << [disc, [payload]]
223
+ end
224
+ end
225
+ end
226
+ tests.map {|disc, lines|
227
+ [parse_diag(lines.join("\n")), disc == "+"]
228
+ }
229
+ else
230
+ fail $options.source_format
231
+ end
232
+ items.each do |item, expected|
233
+ warn [:ITEM, item, expected].inspect if CDDL::CDDLC_DEBUG
234
+ r = cddl.validate(item)
235
+ if r[0]
236
+ # TODO: build annotated output here!
237
+ warn r.inspect
238
+ if !expected
239
+ warn "*** should NOT have validated"
240
+ exit 1
241
+ end
242
+ else
243
+ puts r.to_yaml
244
+ if expected
245
+ warn "*** should have validated" if embedded
246
+ exit 1
247
+ end
248
+ end
249
+ end
250
+ exit
251
+ end
252
+
153
253
  case $options.target
154
254
  when :basic, nil
155
255
  pp result
@@ -189,5 +289,5 @@ when :cddl
189
289
  end
190
290
  puts cddl.to_s
191
291
  else
192
- warn ["Unknown target format: ", $options.target].inspect
292
+ warn ["Unknown target format for CDDL output: ", $options.target].inspect
193
293
  end
data/cddlc.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cddlc"
3
- s.version = "0.3.5"
3
+ s.version = "0.4.1"
4
4
  s.summary = "CDDL (Concise Data Definition Language) converters and miscellaneous tools"
5
5
  s.description = %q{cddlc implements converters and miscellaneous tools for CDDL, RFC 8610}
6
6
  s.author = "Carsten Bormann"
data/data/rfc9360.cddl ADDED
@@ -0,0 +1,2 @@
1
+ COSE_X509 = bstr / [ 2*certs: bstr ]
2
+ COSE_CertHash = [ hashAlg: (int / tstr), hashValue: bstr ]
data/data/rfc9431.cddl ADDED
@@ -0,0 +1,5 @@
1
+ AIF-MQTT = AIF-Generic<mqtt-topic-filter, mqtt-permissions>
2
+ AIF-Generic<Toid, Tperm> = [* [Toid, Tperm]]
3
+ mqtt-topic-filter = tstr ; as per Section 4.7 of MQTT v5.0
4
+ mqtt-permissions = [+permission]
5
+ permission = "pub"/"sub"
data/data/rfc9526.cddl ADDED
@@ -0,0 +1,12 @@
1
+ hna-configuration = {
2
+ "registered_domain" : tstr,
3
+ "dm" : tstr,
4
+ ? "dm_transport" : "DoT"
5
+ ? "dm_port" : uint,
6
+ ? "dm_acl" : hna-acl / [ +hna-acl ]
7
+ ? "hna_auth_method": hna-auth-method
8
+ ? "hna_certificate": tstr
9
+ }
10
+
11
+ hna-acl = tstr
12
+ hna-auth-method /= "certificate"
data/data/rfc9528.cddl ADDED
@@ -0,0 +1,59 @@
1
+ suites = [ 2* int ] / int
2
+
3
+ ead = (
4
+ ead_label : int,
5
+ ? ead_value : bstr,
6
+ )
7
+
8
+ EAD_1 = (1* ead)
9
+ EAD_2 = (1* ead)
10
+ EAD_3 = (1* ead)
11
+ EAD_4 = (1* ead)
12
+
13
+ message_1 = (
14
+ METHOD : int,
15
+ SUITES_I : suites,
16
+ G_X : bstr,
17
+ C_I : bstr / -24..23,
18
+ ? EAD_1,
19
+ )
20
+
21
+ message_2 = (
22
+ G_Y_CIPHERTEXT_2 : bstr,
23
+ )
24
+
25
+ PLAINTEXT_2 = (
26
+ C_R : bstr / -24..23,
27
+ ID_CRED_R : header_map / bstr / -24..23,
28
+ Signature_or_MAC_2 : bstr,
29
+ ? EAD_2,
30
+ )
31
+
32
+ message_3 = (
33
+ CIPHERTEXT_3 : bstr,
34
+ )
35
+
36
+ PLAINTEXT_3 = (
37
+ ID_CRED_I : header_map / bstr / -24..23,
38
+ Signature_or_MAC_3 : bstr,
39
+ ? EAD_3,
40
+ )
41
+
42
+ message_4 = (
43
+ CIPHERTEXT_4 : bstr,
44
+ )
45
+
46
+ PLAINTEXT_4 = (
47
+ ? EAD_4,
48
+ )
49
+
50
+ error = (
51
+ ERR_CODE : int,
52
+ ERR_INFO : any,
53
+ )
54
+
55
+ info = (
56
+ info_label : int,
57
+ context : bstr,
58
+ length : uint,
59
+ )
@@ -0,0 +1,3 @@
1
+ ace-groupcomm-error = {
2
+ &(error-id: 0) => int
3
+ }
@@ -0,0 +1,20 @@
1
+ ;# include rfc9237
2
+
3
+ gname = tstr
4
+
5
+ permissions = uint .bits roles
6
+
7
+ roles = &(
8
+ Requester: 1,
9
+ Responder: 2,
10
+ Monitor: 3,
11
+ Verifier: 4
12
+ )
13
+
14
+ scope_entries = AIF-Generic<gname, permissions>
15
+
16
+ scope = bstr .cbor scope_entries
17
+
18
+ extended_scope = #6.<TAG_FOR_THIS_SEMANTICS>(scope)
19
+
20
+ TAG_FOR_THIS_SEMANTICS = uint
@@ -0,0 +1,13 @@
1
+ gname = tstr
2
+
3
+ role = tstr
4
+
5
+ scope_entry = [ gname , ? ( role / [ 2*role ] ) ]
6
+
7
+ scope_entries = [ * scope_entry ]
8
+
9
+ scope = bstr .cbor scope_entries
10
+
11
+ extended_scope = #6.<TAG_FOR_THIS_SEMANTICS>(scope)
12
+
13
+ TAG_FOR_THIS_SEMANTICS = uint
@@ -0,0 +1,16 @@
1
+ ;# include rfc9237
2
+
3
+ gname = tstr
4
+
5
+ permissions = uint .bits roles
6
+
7
+ roles = &(
8
+ Requester: 1,
9
+ Responder: 2,
10
+ Monitor: 3,
11
+ Verifier: 4
12
+ )
13
+
14
+ scope_entries = AIF-Generic<gname, permissions>
15
+
16
+ scope = bstr .cbor scope_entries
@@ -0,0 +1,9 @@
1
+ gname = tstr
2
+
3
+ role = tstr
4
+
5
+ scope_entry = [gname, ? ( role / [2* role] )]
6
+
7
+ scope_entries = [* scope_entry]
8
+
9
+ scope = bstr .cbor scope_entries
@@ -0,0 +1,10 @@
1
+ inclusion_flag = bool
2
+
3
+ role = tstr
4
+ comb_role = [2* role]
5
+ role_filter = [* ( role / comb_role )]
6
+
7
+ id = bstr
8
+ id_filter = [* id]
9
+
10
+ get_creds = null / [inclusion_flag, role_filter, id_filter]
@@ -0,0 +1,18 @@
1
+ sign_info = sign_info_req / sign_info_resp
2
+
3
+ sign_info_req = null ; in the Token Transfer
4
+ ; Request to the KDC
5
+
6
+ sign_info_resp = [+ sign_info_entry] ; in the Token Transfer
7
+ ; Response from the KDC
8
+
9
+ sign_info_entry =
10
+ [
11
+ id: gname / [+ gname],
12
+ sign_alg: int / tstr,
13
+ sign_parameters: [any],
14
+ sign_key_parameters: [+ parameter: any],
15
+ cred_fmt: int / null
16
+ ]
17
+
18
+ gname = tstr
@@ -0,0 +1,10 @@
1
+ sign_info_entry =
2
+ [
3
+ id : gname / [+ gname],
4
+ sign_alg : int / tstr,
5
+ sign_parameters : [* alg_capab : any],
6
+ * sign_capab : [* capab : any],
7
+ cred_fmt : int / null
8
+ ]
9
+
10
+ gname = tstr
data/data/rfc9597.cddl ADDED
@@ -0,0 +1,5 @@
1
+ CWT-Claims = {
2
+ * Claim-Label => any
3
+ }
4
+
5
+ Claim-Label = int / text
@@ -0,0 +1,343 @@
1
+ # requires for CBOR
2
+
3
+ require 'cbor-pure' unless defined?(CBOR::Tagged)
4
+ require 'half'
5
+
6
+ # requires for control operators
7
+ require 'cbor-deterministic'
8
+ require 'regexp-examples'
9
+ require 'abnftt'
10
+ require 'base64'
11
+ require 'base32'
12
+ require 'base45_lite'
13
+ require 'scanf'
14
+
15
+ # Hmm:
16
+ #!/usr/bin/env RUBY_THREAD_VM_STACK_SIZE=5000000 ruby
17
+
18
+
19
+ class CDDL
20
+
21
+ # DATA_DIR = Pathname.new(__FILE__).split[0] + '../../data'
22
+ # PRELUDE = File.read("#{DATA_DIR}/prelude.cddl") -> #prelude -- parsed
23
+
24
+ MANY = Float::INFINITY
25
+
26
+ MAX_RECURSE = 128 # XXX
27
+
28
+ CDDLC_INVENT = ENV["CDDLC_INVENT"]
29
+ CDDLC_DEBUG = ENV["CDDLC_DEBUG"]
30
+
31
+ # library:
32
+
33
+ def remove_indentation(s)
34
+ l = s.lines
35
+ indent = l.grep(/\S/).map {|l| l[/^\s*/].size}.min
36
+ l.map {|l| l.sub(/^ {0,#{indent}}/, "")}.join
37
+ end
38
+
39
+ # [success, item, info, sublist (a/m/t)]
40
+ # [true, item, annos, sub-results [kv]]
41
+ # [false, item, error, sub-results [kv]]
42
+ # separate bad specs (always fails) from non-matching specs
43
+
44
+ def validate(item)
45
+ @rootrule ||= @rules.keys.first
46
+ # boxify item
47
+ validate1(item, ["name", @rootrule])
48
+ end
49
+
50
+ def numval(s)
51
+ Integer(s) rescue Float(s)
52
+ end
53
+
54
+ def validate1(item, where)
55
+ pp [:VALIDATE1, item, where].inspect if CDDLC_DEBUG
56
+ anno = nil
57
+ case where
58
+ in ["name", name]
59
+ # invent or error out if !rules[name]
60
+ rhs = rules[name]
61
+ unless rhs
62
+ if s = CDDLC_INVENT
63
+ s = "_" if s == ""
64
+ rules[name] = rhs = ["text", "#{s}-#{name}"]
65
+ else
66
+ return [false, item, {undefined: [name]}, []]
67
+ end
68
+ end
69
+ r = validate1(item, rhs)
70
+ case r
71
+ in [true, item, _annos, _sub]
72
+ [true, item, {name: name}, [r]]
73
+ in [false, item, error, _sub]
74
+ [false, item, {nomatch: [name, error]}, [r]]
75
+ else
76
+ fail [:MALFORMED_R, r, item, rhs].inspect
77
+ end
78
+ in ["number", num]
79
+ val = numval(num)
80
+ if !(item.eql? val) # TODO: 0.0 vs. -0.0
81
+ [false, item, {wrongnumber: [item, val, num]}, []]
82
+ else
83
+ [true, item, {}, []]
84
+ end
85
+ in ["text", val]
86
+ if !(item.eql? val) # check text vs. bytes
87
+ [false, item, {wrongtext: [item, val]}, []]
88
+ else
89
+ [true, item, {}, []]
90
+ end
91
+ in ["bytes", val]
92
+ # XXX Need to fix abnftt to yield correct value
93
+ if !(item.eql? val) # check text vs. bytes
94
+ [false, item, {wrongtext: [item, val]}, []]
95
+ else
96
+ [true, item, {}, []]
97
+ end
98
+ in ["tcho", *choices]
99
+ nomatches = []
100
+ choices.each do |where|
101
+ r = validate1(item, where)
102
+ if r[0]
103
+ pp [:TCHO, item, where, r] if CDDLC_DEBUG
104
+ return r
105
+ end
106
+ nomatches << r
107
+ end
108
+ [false, item, nomatches, [r]]
109
+ in ["prim"]
110
+ [true, item, {}, []]
111
+ in ["prim", 0]
112
+ simple_result(Integer === item && item >= 0 && item <= 0xffffffffffffffff,
113
+ item, where, :wrongnumber)
114
+ in ["prim", 1]
115
+ simple_result(Integer === item && item < 0 && item >= -0x10000000000000000,
116
+ item, where, :wrongnumber)
117
+ in ["prim", 2]
118
+ simple_result(String === item && item.encoding == Encoding::BINARY,
119
+ item, where, :wrongbytes)
120
+ in ["prim", 3]
121
+ simple_result(String === item && item.encoding != Encoding::BINARY, # cheat
122
+ item, where, :wrongtext)
123
+ in ["prim", 6, *wh2]
124
+ warn [:WH2, wh2].inspect
125
+ d = if Integer === item
126
+ biggify(item)
127
+ else
128
+ item
129
+ end
130
+ # XXX validate tag against headnum if present
131
+ if CBOR::Tagged === d
132
+ r0 = if Integer === wh2[0]
133
+ simple_result(d.tag == wh2[0], d.tag, wh2[0], :wrongtag)
134
+ else validate1(d.tag, wh2[0])
135
+ end
136
+ r1 = validate1(d.data, wh2[1])
137
+ if r0[0] && r1[0]
138
+ [true, item, {}, []] # XXX add diagnosics
139
+ else
140
+ [false, item, {wrongtag: [item, where]}, [r0, r1]]
141
+ end
142
+ else
143
+ [false, item, {not_a_tag: [item, where]}, []]
144
+ end
145
+ in ["prim", 7, *ai]
146
+ # t, v = extract_value(where) -- if t -- v.eql? d --
147
+ headnum = case item
148
+ when Float
149
+ FLOAT_AI_FROM_SIZE[item.to_cbor.size]
150
+ when CBOR::Simple
151
+ item.value
152
+ when false
153
+ 20
154
+ when true
155
+ 21
156
+ when nil
157
+ 22
158
+ end
159
+ if Array === ai[0] # CDDL for head number
160
+ validate1(headnum, ai[0])
161
+ else
162
+ simple_result(
163
+ ai[0].nil? ||
164
+ ai[0] == headnum,
165
+ item, where, :wrong7)
166
+ end
167
+ in ["op", op, lhs, rhs]
168
+ case op
169
+ in ".." | "..."
170
+ rex = RANGE_EXCLUDE_END[op]
171
+ lhss, lhsv, lhst = extract_value(lhs)
172
+ rhss, rhsv, rhst = extract_value(rhs)
173
+ if !lhss || !rhss
174
+ [false, item, {UNSPECIFIC_RANGE: [op, lhs, rhs]}, []]
175
+ elsif lhst != rhst
176
+ [false, item, {INCOHERENT_RANGE: [op, lhs, rhs]}, []]
177
+ else
178
+ st = scalar_type(item)
179
+ if lhst != st
180
+ [false, item, {rangetype: [op, lhs, rhs]}, []]
181
+ else
182
+ rg = Range.new(lhsv, rhsv, rex)
183
+ simple_result(
184
+ rg.include?(item),
185
+ item, where, :out_of_range)
186
+ end
187
+ end
188
+ in ".cat" | ".det"
189
+ lhss, lhsv, lhst = extract_value(lhs)
190
+ rhss, rhsv, rhst = extract_value(rhs)
191
+ if !lhss || !rhss
192
+ [false, item, {UNSPECIFIC_STRING_CAT: [op, lhs, rhs]}, []]
193
+ elsif [lhsv, rhsv].any? {!(String === _1)}
194
+ [false, item, {NON_STRING_CAT: [op, lhs, rhs]}, []]
195
+ else
196
+ if op == ".det"
197
+ lhsv = remove_indentation(lhsv)
198
+ rhsv = remove_indentation(rhsv)
199
+ end
200
+ case [lhst, rhst]
201
+ in [:text, :text] | [:bytes, :bytes]
202
+ result = lhsv + rhsv
203
+ in [:bytes, :text]
204
+ result = (lhsv + rhsv.b).b
205
+ in [:text, :bytes]
206
+ result = lhsv + rhsv.force_encoding(Encoding::UTF_8)
207
+ unless result.valid_encoding?
208
+ return [false, item, {text_encoding_error: [lhst, lhsv, rhst, rhsv]}, []]
209
+ end
210
+ end
211
+ simple_result(scalar_type(item) == lhst && item == result,
212
+ item, where, :no_match)
213
+ end
214
+ in ".plus"
215
+ lhss, lhsv, lhst = extract_value(lhs)
216
+ rhss, rhsv, rhst = extract_value(rhs)
217
+ if !lhss || !rhss
218
+ [false, item, {UNSPECIFIC_PLUS: [op, lhs, rhs]}, []]
219
+ elsif [lhsv, rhsv].any? {!(Numeric === _1)}
220
+ [false, item, {NON_NUMERIC_PLUS: [op, lhs, rhs]}, []]
221
+ else
222
+ if lhst == :int
223
+ result = lhsv + Integer(rhsv)
224
+ elsif lhst == :float
225
+ result = rbv + rhsv
226
+ end
227
+ simple_result(item.eql?(result),
228
+ item, where, :no_match)
229
+ end
230
+ in ".size"
231
+ anno = :lhs
232
+ r = validate1(item, lhs)
233
+ if r[0]
234
+ case item
235
+ when Integer
236
+ ok, v, vt = extract_value(rhs)
237
+ if ok && vt == :int
238
+ simple_result((item >> (8*v)) == 0,
239
+ item, where, :toolarge)
240
+ end
241
+ when String
242
+ validate1(item.bytesize, rhs)
243
+ else
244
+ false
245
+ end
246
+ end
247
+ in ".bits"
248
+ r = validate1(item, lhs)
249
+ if r[0]
250
+ if String === item
251
+ simple_result(
252
+ item.each_byte.with_index.all? { |b, i|
253
+ bit = i << 3
254
+ 8.times.all? { |nb|
255
+ b[nb] == 0 || validate1(bit+nb, rhs)[0] # collect
256
+ }
257
+ },
258
+ item, where, :unwanted_bit_set)
259
+ elsif Integer === item
260
+ if item >= 0
261
+ ok = true
262
+ i = 0
263
+ d = item
264
+ while ok && d > 0
265
+ if d.odd?
266
+ ok &&= validate1(i, rhs)[0] # collect
267
+ end
268
+ d >>= 1; i += 1
269
+ end
270
+ simple_result(ok,
271
+ item, where, :unwanted_bit_set)
272
+ end
273
+ end
274
+ end
275
+ else
276
+ fail [:CONTROL_UNIMPLEMENTED, op, item, where].inspect
277
+ end
278
+ else
279
+ warn [:UNIMPLEMENTED, item, where].inspect
280
+ exit 1
281
+ end || [false, item, {anno => [item, where]}, []]
282
+ end
283
+ end
284
+
285
+ def scalar_type(item)
286
+ case item
287
+ in NilClass
288
+ :null
289
+ in FalseClass | TrueClass
290
+ :bool
291
+ in Integer
292
+ :int
293
+ in Float
294
+ :float
295
+ in String if item.encoding == Encoding::BINARY
296
+ :bytes
297
+ in String
298
+ :text
299
+ else
300
+ nil
301
+ end
302
+ end
303
+
304
+ FLOAT_AI_FROM_SIZE = {3 => 25, 5 => 26, 9 => 27}
305
+ SIMPLE_VALUE = {
306
+ [:prim, 7, 20] => [true, false, :bool],
307
+ [:prim, 7, 21] => [true, true, :bool],
308
+ [:prim, 7, 22] => [true, nil, :nil],
309
+ }
310
+ SIMPLE_VALUE_SIMPLE = Set[23] + (0..19) + (32..255)
311
+ RANGE_EXCLUDE_END = {".." => false, "..." => true}
312
+
313
+ def simple_result(check, item, where, anno)
314
+ if check
315
+ [true, item, {}, []]
316
+ else
317
+ [false, item, {anno => [item, where]}, []]
318
+ end
319
+ end
320
+
321
+ def biggify(d) # stand-in for real stand-ins
322
+ t = 2 # assuming only 2/3 match an Integer
323
+ if d < 0
324
+ d = ~d
325
+ t = 3
326
+ end
327
+ CBOR::Tagged.new(t, d == 0 ? "".b : d.digits(256).reverse!.pack("C*"))
328
+ end
329
+
330
+ def extract_value(wh) # XXX complete: .cat/plus/det
331
+ case wh
332
+ in x if a = SIMPLE_VALUE[x]
333
+ SIMPLE_VALUE[x]
334
+ in ["number", num]
335
+ [true, Integer(num), :int] rescue [true, Float(num), :float]
336
+ in ["text", val]
337
+ [true, val, :text]
338
+ in ["bytes", val] # TODO
339
+ [true, val, :bytes]
340
+ else
341
+ [false]
342
+ end
343
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cddlc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carsten Bormann
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-01-09 00:00:00.000000000 Z
10
+ date: 2025-02-10 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -83,12 +82,25 @@ files:
83
82
  - data/rfc9290.cddl
84
83
  - data/rfc9321.cddl
85
84
  - data/rfc9338.cddl
85
+ - data/rfc9360.cddl
86
86
  - data/rfc9393-concise-swid-tag.cddl
87
87
  - data/rfc9393-sign.cddl
88
88
  - data/rfc9393-sign1.cddl
89
89
  - data/rfc9393-tags.cddl
90
90
  - data/rfc9393.cddl
91
+ - data/rfc9431.cddl
92
+ - data/rfc9526.cddl
93
+ - data/rfc9528.cddl
91
94
  - data/rfc9581.cddl
95
+ - data/rfc9594-error-handling.cddl
96
+ - data/rfc9594-example-extended-scope-aif.cddl
97
+ - data/rfc9594-example-extended-scope-text.cddl
98
+ - data/rfc9594-example-scope-aif.cddl
99
+ - data/rfc9594-example-scope-text.cddl
100
+ - data/rfc9594-get_creds.cddl
101
+ - data/rfc9594-sign_info-parameter.cddl
102
+ - data/rfc9594-sign_info_entry-with-a-gene.cddl
103
+ - data/rfc9597.cddl
92
104
  - lib/cddlc.rb
93
105
  - lib/parser/cddl-util.rb
94
106
  - lib/parser/cddlgrammar.rb
@@ -97,12 +109,12 @@ files:
97
109
  - lib/processor/cddl-flattening.rb
98
110
  - lib/processor/cddl-undefined.rb
99
111
  - lib/processor/cddl-visitor.rb
112
+ - lib/validator/validate.rb
100
113
  - lib/writer/cddl-writer.rb
101
114
  homepage: http://github.com/cabo/cddlc
102
115
  licenses:
103
116
  - MIT
104
117
  metadata: {}
105
- post_install_message:
106
118
  rdoc_options: []
107
119
  require_paths:
108
120
  - lib
@@ -117,8 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
129
  - !ruby/object:Gem::Version
118
130
  version: '0'
119
131
  requirements: []
120
- rubygems_version: 3.5.14
121
- signing_key:
132
+ rubygems_version: 3.6.2
122
133
  specification_version: 4
123
134
  summary: CDDL (Concise Data Definition Language) converters and miscellaneous tools
124
135
  test_files: []