cddl 0.10.3 → 0.11.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: 652f1e63847fbed19fceeca1ed0b695b25b5f8aa6d312b2bd17f21c0ac7c6549
4
+ data.tar.gz: d55f4a0bff69a37b1c6101b11eb003eb93c00df24ede1dded8d7be9844b4afb1
5
5
  SHA512:
6
- metadata.gz: 2124a4fc046c3dc03d007ca949e4f9191497b359fe19fafe307ed2227c4b5654d909815575504e452add310dfc8487bfc13db94794d4b6c06a7af0bb2701e55f
7
- data.tar.gz: 8a223332d81282eb9ad651dad887579ceb7b44a01d05ccff6458e271ea999a3c5fad5f81c87a6a2ccf927307b3bb9c4e06075361b0f8fc8b02005926a3d9a5b7
6
+ metadata.gz: 6622daf044d0f5a6d0ce4fe90ac57341526f7723aef0ce49e228edd2284711a44302ab0c3a1a28e3e156676db61afb4477a9b97b27269e1509034c41796ca8b9
7
+ data.tar.gz: 966fd633edc283925e0e4bbb5ca04cb40de60470044bbbd94e7df41fb05c185f59ff09ae4767d5dea2899491d3f82db50d3feb01a585fe03891d60f073e50557
data/bin/cddl CHANGED
@@ -7,10 +7,13 @@ require 'json'
7
7
 
8
8
  Encoding.default_external = "UTF-8" # wake up, smell the coffee
9
9
 
10
+ CDDL_VERSION = Gem.loaded_specs["cddl"].version rescue "unknown-version"
11
+
10
12
  EX_USAGE = 64
11
13
  EX_DATAERR = 65
12
14
 
13
15
  def usage
16
+ warn "cddl tool version #{CDDL_VERSION}"
14
17
  warn "Usage:"
15
18
  warn "#$0 spec.cddl generate [n]"
16
19
  warn "#$0 spec.cddl json-generate [n]"
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.11.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,8 @@ 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" ["." headnumber] "(" S type S ")" ; note no space!
17
+ / "#" "7" ["." headnumber] ; note no space!
17
18
  / "#" DIGIT ["." uint] ; major/ai
18
19
  / "#" ; any
19
20
  / "~" S typename [genericarg]
@@ -22,6 +23,8 @@ type1 = type2 [S (rangeop / annotator) S type2]
22
23
  / "&" S "(" S group S ")"
23
24
  / "&" S groupname [genericarg]
24
25
 
26
+ headnumber = uint / ("<" type ">")
27
+
25
28
  type2 = value
26
29
  / typename [genericarg]
27
30
  / "(" type ")"
data/lib/cddl.rb CHANGED
@@ -2,6 +2,7 @@ require 'abnc'
2
2
  require 'pp'
3
3
  require 'pathname'
4
4
  require 'cbor-pure' unless defined?(CBOR::Tagged)
5
+ require 'half'
5
6
  require 'cbor-deterministic'
6
7
  require 'regexp-examples'
7
8
  require 'abnftt'
@@ -9,6 +10,7 @@ require 'colorize'
9
10
  require 'base64'
10
11
  require 'base32'
11
12
  require 'base45_lite'
13
+ require 'scanf'
12
14
 
13
15
  module CDDL
14
16
 
@@ -422,9 +424,17 @@ module CDDL
422
424
  when 3
423
425
  gen_word
424
426
  when 6
425
- CBOR::Tagged.new(where[2], generate1(where[3]))
427
+ tn = Integer === where[2] ? where[2] : generate1(where[2])
428
+ unless Integer === tn && tn >= 0
429
+ fail "Can't generate a tag number out of #{where[2]}"
430
+ end
431
+ CBOR::Tagged.new(tn, generate1(where[3]))
426
432
  when 7
427
- case where[2]
433
+ w2 = where[2]
434
+ if Array === w2
435
+ w2 = generate1(w2)
436
+ end
437
+ case w2
428
438
  when nil
429
439
  Math::PI
430
440
  when 20
