cddl 0.10.3 → 0.10.5

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: 9e60b48882767d7e76926473b44c79369891e4203326d4e31f5693a3819f391d
4
- data.tar.gz: 6ed2f45e7fa8468557e73c96a4dbfdd142d65fdebeeb362efeebec8007b7948f
3
+ metadata.gz: b3b0177b945919083ba2e0595570d098809b87839cb86e823dd54c62f225ad6b
4
+ data.tar.gz: 45302758ba30682f746f9b515cd293a5ac0883b2b126d6f74cd13a4911286e9e
5
5
  SHA512:
6
- metadata.gz: 2124a4fc046c3dc03d007ca949e4f9191497b359fe19fafe307ed2227c4b5654d909815575504e452add310dfc8487bfc13db94794d4b6c06a7af0bb2701e55f
7
- data.tar.gz: 8a223332d81282eb9ad651dad887579ceb7b44a01d05ccff6458e271ea999a3c5fad5f81c87a6a2ccf927307b3bb9c4e06075361b0f8fc8b02005926a3d9a5b7
6
+ metadata.gz: d613c36a0b4e7e1a18c68c1a2c5df9b0c46389936fdc063465bc8c130ba470b5c6467872fd55befa47972ea8cce8362f45a2164e2ee32c02539f29bd45fb1279
7
+ data.tar.gz: 6dca2e75e676eb00aba31e03671b2baf37568a2e4eb8fb0b506c8b02829efb88d6efda323891962e6ca3644be4added36482ee555bbf4d13565517c59cbaf397
data/cddl.gemspec CHANGED
@@ -1,21 +1,23 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'cddl'
3
- s.version = '0.10.3'
3
+ s.version = '0.10.5'
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
- s.add_dependency('abnc')
7
+ s.add_dependency('abnc', '~> 0.1.1')
8
8
  s.add_dependency('json_pure')
9
9
  s.add_dependency('abnftt')
10
10
  s.add_dependency('regexp-examples') # , '1.1.0')
11
11
  s.add_dependency('colorize')
12
12
  s.add_dependency('base32', '~> 0.3')
13
+ s.add_dependency('base45_lite', '~> 1.0')
14
+ s.add_dependency('scanf', '~> 1.0')
13
15
  s.files = `git ls-files`.split("\n").grep(/^[a-z]/)
14
16
  s.files = Dir['lib/**/*.rb'] + %w(cddl.gemspec) + Dir['data/**/*.abnf'] + Dir['data/**/*.cddl'] + Dir['test-data/**/*.cddl'] + Dir['test/**/*.rb']
15
17
  s.require_path = 'lib'
16
18
  s.executables = ['cddl']
17
19
  s.default_executable = 'cddl'
18
- s.required_ruby_version = '>= 2.0'
20
+ s.required_ruby_version = '>= 2.3'
19
21
  s.author = "Carsten Bormann"
20
22
  s.email = "cabo@tzi.org"
21
23
  s.homepage = "http://github.com/cabo/cddl"
data/data/cddl.abnf CHANGED
@@ -13,7 +13,7 @@ genericarg = "<" S type1 S *("," S type1 S ) ">"
13
13
  type = type1 S *("/" S type1 S)
14
14
 
15
15
  type1 = type2 [S (rangeop / annotator) S type2]
16
- / "#" "6" ["." uint] "(" S type S ")" ; note no space!
16
+ / "#" "6" ["." tagnumber] "(" S type S ")" ; note no space!
17
17
  / "#" DIGIT ["." uint] ; major/ai
18
18
  / "#" ; any
19
19
  / "~" S typename [genericarg]
@@ -22,6 +22,8 @@ type1 = type2 [S (rangeop / annotator) S type2]
22
22
  / "&" S "(" S group S ")"
23
23
  / "&" S groupname [genericarg]
24
24
 
25
+ tagnumber = uint / ("<" type ">")
26
+
25
27
  type2 = value
26
28
  / typename [genericarg]
27
29
  / "(" type ")"
data/lib/cddl.rb CHANGED
@@ -9,6 +9,7 @@ require 'colorize'
9
9
  require 'base64'
