cddl 0.10.3 → 0.12.14

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: a4b5bfb31fd9b7fcf4cf66a1d0f2a76550c9682215c486d99a03997bab1ae30b
4
+ data.tar.gz: 97f11378fb18576f115ffb8cbd668fe9e14e33e91e4aac01d874c69e206f2fbd
5
5
  SHA512:
6
- metadata.gz: 2124a4fc046c3dc03d007ca949e4f9191497b359fe19fafe307ed2227c4b5654d909815575504e452add310dfc8487bfc13db94794d4b6c06a7af0bb2701e55f
7
- data.tar.gz: 8a223332d81282eb9ad651dad887579ceb7b44a01d05ccff6458e271ea999a3c5fad5f81c87a6a2ccf927307b3bb9c4e06075361b0f8fc8b02005926a3d9a5b7
6
+ metadata.gz: 623f3945c3fff7c04dd2a4e1c77879d585d347092c87b54d5ead6b8fb3ed3c5ab68a58ae67b7f3f936437c8bc9f92dea6f8597509ba8913fbc5e2e47f43d398a
7
+ data.tar.gz: a04d3f282b0d42182f63dd66988fece8fb0ab7ddb4e159b2f8213705503cff0a97b622a172096b881dc4fe70f16bdcc48a51fa035413bc55421bb5e15d1bcda3
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]"
@@ -19,6 +22,13 @@ def usage
19
22
  exit EX_USAGE
20
23
  end
21
24
 
25
+ def utfify(s)
26
+ s.force_encoding(Encoding::UTF_8).scrub { |c|
27
+ warn "*** replaced invalid UTF-8 byte sequence #{c.inspect} by U+FFFD REPLACEMENT CHARACTER"
28
+ 0xFFFD.chr(Encoding::UTF_8)
29
+ }
30
+ end
31
+
22
32
  def read_arg(arg, remember_fn = true)
23
33
  if arg == "-"
24
34
  $fn = "(stdin)" if remember_fn
@@ -31,7 +41,7 @@ def read_arg(arg, remember_fn = true)
31
41
  end
32
42
 
33
43
  def parser
34
- @parser ||= CDDL::Parser.new(read_arg(ARGV[0], false))
44
+ @parser ||= CDDL::Parser.new(utfify(read_arg(ARGV[0], false)))
35
45
  end
36
46
 
37
47
  def my_pp(v)
@@ -96,7 +106,12 @@ begin
96
106
  instance = if $sequence
97
107
  CBOR.decode("\x9f".b << instance.b << "\xff".b)
98
108
  else
99
- CBOR.decode(instance.b) rescue JSON.load(instance)
109
+ begin
110
+ CBOR.decode(instance.b)
111
+ rescue => e
112
+ warn e.inspect if verbose
113
+ JSON.load(utfify(instance))
114
+ end
100
115
  end
101
116
  instance = instance.cbor_clone if $annotate && ENV["EXPERIMENTAL_ANNOTATE"]
102
117
  warn "#{fn}:" if verbose
@@ -104,6 +119,7 @@ begin
104
119
  # my_pp ann
105
120
  instance.cbor_add_annotations_from(ann) rescue nil
106
121
  my_diag(instance) if $annotate
122
+ warn "ann: #{!!ann}" if verbose
107
123
  unless ann
108
124
  retcode = 1
109
125
  end
data/cddl.gemspec CHANGED
@@ -1,24 +1,25 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'cddl'
3
- s.version = '0.10.3'
3
+ s.version = '0.12.14'
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
- s.add_dependency('regexp-examples') # , '1.1.0')
10
+ s.add_dependency('regexp-examples', '~> 1.5.1') # , '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
- s.default_executable = 'cddl'
18
- s.required_ruby_version = '>= 2.0'
19
+ s.required_ruby_version = '>= 2.3'
19
20
  s.author = "Carsten Bormann"
20
21
  s.email = "cabo@tzi.org"
21
- s.homepage = "http://github.com/cabo/cddl"
22
+ s.homepage = "https://www.rfc-editor.org/rfc/rfc8610#appendix-F"
22
23
  s.license = 'MIT'
23
24
  end
24
25
 
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 ")"
@@ -38,7 +41,7 @@ grpent = [occur S] [memberkey S] type optcom
38
41
  / [occur S] groupname [genericarg] optcom ; preempted by above
39
42
  / [occur S] "(" S group S ")" optcom
40
43
 
41
- memberkey = type1 S "=>"
44
+ memberkey = type1 S ["^" S] "=>"
42
45
  / bareword S ":"
43
46
  / value S ":"
44
47
 
@@ -62,32 +65,45 @@ value = number
62
65
  int = ["-"] uint
63
66
 
64
67
  ; This is a float if it has fraction or exponent; int otherwise
65
- number = int ["." fraction] ["e" exponent ]
68
+ number = hexfloat / (int ["." fraction] ["e" exponent ])
69
+ hexfloat = ["-"] "0x" 1*HEXDIG ["." 1*HEXDIG] "p" exponent
66
70
  fraction = 1*DIGIT
