cddlc 0.3.5 → 0.4.1

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 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: []