10
10
  require 'base32'
11
11
  require 'base45_lite'
12
+ require 'scanf'
12
13
 
13
14
  module CDDL
14
15
 
@@ -422,7 +423,11 @@ module CDDL
422
423
  when 3
423
424
  gen_word
424
425
  when 6
425
- CBOR::Tagged.new(where[2], generate1(where[3]))
426
+ tn = Integer === where[2] ? where[2] : generate1(where[2])
427
+ unless Integer === tn && tn >= 0
428
+ fail "Can't generate a tag number out of #{where[2]}"
429
+ end
430
+ CBOR::Tagged.new(tn, generate1(where[3]))
426
431
  when 7
427
432
  case where[2]
428
433
  when nil
@@ -551,8 +556,7 @@ module CDDL
551
556
  warn "HUH gen #{where.inspect} #{try.inspect}" unless try.nil?
552
557
  end
553
558
  end
554
- 32.times do
555
- content = generate1(target)
559
+ try_generate(target) do |content|
556
560
  if validate1(content, where)
557
561
  return content
558
562
  end
@@ -605,22 +609,22 @@ module CDDL
605
609
  content = Integer(generate1(control)).to_s
606
610
  content
607
611
  when :join
608
- content = generate1(control)
609
- unless Array === content &&
610
- content.all? {|x| String === x &&
611
- ((target == [:prim, 2] && x.encoding == Encoding::BINARY) ||
612
- (target == [:prim, 3] && x.encoding != Encoding::BINARY))}
613
- fail "Don't know yet how to generate #{where}"
612
+ try_generate(control) do |content|
613
+ if Array === content &&
614
+ content.all? {|x| String === x} &&
615
+ Set[content.map {|x| x.encoding}].size == 1
616
+ content = content.join
617
+ if validate1(content, target)
618
+ return content
619
+ end
620
+ end
614
621
  end
615
- content = content.join
616
- content
622
+ fail "Don't know yet how to generate #{where}"
617
623
  when :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
618
624
  :b45, :b32, :h32, :hex, :hexlc, :hexuc
619
- content = generate1(control)
620
- unless String === content
621
- fail "Don't know yet how to generate #{where}"
622
- end
623
- content = case conop
625
+ try_generate(control) do |content|
626
+ if String === content
627
+ content = case conop
624
628
  when :b64u, :"b64u-sloppy"
625
629
  Base64.urlsafe_encode64(content, padding: false)
626
630
  when :b64c, :"b64c-sloppy"
@@ -639,10 +643,32 @@ module CDDL
639
643
  content.unpack("H*")[0]
640
644
  else fail "Cannot happen"
641
645
  end
642
- content
646
+ if validate1(content, target)
647
+ return content
648
+ end
649
+ end
650
+ end
651
+ fail "Not smart enough to generate #{where}"
652
+ when :printf
653
+ try_generate(control) do |content|
654
+ if Array === content && content.size >= 1
655
+ fmt, *data = content
656
+ if String === fmt
657
+ begin
658
+ content = fmt % data
659
+ if validate1(content, target)
660
+ return content
661
+ end
662
+ rescue ArgumentError => e
663
+ # be verbose about mismatches here
664
+ @last_message << "\n** #{fmt.inspect} ArgumentError #{e}"
665
+ end
666
+ end
667
+ end
668
+ end
669
+ fail "Not smart enough to generate #{where}#{@last_message}"
643
670
  when :within, :and
644
- 32.times do
645
- content = generate1(target)
671
+ try_generate(target) do |content|
646
672
  if validate1(content, control)
647
673
  return content
648
674
  elsif conop == :within
@@ -670,6 +696,13 @@ module CDDL
670
696
  end
671
697
  end
672
698
 
699
+ def try_generate(target)
700
+ 32.times do
701
+ content = generate1(target)
702
+ yield content # should return if success
703
+ end
704
+ end
705
+
673
706
  VALUE_TYPE = {text: String, bytes: String, int: Integer, float: Float}