67
- exponent = int
71
+ exponent = ["+"/"-"] 1*DIGIT
68
72
 
69
73
  text = %x22 *SCHAR %x22
70
- SCHAR = %x20-21 / %x23-7E / SESC
71
- SESC = "\" %x20-7E
74
+ SCHAR = %x20-21 / %x23-5B / %x5D-7E / NONASCII / SESC
75
+
76
+ SESC = "\" ( %x22 / "/" / "\" / ; \" \/ \\
77
+ %x62 / %x66 / %x6E / %x72 / %x74 / ; \b \f \n \r \t
78
+ (%x75 hexchar) ) ; \uXXXX
79
+
80
+ hexchar = "{" (1*"0" [ hexscalar ] / hexscalar) "}" /
81
+ non-surrogate / (high-surrogate "\" %x75 low-surrogate)
82
+ non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") HEXDIG HEXDIG HEXDIG) /
83
+ ("D" %x30-37 HEXDIG HEXDIG)
84
+ high-surrogate = "D" ("8"/"9"/"A"/"B") HEXDIG HEXDIG
85
+ low-surrogate = "D" ("C"/"D"/"E"/"F") HEXDIG HEXDIG
86
+ hexscalar = "10" HEXDIG HEXDIG HEXDIG HEXDIG / HEXDIG1 HEXDIG HEXDIG HEXDIG HEXDIG
87
+ / non-surrogate / HEXDIG [HEXDIG [HEXDIG]]
72
88
 
73
89
  bytes = [bsqual] %x27 *BCHAR %x27
74
- BCHAR = %x20-26 / %x28-5B / %x5D-7E / SESC / CRLF
75
- bsqual = %x68 ; "h"
76
- / %x62.36.34 ; "b64"
90
+ BCHAR = %x20-26 / %x28-5B / %x5D-7E / NONASCII / SESC / "\'" / CRLF
91
+ bsqual = "h" / "b64"
77
92
 
78
93
  id = EALPHA *(*("-" / ".") (EALPHA / DIGIT))
79
94
  ALPHA = %x41-5A / %x61-7A
80
- EALPHA = %x41-5A / %x61-7A / "@" / "_" / "$"
95
+ EALPHA = ALPHA / "@" / "_" / "$"
81
96
  DIGIT = %x30-39
82
97
  DIGIT1 = %x31-39
83
98
  HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
99
+ HEXDIG1 = DIGIT1 / "A" / "B" / "C" / "D" / "E" / "F"
84
100
  BINDIG = %x30-31
85
101
 
86
102
  S = *WS
87
103
  WS = SP / NL
88
104
  SP = %x20
89
105
  NL = COMMENT / CRLF
90
- COMMENT = ";" *(SP / VCHAR) CRLF
91
- VCHAR = %x21-7E
106
+ COMMENT = ";" *PCHAR CRLF
107
+ PCHAR = %x20-7E / NONASCII
108
+ NONASCII = %xA0-D7FF / %xE000-10FFFD
92
109
  CRLF = %x0A / %x0D.0A
93
-
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
 
@@ -38,6 +40,7 @@ module CDDL
38
40
  [{}, {}]
39
41
  end
40
42
 
43
+ CDDL_UNUSED_OK = ENV["CDDL_UNUSED_OK"]
41
44
 
42
45
  class BackTrack < Exception; end
43
46
 
@@ -59,7 +62,7 @@ module CDDL
59
62
  if upto - presult < 100
60
63
  part2 = source_text[presult...upto]
61
64
  else
62
- part2 = source_text[presult, 50] + "......." + source_text[upto-50, 50]
65
+ part2 = source_text[presult, 50] + "......." + (source_text[upto-50, 50] || "")
63
66
  end
64
67
  warn "*** Look for syntax problems around the #{
65
68
  "%%%".colorize(background: :light_yellow)} markers:\n#{
@@ -116,6 +119,16 @@ module CDDL
116
119
  r.compact
117
120
  end
118
121
 
122
+ def longest_initial_match(old, now)
123
+ md = /\A(.*)(.*)\n\1(.*)\z/.match([old,now].join("\n"))
124
+ md[1..3]
125
+ end
126
+
127
+ def diff_message(old, now)
128
+ c, l, r = longest_initial_match(old, now)
129
+ "-- common: >#{c}< -- old: >#{l}< -- new: >#{r}<"
130
+ end
131
+
119
132
  def cname(s)
120
133
  s.to_s.gsub(/-/, "_")
121
134
  end
@@ -202,7 +215,8 @@ module CDDL
202
215
  ids = g.children(:id).map(&:to_s)
203
216
  # puts ["ids", ids].inspect
204
217
  if b = @generics[n]
205
- fail "Duplicate generics definition #{n} as #{rule_ast} (was #{b})"
218
+ fail "Duplicate generics definition #{n} #{
219
+ diff_message(strip_nodes(b[0]).inspect, strip_nodes(rule_ast).inspect)}"
206
220
  end
