cddl 0.10.3 → 0.10.5

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