674
707
  SIMPLE_VALUE = {
675
708
  [:prim, 7, 20] => [true, false, :bool],
@@ -717,6 +750,19 @@ module CDDL
717
750
  }]
718
751
  end
719
752
 
753
+
754
+ def extract_arg0(t)
755
+ return [false] unless t[0] == :array
756
+ [true,
757
+ (el = t[1]
758
+ return [false] unless el[0..3] == [:member, 1, 1, nil]
759
+ ok, v, vt = extract_value(el[4])
760
+ return [false] unless ok
761
+ [v, vt]
762
+ ),
763
+ *t[2..-1]]
764
+ end
765
+
720
766
  def extract_feature(control, d)
721
767
  ok, v, vt = extract_value(control)
722
768
  if ok
@@ -1126,6 +1172,21 @@ module CDDL
1126
1172
  end
1127
1173
  ) && validate1(decoded.b, control)
1128
1174
  )
1175
+ when :printf
1176
+ ann if String === d && (
1177
+ ok, fmt, *v = extract_arg0(control)
1178
+ if ok && String == fmt[1]
1179
+ fmt = fmt[0]
1180
+ # warn "** ok #{ok.inspect} fmt #{fmt.inspect} v #{v.inspect}"
1181
+ decoded = d.scanf(fmt) # this is a bit too lenient, so let's do:
1182
+ encode_again = fmt % decoded
1183
+ if encode_again != d
1184
+ warn "** fmt #{fmt.inspect} d #{d.inspect} decoded #{decoded.inspect} encode_again #{encode_again.inspect}"
1185
+ else
1186
+ validate1(decoded, [:array, *v])
1187
+ end
1188
+ end
1189
+ )
1129
1190
  when :within
1130
1191
  if validate1(d, control)
1131
1192
  ann
@@ -1161,7 +1222,9 @@ module CDDL
1161
1222
  end
1162
1223
  d = CBOR::Tagged.new(t, d == 0 ? "".b : d.digits(256).reverse!.pack("C*"))
1163
1224
  end
1164
- CBOR::Tagged === d && d.tag == where[2] && validate1a(d.data, where[3])
1225
+ CBOR::Tagged === d && (
1226
+ Integer === where[2] ? d.tag == where[2] : validate1a(d.tag, where[2])
1227
+ ) && validate1a(d.data, where[3])
1165
1228
  when 7
1166
1229
  t, v = extract_value(where)
1167
1230
  if t
@@ -1488,6 +1551,7 @@ module CDDL
1488
1551
  :json, :decimal, :join,
1489
1552
  :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
1490
1553
  :b45, :b32, :h32, :hex, :hexlc, :hexuc,
1554
+ :printf,
1491
1555
  ]
1492
1556
 
1493
1557
  def type1(n, canbegroup = false)
@@ -1519,7 +1583,14 @@ module CDDL
1519
1583
  [:prim]
1520
1584
  when /\A#(\d+)/
1521
1585
  maj = $1.to_i
1522
- s = [:prim, maj, *n.children(:uint).map(&:to_s).map(&:to_i)]
1586
+ s = [:prim, maj]
1587
+ if tn = n.tagnumber
1588
+ if ui = tn.uint
1589
+ s << ui.to_s.to_i
1590
+ elsif tt = tn.type
1591
+ s << type(tt)
1592
+ end
1593
+ end
1523
1594
  if tagged_type = n.type
1524
1595
  s << type(tagged_type)
1525
1596
  end
@@ -0,0 +1,2 @@
1
+ a = text .printf (["%8d %06d", ~arr])
2
+ arr = [uint, uint]
@@ -0,0 +1 @@
1
+ my_label = text .printf (["0x%x: %a", 4711, 81.5])
@@ -0,0 +1,2 @@
1
+ my_alg_sha = hexlabel<4>
2
+ hexlabel<K> = text .printf (["0x%04x", K])
@@ -0,0 +1,2 @@
1
+ my_alg_sha = hexlabel<int>
2
+ hexlabel<K> = text .printf (["0x%04x", K])
@@ -0,0 +1,2 @@
1
+ any_alg = hexlabel<1..20>
2
+ hexlabel<K> = text .printf (["0x%04x", K])
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.10.3
4
+ version: 0.10.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carsten Bormann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-09 00:00:00.000000000 Z
11
+ date: 2024-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cbor-diag
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: abnc
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 0.1.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 0.1.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: json_pure
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,34 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: base45_lite
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: scanf
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.0'
111
139
  description: A parser, generator, and validator for CDDL