207
221
  @generics[n] = [rule_ast, ids]
208
222
  else
@@ -214,7 +228,7 @@ module CDDL
214
228
  if a == b
215
229
  warn "*** Warning: Identical redefinition of #{n} as #{a}"
216
230
  else
217
- fail "Duplicate rule definition #{n} as #{b} (was #{a})"
231
+ fail "Duplicate rule definition #{n} #{diff_message(b, a)}"
218
232
  end
219
233
  end
220
234
  @rules[n] = rule_ast
@@ -246,7 +260,7 @@ module CDDL
246
260
  r_process("used_in_cddl_prelude", @rules["used_in_cddl_prelude"])
247
261
  @rules.each do |n, r|
248
262
  # r_process(n, r) # debug only loop
249
- warn "*** Unused rule #{n}" unless @stage1[n]
263
+ warn "*** Unused rule #{n}" unless @stage1[n] || CDDL_UNUSED_OK
250
264
  end
251
265
  if result[0] == :grpent
252
266
  warn "Group at top -- first rule must be a type!"
@@ -300,6 +314,12 @@ module CDDL
300
314
  abnfb: Encoding::BINARY
301
315
  }
302
316
 
317
+ def myfrand(exp)
318
+ exprange = 1 << exp
319
+ expoffset= exprange >> 1
320
+ (rand(2)*2-1) * rand() * 2.0**(rand(exprange)-expoffset)
321
+ end
322
+
303
323
  def generate
304
324
  @recursion = 0
305
325
  generate1(rules)
@@ -422,9 +442,17 @@ module CDDL
422
442
  when 3
423
443
  gen_word
424
444
  when 6
425
- CBOR::Tagged.new(where[2], generate1(where[3]))
445
+ tn = Integer === where[2] ? where[2] : generate1(where[2])
446
+ unless Integer === tn && tn >= 0
447
+ fail "Can't generate a tag number out of #{where[2]}"
448
+ end
449
+ CBOR::Tagged.new(tn, generate1(where[3]))
426
450
  when 7
427
- case where[2]
451
+ w2 = where[2]
452
+ if Array === w2
453
+ w2 = generate1(w2)
454
+ end
455
+ case w2
428
456
  when nil
429
457
  Math::PI
430
458
  when 20
@@ -433,10 +461,22 @@ module CDDL
433
461
  true
434
462
  when 22
435
463
  nil
436
- when 23
437
- :undefined
438
- when 25, 26, 27
439
- rand()
464
+ when 0..19, 23, 32..255
465
+ CBOR::Simple.new(w2)
466
+ when 25
467
+ while !(hs = Half.encode_from_single_bytes([myfrand(5)].pack("g")))
468
+ end
469
+ Half.decode(hs)
470
+ when 26
471
+ while (a = [myfrand(8)].pack("g").unpack("g").first).to_cbor.size != 5
472
+ end
473
+ a
474
+ when 27
475
+ while (a = myfrand(11)).to_cbor.size != 9
476
+ end
477
+ a
478
+ else
479
+ fail "Can't generate prim #7.#{where[2].inspect}" # XXX retry array generate
440
480
  end
441
481
  else
442
482
  fail "Can't generate prim #{where[1]}"
@@ -551,8 +591,7 @@ module CDDL
551
591
  warn "HUH gen #{where.inspect} #{try.inspect}" unless try.nil?
552
592
  end
553
593
  end
554
- 32.times do
555
- content = generate1(target)
594
+ try_generate(target) do |content|
556
595
  if validate1(content, where)
557
596
  return content
558
597
  end
@@ -598,29 +637,35 @@ module CDDL
598
637
  end
599
638
  content = JSON::dump(generate1(control))
600
639
  content
601
- when :decimal
640
+ when :decimal, :base10
641
+ if conop == :decimal
642
+ unless @decimal_warned
643
+ warn "** .decimal control operator is now called .base10"
644
+ @decimal_warned = true
645
+ end
646
+ end
602
647
  unless target == [:prim, 3]
603
648
  fail "Don't know yet how to generate #{where}"
604
649
  end
605
650
  content = Integer(generate1(control)).to_s
606
651
  content
607
652
  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}"
653
+ try_generate(control) do |content|
654
+ if Array === content &&
655
+ content.all? {|x| String === x} &&
656
+ Set[content.map {|x| x.encoding}].size == 1
657
+ content = content.join
658
+ if validate1(content, target)
659
+ return content
660
+ end
661
+ end
614
662
  end
615
- content = content.join
616
- content
663
+ fail "Don't know yet how to generate #{where}"
617
664
  when :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
618
665
  :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
666
+ try_generate(control) do |content|
667
+ if String === content
668
+ content = case conop
624
669
  when :b64u, :"b64u-sloppy"
625
670
  Base64.urlsafe_encode64(content, padding: false)
626
671
  when :b64c, :"b64c-sloppy"