@@ -433,10 +443,22 @@ module CDDL
433
443
  true
434
444
  when 22
435
445
  nil
436
- when 23
437
- :undefined
438
- when 25, 26, 27
439
- rand()
446
+ when 0..19, 23, 32..255
447
+ CBOR::Simple.new(w2)
448
+ when 25
449
+ while !(hs = Half.encode_from_single_bytes([rand()].pack("g")))
450
+ end
451
+ Half.decode(hs)
452
+ when 26
453
+ while (a = [rand()].pack("g").unpack("g").first).to_cbor.size != 5
454
+ end
455
+ a
456
+ when 27
457
+ while (a = rand()).to_cbor.size != 9
458
+ end
459
+ a
460
+ else
461
+ fail "Can't generate prim #7.#{where[2].inspect}" # XXX retry array generate
440
462
  end
441
463
  else
442
464
  fail "Can't generate prim #{where[1]}"
@@ -551,8 +573,7 @@ module CDDL
551
573
  warn "HUH gen #{where.inspect} #{try.inspect}" unless try.nil?
552
574
  end
553
575
  end
554
- 32.times do
555
- content = generate1(target)
576
+ try_generate(target) do |content|
556
577
  if validate1(content, where)
557
578
  return content
558
579
  end
@@ -605,22 +626,22 @@ module CDDL
605
626
  content = Integer(generate1(control)).to_s
606
627
  content
607
628
  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}"
629
+ try_generate(control) do |content|
630
+ if Array === content &&
631
+ content.all? {|x| String === x} &&
632
+ Set[content.map {|x| x.encoding}].size == 1
633
+ content = content.join
634
+ if validate1(content, target)
635
+ return content
636
+ end
637
+ end
614
638
  end
615
- content = content.join
616
- content
639
+ fail "Don't know yet how to generate #{where}"
617
640
  when :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
618
641
  :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
642
+ try_generate(control) do |content|
643
+ if String === content
644
+ content = case conop
624
645
  when :b64u, :"b64u-sloppy"
625
646
  Base64.urlsafe_encode64(content, padding: false)
626
647
  when :b64c, :"b64c-sloppy"
@@ -639,10 +660,32 @@ module CDDL
639
660
  content.unpack("H*")[0]
640
661
  else fail "Cannot happen"
641
662
  end
642
- content
663
+ if validate1(content, target)
664
+ return content
665
+ end
666
+ end
667
+ end
668
+ fail "Not smart enough to generate #{where}"
669
+ when :printf
670
+ try_generate(control) do |content|
671
+ if Array === content && content.size >= 1
672
+ fmt, *data = content
673
+ if String === fmt
674
+ begin
675
+ content = fmt % data
676
+ if validate1(content, target)
677
+ return content
678
+ end
679
+ rescue ArgumentError => e
680
+ # be verbose about mismatches here
681
+ @last_message << "\n** #{fmt.inspect} ArgumentError #{e}"
682
+ end
683
+ end
684
+ end
685
+ end
686
+ fail "Not smart enough to generate #{where}#{@last_message}"
643
687
  when :within, :and
644
- 32.times do
645
- content = generate1(target)
688
+ try_generate(target) do |content|
646
689
  if validate1(content, control)
647
690
  return content
648
691
  elsif conop == :within
@@ -670,22 +713,41 @@ module CDDL
670
713
  end
671
714
  end
672
715
 
716
+ def try_generate(target)
717
+ 32.times do
718
+ content = generate1(target)
719
+ yield content # should return if success
720
+ end
721
+ end
722
+
673
723
  VALUE_TYPE = {text: String, bytes: String, int: Integer, float: Float}
674
724
  SIMPLE_VALUE = {
675
725
  [:prim, 7, 20] => [true, false, :bool],
676
726
  [:prim, 7, 21] => [true, true, :bool],
677
727
  [:prim, 7, 22] => [true, nil, :nil],
678
- [:prim, 7, 23] => [true, :undefined, :undefined],
679
728
  }
729
+ SIMPLE_VALUE_SIMPLE = Set[23] + (0..19) + (32..255)
680
730
 