112
140
  email: cabo@tzi.org
113
141
  executables:
@@ -119,7 +147,6 @@ files:
119
147
  - cddl.gemspec
120
148
  - data/cddl.abnf
121
149
  - data/prelude.cddl
122
- - lib/base45_lite.rb
123
150
  - lib/cbor-pp-play.rb
124
151
  - lib/cbor-pp.rb
125
152
  - lib/cddl.rb
@@ -208,6 +235,11 @@ files:
208
235
  - test-data/oidbat.cddl
209
236
  - test-data/patch1.cddl
210
237
  - test-data/plus.cddl
238
+ - test-data/printf.cddl
239
+ - test-data/printf0.cddl
240
+ - test-data/printf1.cddl
241
+ - test-data/printf2.cddl
242
+ - test-data/printf3.cddl
211
243
  - test-data/reused_named_group.cddl
212
244
  - test-data/sasl.cddl
213
245
  - test-data/sequence.cddl
@@ -240,14 +272,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
240
272
  requirements:
241
273
  - - ">="
242
274
  - !ruby/object:Gem::Version
243
- version: '2.0'
275
+ version: '2.3'
244
276
  required_rubygems_version: !ruby/object:Gem::Requirement
245
277
  requirements:
246
278
  - - ">="
247
279
  - !ruby/object:Gem::Version
248
280
  version: '0'
249
281
  requirements: []
250
- rubygems_version: 3.4.6
282
+ rubygems_version: 3.4.10
251
283
  signing_key:
252
284
  specification_version: 4
253
285
  summary: CDDL generator and validator.
data/lib/base45_lite.rb DELETED
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright (c) 2022 Weihang Jian <https://tonytonyjan.net>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in all
13
- # copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- # SOFTWARE.
22
-
23
- # An implementation of draft-faltstrom-base45-10, see
24
- # https://datatracker.ietf.org/doc/draft-faltstrom-base45/
25
- module Base45Lite
26
- class Error < ::StandardError; end
27
- class OverflowError < Error; end
28
- class InvalidCharacterError < Error; end
29
- class ForbiddenLengthError < Error; end
30
-
31
- MAX_UINT18 = 2**16 - 1
32
- SQUARED_45 = 45**2
33
- MAPPING = [
34
- *'0'..'9',
35
- *'A'..'Z',
36
- ' ', '$', '%', '*', '+', '-', '.', '/', ':'
37
- ].map!.with_index { |x, i| [i, x] }.to_h.freeze
38
- REVERSE_MAPPING = MAPPING.invert.freeze
39
-
40
- def self.encode(input)
41
- sequence = []
42
- input.unpack('n*').map! do |uint16|
43
- i, c = uint16.divmod(45)
44
- i, d = i.divmod(45)
45
- _, e = i.divmod(45)
46
- sequence.push(c, d, e)
47
- end
48
- if input.bytesize.odd?
49
- i, c = input.getbyte(-1).divmod(45)
50
- _, d = i.divmod(45)
51
- sequence.push(c, d)
52
- end
53
- sequence.map!{ |n| MAPPING[n] }.join
54
- end
55
-
56
- def self.decode(input)
57
- input
58
- .chars.map! { |c| REVERSE_MAPPING[c] || raise(InvalidCharacterError) }
59
- .each_slice(3).map do |slice|
60
- c, d, e = slice
61
- raise ForbiddenLengthError if d.nil?
62
-
63
- sum = c + d * 45
64
- sum += e * SQUARED_45 if e
65
- raise OverflowError if sum > MAX_UINT18
66
-
67
- sum
68
- end
69
- .pack((input.length % 3).zero? ? 'n*' : "n#{input.length / 3}C")
70
- end
71
- end