@@ -639,10 +684,33 @@ module CDDL
639
684
  content.unpack("H*")[0]
640
685
  else fail "Cannot happen"
641
686
  end
642
- content
687
+ if validate1(content, target)
688
+ return content
689
+ end
690
+ end
691
+ end
692
+ fail "Not smart enough to generate #{where}"
693
+ when :printf
694
+ try_generate(control) do |content|
695
+ if Array === content && content.size >= 1
696
+ fmt, *data = content
697
+ if String === fmt
698
+ begin
699
+ content = fmt % data
700
+ if validate1(content, target)
701
+ return content
702
+ end
703
+ rescue ArgumentError => e
704
+ # be verbose about mismatches here
705
+ @last_message << "\n** #{fmt.inspect} ArgumentError #{e}"
706
+ end
707
+ end
708
+ end
709
+ end
710
+ fail "Not smart enough to generate #{where}#{@last_message}"
643
711
  when :within, :and
644
- 32.times do
645
- content = generate1(target)
712
+ try_generate(target) do |content|
713
+ $features ||= Hash.new {|h, k| h[k] = {}}
646
714
  if validate1(content, control)
647
715
  return content
648
716
  elsif conop == :within
@@ -670,22 +738,41 @@ module CDDL
670
738
  end
671
739
  end
672
740
 
741
+ def try_generate(target)
742
+ 32.times do
743
+ content = generate1(target)
744
+ yield content # should return if success
745
+ end
746
+ end
747
+
673
748
  VALUE_TYPE = {text: String, bytes: String, int: Integer, float: Float}
674
749
  SIMPLE_VALUE = {
675
750
  [:prim, 7, 20] => [true, false, :bool],
676
751
  [:prim, 7, 21] => [true, true, :bool],
677
752
  [:prim, 7, 22] => [true, nil, :nil],
678
- [:prim, 7, 23] => [true, :undefined, :undefined],
679
753
  }
754
+ SIMPLE_VALUE_SIMPLE = Set[23] + (0..19) + (32..255)
680
755
 
681
756
  def extract_value(t) # []
682
757
  if vt = VALUE_TYPE[t[0]]
683
758
  [true, t[1], vt]
684
- elsif v = SIMPLE_VALUE[t]
685
- v
759
+ elsif t[0] == :prim && t[1] == 7
760
+ case t2 = t[2]
761
+ when Integer
762
+ when Array
763
+ a, b, c = extract_value(t2)
764
+ if a && c == Integer
765
+ t2 = b
766
+ end
767
+ end
768
+ if v = SIMPLE_VALUE[[:prim, 7, t2]]
769
+ v
770
+ elsif SIMPLE_VALUE_SIMPLE === t2
771
+ [true, CBOR::Simple.new(t2), :simple]
772
+ end
686
773
  elsif t[0] == :anno
687
774
  _, conop, target, control = t
688
- # warn ["EXV0", conop, target, control].inspect
775
+ warn ["EXV0", conop, target, control].inspect if ENV["CDDL_TRACE"]
689
776
  if conop == :cat || conop == :plus || conop == :det
690
777
  ok1, v1, vt1 = extract_value(target)
691
778
  ok2, v2, vt2 = extract_value(control)
@@ -717,6 +804,19 @@ module CDDL
717
804
  }]
718
805
  end
719
806
 
807
+
808
+ def extract_arg0(t)
809
+ return [false] unless t[0] == :array
810
+ [true,
811
+ (el = t[1]
812
+ return [false] unless el[0..3] == [:member, 1, 1, nil]
813
+ ok, v, vt = extract_value(el[4])
814
+ return [false] unless ok
815
+ [v, vt]
816
+ ),
817
+ *t[2..-1]]
818
+ end
819
+
720
820
  def extract_feature(control, d)
721
821
  ok, v, vt = extract_value(control)
722
822
  if ok
@@ -905,6 +1005,19 @@ module CDDL
905
1005
  }
906
1006
  end
907
1007
 
1008
+ def validate1a_ignore_encoding(d, where)
1009
+ if String === d
1010
+ validate1a(d.force_encoding(Encoding::BINARY), where) or (
1011
+ text = d.force_encoding(Encoding::UTF_8).scrub {
1012
+ fail "can't use bytes as text"
1013
+ } rescue :NOT_A_TEXT_STRING
1014
+ validate1a(text, where)
1015
+ )
1016
+ else
1017
+ validate1a(d, where)
1018
+ end
1019
+ end
1020
+
908
1021
  def validate1a(d, where)
909
1022
  if ann = validate1(d, where)
910
1023
  here = [d, where]
@@ -917,6 +1030,8 @@ module CDDL
917
1030
  end
918
1031
 
919
1032
  OPERATORS = {lt: :<, le: :<=, gt: :>, ge: :>=, eq: :==, ne: :!=}
1033
+ OPERATORS_MATCH = {eq: true, ne: false}
1034
+ FLOAT_AI_FROM_SIZE = {3 => 25, 5 => 26, 9 => 27}
920
1035
 