681
731
  def extract_value(t) # []
682
732
  if vt = VALUE_TYPE[t[0]]
683
733
  [true, t[1], vt]
684
- elsif v = SIMPLE_VALUE[t]
685
- v
734
+ elsif t[0] == :prim && t[1] == 7
735
+ case t2 = t[2]
736
+ when Integer
737
+ when Array
738
+ a, b, c = extract_value(t2)
739
+ if a && c == Integer
740
+ t2 = b
741
+ end
742
+ end
743
+ if v = SIMPLE_VALUE[[:prim, 7, t2]]
744
+ v
745
+ elsif SIMPLE_VALUE_SIMPLE === t2
746
+ [true, CBOR::Simple.new(t2), :simple]
747
+ end
686
748
  elsif t[0] == :anno
687
749
  _, conop, target, control = t
688
- # warn ["EXV0", conop, target, control].inspect
750
+ warn ["EXV0", conop, target, control].inspect if ENV["CDDL_TRACE"]
689
751
  if conop == :cat || conop == :plus || conop == :det
690
752
  ok1, v1, vt1 = extract_value(target)
691
753
  ok2, v2, vt2 = extract_value(control)
@@ -717,6 +779,19 @@ module CDDL
717
779
  }]
718
780
  end
719
781
 
782
+
783
+ def extract_arg0(t)
784
+ return [false] unless t[0] == :array
785
+ [true,
786
+ (el = t[1]
787
+ return [false] unless el[0..3] == [:member, 1, 1, nil]
788
+ ok, v, vt = extract_value(el[4])
789
+ return [false] unless ok
790
+ [v, vt]
791
+ ),
792
+ *t[2..-1]]
793
+ end
794
+
720
795
  def extract_feature(control, d)
721
796
  ok, v, vt = extract_value(control)
722
797
  if ok
@@ -905,6 +980,19 @@ module CDDL
905
980
  }
906
981
  end
907
982
 
983
+ def validate1a_ignore_encoding(d, where)
984
+ if String === d
985
+ validate1a(d.force_encoding(Encoding::BINARY), where) or (
986
+ text = d.force_encoding(Encoding::UTF_8).scrub {
987
+ fail "can't use bytes as text"
988
+ } rescue :NOT_A_TEXT_STRING
989
+ validate1a(text, where)
990
+ )
991
+ else
992
+ validate1a(d, where)
993
+ end
994
+ end
995
+
908
996
  def validate1a(d, where)
909
997
  if ann = validate1(d, where)
910
998
  here = [d, where]
@@ -917,6 +1005,7 @@ module CDDL
917
1005
  end
918
1006
 
919
1007
  OPERATORS = {lt: :<, le: :<=, gt: :>, ge: :>=, eq: :==, ne: :!=}
1008
+ FLOAT_AI_FROM_SIZE = {3 => 25, 5 => 26, 9 => 27}
920
1009
 
921
1010
  def validate1(d, where)
922
1011
  if ENV["CDDL_TRACE"]
@@ -963,7 +1052,7 @@ module CDDL
963
1052
  if conop == :cat || conop == :plus || conop == :det
964
1053
  ok1, v1, vt1 = extract_value(target)
965
1054
  ok2, v2, vt2 = extract_value(control)