921
1036
  def validate1(d, where)
922
1037
  if ENV["CDDL_TRACE"]
@@ -927,6 +1042,9 @@ module CDDL
927
1042
  @last_data = d
928
1043
  @last_rule = where
929
1044
  ann = nil
1045
+ if CBOR::Tagged === d && d.tag === 888 && ENV["CDDL_888"]
1046
+ return []
1047
+ end
930
1048
  case where[0]
931
1049
  when :type1
932
1050
  if where[1..-1].any? {|r| ann = validate1a(d, r)}
@@ -963,7 +1081,7 @@ module CDDL
963
1081
  if conop == :cat || conop == :plus || conop == :det
964
1082
  ok1, v1, vt1 = extract_value(target)
965
1083
  ok2, v2, vt2 = extract_value(control)
966
- # warn ["ANNO0", ok1, v1, vt1, ok2, v2, vt2, d].inspect
1084
+ warn ["ANNO0", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
967
1085
  if ok1 && ok2
968
1086
  v2 = Integer(v2) if vt1 == Integer
969
1087
  if conop == :det
@@ -972,6 +1090,30 @@ module CDDL
972
1090
  end
973
1091
  # warn ["ANNO", ok1, v1, vt1, ok2, v2, vt2, d].inspect
974
1092
  [] if d == v1 + v2 # XXX Focus ArgumentError
1093
+ elsif conop == :cat && String === d
1094
+ warn ["CAT-L", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
1095
+ if ok1 && vt1 == String
1096
+ # d and lhs (v1) need to agree in encoding
1097
+ if d.encoding == v1.encoding
1098
+ if d[0...v1.length] == v1
1099
+ d2 = d[v1.length..-1]
1100
+ warn ["CAT-L1", d2, d2.encoding, control].inspect if ENV["CDDL_TRACE"]
1101
+ validate1a_ignore_encoding(d2, control)
1102
+ end
1103
+ end
1104
+ elsif ok2 && vt2 == String
1105
+ warn ["CAT-R", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
1106
+ if d[-v2.length..-1] == v2
1107
+ d1 = d[0...-v2.length]
1108
+ validate1a(d1, control)
1109
+ end
1110
+ end
1111
+ elsif conop == :plus && Integer === d
1112
+ if ok1 && vt1 == Integer
1113
+ validate1a(d - Integer(v1), control)
1114
+ elsif ok2 && vt2 == Integer
1115
+ validate1a(d - Integer(v2), target)
1116
+ end
975
1117
  end
976
1118
  elsif ann = validate1a(d, target)
977
1119
  case conop
@@ -1022,6 +1164,11 @@ module CDDL
1022
1164
  ok, v, _vt = extract_value(control)
1023
1165
  if ok
1024
1166
  ann if d.send(op, v) rescue nil # XXX Focus ArgumentError
1167
+ else
1168
+ needs_to_match = OPERATORS_MATCH[conop]
1169
+ unless needs_to_match.nil?
1170
+ ann if !!validate1(d, control) == needs_to_match
1171
+ end
1025
1172
  end
1026
1173
  when :regexp
1027
1174
  ann if (
@@ -1074,21 +1221,89 @@ module CDDL
1074
1221
  end
1075
1222
  when :json
1076
1223
  ann if validate1((JSON::load(d) rescue :BAD_JSON), control)
1077
- when :decimal
1224
+ when :decimal, :base10
1225
+ if conop == :decimal
1226
+ unless @decimal_warned
1227
+ warn "** .decimal control operator is now called .base10"
1228
+ @decimal_warned = true
1229
+ end
1230
+ end
1231
+
1078
1232
  ann if (
1079
1233
  if /\A0|-?[1-9][0-9]*\z/ === d
1080
1234
  validate1((d.to_i rescue :BAD_JSON), control)
1081
1235
  end
1082
1236
  )
1083
1237
  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
1238
+ t = control
1239
+ v = if t[0] == :array
1240
+ t[1..-1].map { |el|
1241
+ if el[0..2] == [:member, 1, 1]
1242
+ ok, v, vt = extract_value(el[4])
1243
+ if ok
1244
+ [true, v, vt]
1245
+ else
1246
+ [false, el[4]]
1247
+ end
1248
+ end
1249
+ }
1250
+ end
1251
+ warn "@@@JOIN@@@ #{v.inspect}" if ENV["CDDL_TRACE"]
1252
+ ok = true
1253
+ if v
1254
+ ix = 0
1255
+ rest = d.dup
1256
+ while ix < v.length
1257
+ if left = v[ix]
1258
+ if left[0] # match constant value first
1259
+ fail "Not a string for #{left.inspect} in #{where}" unless String == left[2]
1260
+ want = left[1]
1261
+ have = rest[0...left[1].length]
1262
+ if want == have
1263
+ rest[0...left[1].length] = ''
1264
+ ix += 1
1265
+ next
1266
+ else
1267
+ fail ".join: want #{want.inspect}, have #{have.inspect}"
1268
+ end
1269
+ else
1270
+ ix += 1
1271
+ if ix == v.length # match remaining
1272
+ warn "@@@JOIN ok in #{ok.inspect} rest #{rest.inspect}" if ENV["CDDL_TRACE"]
1273
+ ok &&= validate1(rest, left[1])
1274
+ warn "@@@JOIN ok out #{ok.inspect}" if ENV["CDDL_TRACE"]
1275
+ # more diag
1276
+ rest = ''
1277
+ next
1278
+ else
1279
+ if mid = v[ix]
1280
+ if mid[0] # have constant value to split over
1281
+ fail "Not a string for #{mid} in #{where}" unless String == mid[2]
1282
+ rest1, rest2 = rest.split(mid[1], 2)
1283
+ if rest2
1284
+ warn "@@@JOIN ok in #{ok.inspect} rest1 #{rest1.inspect}" if ENV["CDDL_TRACE"]
1285
+ ok &&= validate1(rest1, left[1])
1286
+ warn "@@@JOIN ok out #{ok.inspect}" if ENV["CDDL_TRACE"]
1287
+ rest = rest2
1288
+ ix += 1
1289
+ next
1290
+ else
1291
+ fail "Can't find #{mid[1].inspect} in #{rest.inspect}"
1292
+ end
1293
+ else
1294
+ fail "Cannot validate consecutive non-constant members of .join in #{where}"
1295
+ end
1296
+ else
1297
+ fail "Cannot handle .join over #{t[ix+1]} in #{where}"
1298
+ end
1299
+ end
1300
+ end
1301
+ else
1302
+ fail "Cannot handle .join over #{t[ix+1]} in #{where}"
1303
+ end
1304
+ end
1305
+ fail "Can't match #{rest.inspect} for .join in #{where}" if rest != ''
1306
+ ann if ok
1092
1307
  else
1093
1308
  fail "Don't know yet how to validate against #{where}"
1094
1309
  end
@@ -1097,7 +1312,7 @@ module CDDL
1097
1312
  String === d && (
1098
1313
  decoded = case conop
1099
1314
  when :b64u
1100
- /=/ !~ d &&
1315
+ /[+\/=]/ !~ d &&
1101
1316
  Base64.urlsafe_decode64(d)
1102
1317
  when :"b64u-sloppy"
1103
1318
  /[-_=]/ !~ d &&
@@ -1126,6 +1341,21 @@ module CDDL
1126
1341
  end
1127
1342
  ) && validate1(decoded.b, control)
1128
1343
  )
1344
+ when :printf
1345
+ ann if String === d && (
1346
+ ok, fmt, *v = extract_arg0(control)
1347
+ if ok && String == fmt[1]
1348
+ fmt = fmt[0]
1349
+ # warn "** ok #{ok.inspect} fmt #{fmt.inspect} v #{v.inspect}"
1350
+ decoded = d.scanf(fmt) # this is a bit too lenient, so let's do:
1351
+ encode_again = fmt % decoded
1352
+ if encode_again != d
1353
+ warn "** fmt #{fmt.inspect} d #{d.inspect} decoded #{decoded.inspect} encode_again #{encode_again.inspect}"
1354
+ else
1355
+ validate1(decoded, [:array, *v])
1356
+ end
1357
+ end
1358
+ )
1129
1359
  when :within
1130
1360
  if validate1(d, control)
1131
1361
  ann
@@ -1161,20 +1391,35 @@ module CDDL
1161
1391
  end
1162
1392
  d = CBOR::Tagged.new(t, d == 0 ? "".b : d.digits(256).reverse!.pack("C*"))
1163
1393
  end
1164
- CBOR::Tagged === d && d.tag == where[2] && validate1a(d.data, where[3])
1394
+ CBOR::Tagged === d && (
1395
+ Integer === where[2] ? d.tag == where[2] : validate1a(d.tag, where[2])
1396
+ ) && validate1a(d.data, where[3])
1165
1397
  when 7
1166
1398
  t, v = extract_value(where)
1167
1399
  if t
1168
1400
  v.eql? d
1169
1401
  else
1170
- case where[2]
1402
+ case w2 = where[2]
1171
1403
  when nil
1172
- # XXX
1173
- fail
1404
+ Float === d || CBOR::Simple === d || [false, true, nil].include?(d)
1405
+ when Array
1406
+ headnum = case d
1407
+ when Float
1408
+ FLOAT_AI_FROM_SIZE[d.to_cbor.size]
1409
+ when false
1410
+ 20
1411
+ when true
1412
+ 21
1413
+ when nil
1414
+ 22
1415
+ when CBOR::Simple
1416
+ d.value
1417
+ end
1418
+ validate1a(headnum, w2)
1174
1419
  when 25, 26, 27
1175
- Float === d
1420
+ Float === d && FLOAT_AI_FROM_SIZE[d.to_cbor.size] == w2
1176
1421
  else
1177
- fail
1422
+ fail [:val7, d, where].inspect
1178
1423
  end
1179
1424
  end
1180
1425
  else
@@ -1224,6 +1469,10 @@ module CDDL
1224
1469
  else
1225
1470
  [:type1]
1226
1471
  end
1472
+ elsif s = ENV["CDDL_INVENT"]
1473
+ s = "_" if s == ""
1474
+ r = [:type1, [:text, "#{s}-#{name}"]]
1475
+ return r
1227
1476
  end
1228
1477
  end
1229
1478
  if r
@@ -1269,6 +1518,18 @@ module CDDL
1269
1518
  end
1270
1519
  end
1271
1520
 
1521
+ STRING_ESCAPES = {
1522
+ "\"" => "\"",
1523
+ "/" => "/",
1524
+ "\\" => "\\",
1525
+ "'" => "'",
1526
+ "b" => "\b",
1527
+ "f" => "\f",
1528
+ "n" => "\n",
1529
+ "r" => "\r",
1530
+ "t" => "\t",
1531
+ }
1532
+
1272
1533
  def value(n)
1273
1534
  # cheat:
1274
1535
  # warn n
@@ -1278,7 +1539,20 @@ module CDDL
1278
1539
  if parts[-1] != ""
1279
1540
  warn "*** Problem decoding byte string #{s.inspect}"
1280
1541
  end
1281
- bsval = parts[0...-1].join("'").gsub(/\\(.)/){$1}
1542
+ bsval = parts[0...-1].join("'").gsub(/\\u([Dd][89AaBb][0-9a-zA-Z]{2})\\u([Dd][CcDdEeFf][0-9a-zA-Z]{2})|\\u([0-9a-zA-Z]{4})|\\u\{([0-9a-zA-Z]+)\}|\r?(\n)|\\([^u])/) {
1543
+ if hex = $3 || $4
1544
+ hex.to_i(16).chr(Encoding::UTF_8)
1545
+ elsif lf = $5
1546
+ lf
1547
+ elsif escaped = $6
1548
+ STRING_ESCAPES[$6] or (
1549
+ fail "Invalid String Escape #{escaped.inspect} in #{s.inspect}"
1550
+ )
1551
+ else
1552
+ ((($1.to_i(16) & 0x3ff) << 10) +
1553
+ ($2.to_i(16) & 0x3ff) + 0x10000).chr(Encoding::UTF_8)
1554
+ end
1555
+ }
1282
1556
  [:bytes,
1283
1557
  case bsqual
1284
1558
  when ""
@@ -1292,7 +1566,21 @@ module CDDL
1292
1566
  end
1293
1567
  ]
1294
1568
  else
1295
- val = eval(n.to_s)
1569
+ if s[-1] == '"'
1570
+ s.gsub!(/\\u([Dd][89AaBb][0-9a-zA-Z]{2})\\u([Dd][CcDdEeFf][0-9a-zA-Z]{2})|\\([^u]|u[0-9a-zA-Z]{4})/) {
1571
+ if $3
1572
+ "\\#$3" # skip this, use eval parser
1573
+ else
1574
+ ((($1.to_i(16) & 0x3ff) << 10) +
1575
+ ($2.to_i(16) & 0x3ff) + 0x10000).chr(Encoding::UTF_8)
1576
+ end
1577
+ }
1578
+ end
1579
+ if s =~ /p.*\d\z/ # hexfloat
1580
+ val = s.scanf("%a").first
1581
+ else
1582
+ val = eval(s)
1583
+ end
1296
1584
  # warn val
1297
1585
  case val
1298
1586
  when Integer; [:int, val]
@@ -1485,9 +1773,10 @@ module CDDL
1485
1773
  :within, :and,
1486
1774
  :default, :lt, :le, :gt, :ge, :eq, :ne,
1487
1775
  :feature, :abnf, :abnfb, :det, :cat, :plus,
1488
- :json, :decimal, :join,
1776
+ :json, :decimal, :base10, :join,
1489
1777
  :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
1490
1778
  :b45, :b32, :h32, :hex, :hexlc, :hexuc,
1779
+ :printf,
1491
1780
  ]
1492
1781
 
1493
1782
  def type1(n, canbegroup = false)
@@ -1520,6 +1809,13 @@ module CDDL
1520
1809
  when /\A#(\d+)/
1521
1810
  maj = $1.to_i
1522
1811
  s = [:prim, maj, *n.children(:uint).map(&:to_s).map(&:to_i)]
1812
+ if tn = n.headnumber
1813
+ if ui = tn.uint
1814
+ s << ui.to_s.to_i
1815
+ elsif tt = tn.type
1816
+ s << type(tt)
1817
+ end
1818
+ end
1523
1819
  if tagged_type = n.type
1524
1820
  s << type(tagged_type)
1525
1821
  end
@@ -0,0 +1,12 @@
1
+ a = text .b64u bytes
2
+
3
+ ;;gp 10
4
+
5
+ ;;vp "AAAA"
6
+ ;;vp "AAA-"
7
+ ;;vp "AAA_"
8
+ ; fail with 0.11.5:
9
+ ;;vp "AAA+"
10
+ ;;vp "AAA/"
11
+ ;;vp "AAA="
12
+ ;;vp "+kd8"
@@ -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 @@
1
+ s = [text .decimal 4711, text .base10 4712]
@@ -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])
@@ -0,0 +1,16 @@
1
+ cwt = [
2
+ bstr .cbor protected-map,
3
+ unprotected-map,
4
+ bstr .cbor payload-map,
5
+ bstr ; signature
6
+ ]
7
+
8
+ protected-map = {
9
+ &(alg: 1) => int,
10
+ ? &(typ: 16) => text,
11
+ * key => any
12
+ }
13
+
14
+ unprotected-map = ()
15
+ key = "key"
16
+ payload-map = { payload: "map"}
metadata CHANGED
@@ -1,14 +1,13 @@
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.12.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carsten Bormann
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-03-09 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: cbor-diag
@@ -28,16 +27,16 @@ dependencies:
28
27
  name: abnc
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
- - - ">="
30
+ - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: '0'
32
+ version: 0.1.1
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
- - - ">="
37
+ - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: '0'
39
+ version: 0.1.1
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: json_pure
43
42
  requirement: !ruby/object:Gem::Requirement