966
- # warn ["ANNO0", ok1, v1, vt1, ok2, v2, vt2, d].inspect
1055
+ warn ["ANNO0", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
967
1056
  if ok1 && ok2
968
1057
  v2 = Integer(v2) if vt1 == Integer
969
1058
  if conop == :det
@@ -972,6 +1061,30 @@ module CDDL
972
1061
  end
973
1062
  # warn ["ANNO", ok1, v1, vt1, ok2, v2, vt2, d].inspect
974
1063
  [] if d == v1 + v2 # XXX Focus ArgumentError
1064
+ elsif conop == :cat && String === d
1065
+ warn ["CAT-L", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
1066
+ if ok1 && vt1 == String
1067
+ # d and lhs (v1) need to agree in encoding
1068
+ if d.encoding == v1.encoding
1069
+ if d[0...v1.length] == v1
1070
+ d2 = d[v1.length..-1]
1071
+ warn ["CAT-L1", d2, d2.encoding, control].inspect if ENV["CDDL_TRACE"]
1072
+ validate1a_ignore_encoding(d2, control)
1073
+ end
1074
+ end
1075
+ elsif ok2 && vt2 == String
1076
+ warn ["CAT-R", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
1077
+ if d[-v2.length..-1] == v2
1078
+ d1 = d[0...-v2.length]
1079
+ validate1a(d1, control)
1080
+ end
1081
+ end
1082
+ elsif conop == :plus && Integer === d
1083
+ if ok1 && vt1 == Integer
1084
+ validate1a(d - Integer(v1), control)
1085
+ elsif ok2 && vt2 == Integer
1086
+ validate1a(d - Integer(v2), target)
1087
+ end
975
1088
  end
976
1089
  elsif ann = validate1a(d, target)
977
1090
  case conop
@@ -1081,14 +1194,75 @@ module CDDL
1081
1194
  end
1082
1195
  )
1083
1196
  when :join
1084
- ok, *v = extract_array(control)
1085
- # warn "@@@JJJ@@@ #{ok.inspect} #{v.inspect}"
1086
- if ok
1087
- expected = v.map {|ve|
1088
- fail "Not a string in #{where}" unless String === ve[0]
1089
- ve[0]
1090
- }.join
1091
- ann if d == expected
1197
+ t = control
1198
+ v = if t[0] == :array
1199
+ t[1..-1].map { |el|
1200
+ if el[0..2] == [:member, 1, 1]
1201
+ ok, v, vt = extract_value(el[4])
1202
+ if ok
1203
+ [true, v, vt]
1204
+ else
1205
+ [false, el[4]]
1206
+ end
1207
+ end
1208
+ }
1209
+ end
1210
+ warn "@@@JOIN@@@ #{v.inspect}" if ENV["CDDL_TRACE"]
1211
+ ok = true
1212
+ if v
1213
+ ix = 0
1214
+ rest = d.dup
1215
+ while ix < v.length
1216
+ if left = v[ix]
1217
+ if left[0] # match constant value first
1218
+ fail "Not a string for #{left.inspect} in #{where}" unless String == left[2]
1219
+ want = left[1]
1220
+ have = rest[0...left[1].length]
1221
+ if want == have
1222
+ rest[0...left[1].length] = ''
1223
+ ix += 1
1224
+ next
1225
+ else
1226
+ fail ".join: want #{want.inspect}, have #{have.inspect}"
1227
+ end
1228
+ else
1229
+ ix += 1
1230
+ if ix == v.length # match remaining
1231
+ warn "@@@JOIN ok in #{ok.inspect} rest #{rest.inspect}" if ENV["CDDL_TRACE"]
1232
+ ok &&= validate1(rest, left[1])
1233
+ warn "@@@JOIN ok out #{ok.inspect}" if ENV["CDDL_TRACE"]
1234
+ # more diag
1235
+ rest = ''
1236
+ next
1237
+ else
1238
+ if mid = v[ix]
1239
+ if mid[0] # have constant value to split over
1240
+ fail "Not a string for #{mid} in #{where}" unless String == mid[2]
1241
+ rest1, rest2 = rest.split(mid[1], 2)
1242
+ if rest2
1243
+ warn "@@@JOIN ok in #{ok.inspect} rest1 #{rest1.inspect}" if ENV["CDDL_TRACE"]
1244
+ ok &&= validate1(rest1, left[1])
1245
+ warn "@@@JOIN ok out #{ok.inspect}" if ENV["CDDL_TRACE"]
1246
+ rest = rest2
1247
+ ix += 1
1248
+ next
1249
+ else
1250
+ fail "Can't find #{mid[1].inspect} in #{rest.inspect}"
1251
+ end
1252
+ else
1253
+ fail "Cannot validate consecutive non-constant members of .join in #{where}"
1254
+ end
1255
+ else
1256
+ fail "Cannot handle .join over #{t[ix+1]} in #{where}"
1257
+ end
1258
+ end
1259
+ end
1260
+ else
1261
+ fail "Cannot handle .join over #{t[ix+1]} in #{where}"
1262
+ end
1263
+ end
1264
+ fail "Can't match #{rest.inspect} for .join in #{where}" if rest != ''
1265
+ ann if ok
1092
1266
  else
1093
1267
  fail "Don't know yet how to validate against #{where}"
1094
1268
  end
@@ -1097,7 +1271,7 @@ module CDDL
1097
1271
  String === d && (
1098
1272
  decoded = case conop
1099
1273
  when :b64u
1100
- /=/ !~ d &&
1274
+ /[+\/=]/ !~ d &&
1101
1275
  Base64.urlsafe_decode64(d)
1102
1276
  when :"b64u-sloppy"
1103
1277
  /[-_=]/ !~ d &&
@@ -1126,6 +1300,21 @@ module CDDL
1126
1300
  end
1127
1301
  ) && validate1(decoded.b, control)
1128
1302
  )
1303
+ when :printf
1304
+ ann if String === d && (
1305
+ ok, fmt, *v = extract_arg0(control)
1306
+ if ok && String == fmt[1]
1307
+ fmt = fmt[0]
1308
+ # warn "** ok #{ok.inspect} fmt #{fmt.inspect} v #{v.inspect}"
1309
+ decoded = d.scanf(fmt) # this is a bit too lenient, so let's do:
1310
+ encode_again = fmt % decoded
1311
+ if encode_again != d
1312
+ warn "** fmt #{fmt.inspect} d #{d.inspect} decoded #{decoded.inspect} encode_again #{encode_again.inspect}"
1313
+ else
1314
+ validate1(decoded, [:array, *v])
1315
+ end
1316
+ end
1317
+ )
1129
1318
  when :within
1130
1319
  if validate1(d, control)
1131
1320
  ann
@@ -1161,20 +1350,35 @@ module CDDL
1161
1350
  end
1162
1351
  d = CBOR::Tagged.new(t, d == 0 ? "".b : d.digits(256).reverse!.pack("C*"))
1163
1352
  end
1164
- CBOR::Tagged === d && d.tag == where[2] && validate1a(d.data, where[3])
1353
+ CBOR::Tagged === d && (
1354
+ Integer === where[2] ? d.tag == where[2] : validate1a(d.tag, where[2])
1355
+ ) && validate1a(d.data, where[3])
1165
1356
  when 7
1166
1357
  t, v = extract_value(where)
1167
1358
  if t
1168
1359
  v.eql? d
1169
1360
  else
1170
- case where[2]
1361
+ case w2 = where[2]
1171
1362
  when nil
1172
- # XXX
1173
- fail
1363
+ Float === d || CBOR::Simple === d || [false, true, nil].include?(d)
1364
+ when Array
1365
+ headnum = case d
1366
+ when Float
1367
+ FLOAT_AI_FROM_SIZE[d.to_cbor.size]
1368
+ when false
1369
+ 20
1370
+ when true
1371
+ 21
1372
+ when nil
1373
+ 22
1374
+ when CBOR::Simple
1375
+ d.value
1376
+ end
1377
+ validate1a(headnum, w2)
1174
1378
  when 25, 26, 27
1175
- Float === d
1379
+ Float === d && FLOAT_AI_FROM_SIZE[d.to_cbor.size] == w2
1176
1380
  else
1177
- fail
1381
+ fail [:val7, d, where].inspect
1178
1382
  end
1179
1383
  end
1180
1384
  else
@@ -1488,6 +1692,7 @@ module CDDL
1488
1692
  :json, :decimal, :join,
1489
1693
  :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
1490
1694
  :b45, :b32, :h32, :hex, :hexlc, :hexuc,
1695
+ :printf,
1491
1696
  ]
1492
1697
 
1493
1698
  def type1(n, canbegroup = false)
@@ -1520,6 +1725,13 @@ module CDDL
1520
1725
  when /\A#(\d+)/
1521
1726
  maj = $1.to_i
1522
1727
  s = [:prim, maj, *n.children(:uint).map(&:to_s).map(&:to_i)]
1728
+ if tn = n.headnumber
1729
+ if ui = tn.uint
1730
+ s << ui.to_s.to_i
1731
+ elsif tt = tn.type
1732
+ s << type(tt)
1733
+ end
1734
+ end
1523
1735
  if tagged_type = n.type
1524
1736
  s << type(tagged_type)
1525
1737
  end
@@ -0,0 +1,10 @@
1
+ a = text .b64u bytes
2
+
3
+ ;;gp 10
4
+
5
+ ;;vp "AAAA"
6
+ ;;vp "AAA-"
7
+ ;;vp "AAA_"
8
+ ;;vp "AAA+"
9
+ ;;vp "AAA/"
10
+ ;;vp "AAA="
@@ -1,2 +1,4 @@
1
1
  foo = text .regexp myregexp
2
2
  myregexp = "A" .cat "B"
3
+
4
+ ;;gp 10
@@ -0,0 +1,8 @@
1
+ a1 = '' .cat a2
2
+ a2 = text .b64u ain
3
+ ; a = "e30" .b64u ain
4
+ ain = '{}'
5
+
6
+ ;;gp 3
7
+ ;;vp 'e30'
8
+ ;;vp "e30"
@@ -0,0 +1,3 @@
1
+ a = b<13..15>
2
+ b<T> = #7.<32 .plus T>
3
+ ; cddl dotplus1.cddl gp 10
@@ -0,0 +1,3 @@
1
+ a = d<17..19>
2
+ d<T> = #7.<T .plus 32>
3
+ ; cddl dotplus.cddl gp 10
@@ -0,0 +1,3 @@
1
+ a = d<17..19>
2
+ d<T> = 32.5 .plus T
3
+ ; cddl dotplus4.cddl gp 10
@@ -0,0 +1,3 @@
1
+ a = d<17..19>
2
+ d<T> = T .plus 32.5
3
+ ; cddl dotplus4.cddl gp 10
@@ -0,0 +1,14 @@
1
+ terminal-color = &basecolors
2
+ basecolors = (
3
+ black: 0, red: 1, green: 2, yellow: 3,
4
+ blue: 4, magenta: 5, cyan: 6, white: 7,
5
+ reserved: (8..255) .feature "extension"
6
+ )
7
+ ; extended-color = &(
8
+ ; basecolors,
9
+ ; orange: 8, pink: 9, purple: 10, brown: 11,
10
+ ; )
11
+
12
+ ;;gp 10
13
+ ;;vp 42
14
+ ;;vp 433
@@ -0,0 +1,12 @@
1
+ terminal-color = $terminal-color / text .feature "extension"
2
+ $terminal-color /= &basecolors
3
+ basecolors = (
4
+ black: "black", red: "red", green: "green",
5
+ )
6
+
7
+ pastelcolors = ( pink: "pink", mauve: "mauve", peach: "peach", lavender: "lavender" )
8
+ $terminal-color /= &pastelcolors
9
+
10
+ ;;gp 10
11
+ ;;vp "florp"
12
+ ;;vp "lavender"
@@ -0,0 +1,15 @@
1
+ ; JWT-JWS = text .join ([
2
+ ; b64u<jwt-headers>, ".",
3
+ ; b64u<jwt-payload>, ".",
4
+ ; b64u<jwt-signature>])
5
+ ; ; a = jwt-headers
6
+ ; ; a = b64u<"abc"> ; fails
7
+ ; ; a = b64u<'abc'> ; succeeds
8
+ ; b64u<B> = text .b64u B
9
+ jwt-headers = '' .cat jwt-headers1
10
+ jwt-headers1 = text .json jwt-headermap
11
+ jwt-headermap = { * text => any } ; simplified
12
+ jwt-payload = bytes
13
+ jwt-signature = bytes
14
+
15
+ ;;gp 10
@@ -0,0 +1,15 @@
1
+ JWT-JWS = text .join ([
2
+ b64u<jwt-headers>, ".",
3
+ b64u<jwt-payload>, ".",
4
+ b64u<jwt-signature>])
5
+ ; a = jwt-headers
6
+ ; a = b64u<"abc"> ; fails
7
+ ; a = b64u<'abc'> ; succeeds
8
+ b64u<B> = text .b64u B
9
+ jwt-headers = '' .cat jwt-headers1
10
+ jwt-headers1 = text .json jwt-headermap
11
+ jwt-headermap = { * text => any } ; simplified
12
+ jwt-payload = bytes
13
+ jwt-signature = bytes
14
+
15
+ ;;gp 10
@@ -0,0 +1,7 @@
1
+ start = [a, e, b, c, d]
2
+ a = false
3
+ e = undefined
4
+ b = float32
5
+ ; c = #7.32
6
+ c = #6.<12>(3)
7
+ d = #6.13(4)
@@ -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.11.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-04-15 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
@@ -136,6 +163,7 @@ files:
136
163
  - test-data/b.cddl