@@ -70,16 +69,16 @@ dependencies:
70
69
  name: regexp-examples
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
- - - ">="
72
+ - - "~>"
74
73
  - !ruby/object:Gem::Version
75
- version: '0'
74
+ version: 1.5.1
76
75
  type: :runtime
77
76
  prerelease: false
78
77
  version_requirements: !ruby/object:Gem::Requirement
79
78
  requirements:
80
- - - ">="
79
+ - - "~>"
81
80
  - !ruby/object:Gem::Version
82
- version: '0'
81
+ version: 1.5.1
83
82
  - !ruby/object:Gem::Dependency
84
83
  name: colorize
85
84
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +107,34 @@ dependencies:
108
107
  - - "~>"
109
108
  - !ruby/object:Gem::Version
110
109
  version: '0.3'
110
+ - !ruby/object:Gem::Dependency
111
+ name: base45_lite
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.0'
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '1.0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: scanf
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '1.0'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '1.0'
111
138
  description: A parser, generator, and validator for CDDL
112
139
  email: cabo@tzi.org
113
140
  executables:
@@ -119,7 +146,6 @@ files:
119
146
  - cddl.gemspec
120
147
  - data/cddl.abnf
121
148
  - data/prelude.cddl
122
- - lib/base45_lite.rb
123
149
  - lib/cbor-pp-play.rb