137
164
  - test-data/b64c-sloppy.cddl
138
165
  - test-data/b64c.cddl
166
+ - test-data/b64u-strict.cddl
139
167
  - test-data/b64u.cddl
140
168
  - test-data/badaddr.cddl
141
169
  - test-data/base32.cddl
@@ -146,6 +174,7 @@ files:
146
174
  - test-data/bpv7a.cddl
147
175
  - test-data/bpv7b.cddl
148
176
  - test-data/cat-re.cddl
177
+ - test-data/catb64.cddl
149
178
  - test-data/cdni-ct.cddl
150
179
  - test-data/complex-occ.cddl
151
180
  - test-data/coral.cddl
@@ -158,7 +187,13 @@ files:
158
187
  - test-data/decimal.cddl
159
188
  - test-data/decimal2.cddl
160
189
  - test-data/det1.cddl
190
+ - test-data/dotplus1.cddl
191
+ - test-data/dotplus2.cddl
192
+ - test-data/dotplus3.cddl
193
+ - test-data/dotplus4.cddl
161
194
  - test-data/dotsize.cddl
195
+ - test-data/enum.cddl
196
+ - test-data/enum1.cddl
162
197
  - test-data/extractor-demo.cddl
163
198
  - test-data/feat1.cddl
164
199
  - test-data/feature-controller.cddl
@@ -186,8 +221,10 @@ files:
186
221
  - test-data/joini.cddl
187
222
  - test-data/joinx.cddl
188
223
  - test-data/json.cddl
224
+ - test-data/json1.cddl
189
225
  - test-data/json2.cddl
190
226
  - test-data/jsoniodef.cddl
227
+ - test-data/jwt.cddl
191
228
  - test-data/kevin5.cddl
192
229
  - test-data/lint1.cddl
193
230
  - test-data/map-group.cddl
@@ -208,6 +245,12 @@ files:
208
245
  - test-data/oidbat.cddl
209
246
  - test-data/patch1.cddl
210
247
  - test-data/plus.cddl
248
+ - test-data/prim.cddl
249
+ - test-data/printf.cddl
250
+ - test-data/printf0.cddl
251
+ - test-data/printf1.cddl
252
+ - test-data/printf2.cddl
253
+ - test-data/printf3.cddl
211
254
  - test-data/reused_named_group.cddl
212
255
  - test-data/sasl.cddl
213
256
  - test-data/sequence.cddl
@@ -240,14 +283,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
240
283
  requirements:
241
284
  - - ">="
242
285
  - !ruby/object:Gem::Version
243
- version: '2.0'
286
+ version: '2.3'
244
287
  required_rubygems_version: !ruby/object:Gem::Requirement
245
288
  requirements:
246
289
  - - ">="
247
290
  - !ruby/object:Gem::Version
248
291
  version: '0'
249
292
  requirements: []
250
- rubygems_version: 3.4.6
293
+ rubygems_version: 3.5.4
251
294
  signing_key:
252
295
  specification_version: 4
253
296
  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