124
150
  - lib/cbor-pp.rb
125
151
  - lib/cddl.rb
@@ -136,6 +162,7 @@ files:
136
162
  - test-data/b.cddl
137
163
  - test-data/b64c-sloppy.cddl
138
164
  - test-data/b64c.cddl
165
+ - test-data/b64u-strict.cddl
139
166
  - test-data/b64u.cddl
140
167
  - test-data/badaddr.cddl
141
168
  - test-data/base32.cddl
@@ -146,6 +173,7 @@ files:
146
173
  - test-data/bpv7a.cddl
147
174
  - test-data/bpv7b.cddl
148
175
  - test-data/cat-re.cddl
176
+ - test-data/catb64.cddl
149
177
  - test-data/cdni-ct.cddl
150
178
  - test-data/complex-occ.cddl
151
179
  - test-data/coral.cddl
@@ -155,10 +183,17 @@ files:
155
183
  - test-data/cose.cddl
156
184
  - test-data/dcaf.cddl
157
185
  - test-data/dcaf1.cddl
186
+ - test-data/decimal-warn.cddl
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
@@ -220,6 +263,7 @@ files:
220
263
  - test-data/toerless0.cddl
221
264
  - test-data/toerless1.cddl
222
265
  - test-data/two_anonymous_groups.cddl
266
+ - test-data/valemb.cddl
223
267
  - test-data/wrong1.cddl
224
268
  - test-data/wrong1a.cddl
225
269
  - test-data/wrong2.cddl
@@ -228,11 +272,10 @@ files:
228
272
  - test-data/yangid.cddl
229
273
  - test-data/yaron1.cddl
230
274
  - test/test-cddl.rb
231
- homepage: http://github.com/cabo/cddl
275
+ homepage: https://www.rfc-editor.org/rfc/rfc8610#appendix-F
232
276
  licenses:
233
277
  - MIT
234
278
  metadata: {}
235
- post_install_message:
236
279
  rdoc_options: []
237
280
  require_paths:
238
281
  - lib
@@ -240,15 +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
251
- signing_key:
293
+ rubygems_version: 4.0.8
252
294
  specification_version: 4
253
295
  summary: CDDL generator and validator.
254
296
  test_files: []
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