cddl 0.10.3 → 0.12.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/cddl +18 -2
- data/cddl.gemspec +7 -5
- data/data/cddl.abnf +26 -11
- data/lib/cddl.rb +312 -48
- data/test-data/b64u-strict.cddl +12 -0
- data/test-data/cat-re.cddl +2 -0
- data/test-data/catb64.cddl +8 -0
- data/test-data/dotplus1.cddl +3 -0
- data/test-data/dotplus2.cddl +3 -0
- data/test-data/dotplus3.cddl +3 -0
- data/test-data/dotplus4.cddl +3 -0
- data/test-data/enum.cddl +14 -0
- data/test-data/enum1.cddl +12 -0
- data/test-data/json1.cddl +15 -0
- data/test-data/jwt.cddl +15 -0
- data/test-data/prim.cddl +7 -0
- data/test-data/printf.cddl +2 -0
- data/test-data/printf0.cddl +1 -0
- data/test-data/printf1.cddl +2 -0
- data/test-data/printf2.cddl +2 -0
- data/test-data/printf3.cddl +2 -0
- data/test-data/valemb.cddl +16 -0
- metadata +58 -14
- data/lib/base45_lite.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c98730c57c25c57066cc2c35d0912b14df39e1d3f3ff3815950217435513d30
|
4
|
+
data.tar.gz: 1da65aafd52644087e1fa33d5e158ae4c85d58b11658fc39bf64a465f8cf3b43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54a58e321f94a6c8e3c61dd0216f1e6afd214972dbd71cc4326a5ec294714b4f0ce5b1695ab951bd5526e1cd9a1550c5102333395e3fdda4cac3a87d0c4d075b
|
7
|
+
data.tar.gz: ad35e2794090e2d403ffa218fd3c9414052c00092b0a1b34ab11d9a7563be3ac06b0e3b5923982f1f46e9b0a2b13e578c7c3da0b12b4cc4ee6eaff0bb5581f5b
|
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
|
-
|
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,26 @@
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
2
2
|
s.name = 'cddl'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.12.9'
|
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
19
|
s.default_executable = 'cddl'
|
18
|
-
s.required_ruby_version = '>= 2.
|
20
|
+
s.required_ruby_version = '>= 2.3'
|
19
21
|
s.author = "Carsten Bormann"
|
20
22
|
s.email = "cabo@tzi.org"
|
21
|
-
s.homepage = "
|
23
|
+
s.homepage = "https://www.rfc-editor.org/rfc/rfc8610#appendix-F"
|
22
24
|
s.license = 'MIT'
|
23
25
|
end
|
24
26
|
|
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" ["."
|
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
|
|
@@ -67,27 +70,39 @@ fraction = 1*DIGIT
|
|
67
70
|
exponent = int
|
68
71
|
|
69
72
|
text = %x22 *SCHAR %x22
|
70
|
-
SCHAR = %x20-21 / %x23-7E / SESC
|
71
|
-
|
73
|
+
SCHAR = %x20-21 / %x23-5B / %x5D-7E / NONASCII / SESC
|
74
|
+
|
75
|
+
SESC = "\" ( %x22 / "/" / "\" / ; \" \/ \\
|
76
|
+
%x62 / %x66 / %x6E / %x72 / %x74 / ; \b \f \n \r \t
|
77
|
+
(%x75 hexchar) ) ; \uXXXX
|
78
|
+
|
79
|
+
hexchar = "{" (1*"0" [ hexscalar ] / hexscalar) "}" /
|
80
|
+
non-surrogate / (high-surrogate "\" %x75 low-surrogate)
|
81
|
+
non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") HEXDIG HEXDIG HEXDIG) /
|
82
|
+
("D" %x30-37 HEXDIG HEXDIG)
|
83
|
+
high-surrogate = "D" ("8"/"9"/"A"/"B") HEXDIG HEXDIG
|
84
|
+
low-surrogate = "D" ("C"/"D"/"E"/"F") HEXDIG HEXDIG
|
85
|
+
hexscalar = "10" HEXDIG HEXDIG HEXDIG HEXDIG / HEXDIG1 HEXDIG HEXDIG HEXDIG HEXDIG
|
86
|
+
/ non-surrogate / HEXDIG [HEXDIG [HEXDIG]]
|
72
87
|
|
73
88
|
bytes = [bsqual] %x27 *BCHAR %x27
|
74
|
-
BCHAR = %x20-26 / %x28-5B / %x5D-7E / SESC / CRLF
|
75
|
-
bsqual =
|
76
|
-
/ %x62.36.34 ; "b64"
|
89
|
+
BCHAR = %x20-26 / %x28-5B / %x5D-7E / NONASCII / SESC / "\'" / CRLF
|
90
|
+
bsqual = "h" / "b64"
|
77
91
|
|
78
92
|
id = EALPHA *(*("-" / ".") (EALPHA / DIGIT))
|
79
93
|
ALPHA = %x41-5A / %x61-7A
|
80
|
-
EALPHA =
|
94
|
+
EALPHA = ALPHA / "@" / "_" / "$"
|
81
95
|
DIGIT = %x30-39
|
82
96
|
DIGIT1 = %x31-39
|
83
97
|
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
|
98
|
+
HEXDIG1 = DIGIT1 / "A" / "B" / "C" / "D" / "E" / "F"
|
84
99
|
BINDIG = %x30-31
|
85
100
|
|
86
101
|
S = *WS
|
87
102
|
WS = SP / NL
|
88
103
|
SP = %x20
|
89
104
|
NL = COMMENT / CRLF
|
90
|
-
COMMENT = ";" *
|
91
|
-
|
105
|
+
COMMENT = ";" *PCHAR CRLF
|
106
|
+
PCHAR = %x20-7E / NONASCII
|
107
|
+
NONASCII = %xA0-D7FF / %xE000-10FFFD
|
92
108
|
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#{
|
@@ -246,7 +249,7 @@ module CDDL
|
|
246
249
|
r_process("used_in_cddl_prelude", @rules["used_in_cddl_prelude"])
|
247
250
|
@rules.each do |n, r|
|
248
251
|
# r_process(n, r) # debug only loop
|
249
|
-
warn "*** Unused rule #{n}" unless @stage1[n]
|
252
|
+
warn "*** Unused rule #{n}" unless @stage1[n] || CDDL_UNUSED_OK
|
250
253
|
end
|
251
254
|
if result[0] == :grpent
|
252
255
|
warn "Group at top -- first rule must be a type!"
|
@@ -300,6 +303,12 @@ module CDDL
|
|
300
303
|
abnfb: Encoding::BINARY
|
301
304
|
}
|
302
305
|
|
306
|
+
def myfrand(exp)
|
307
|
+
exprange = 1 << exp
|
308
|
+
expoffset= exprange >> 1
|
309
|
+
(rand(2)*2-1) * rand() * 2.0**(rand(exprange)-expoffset)
|
310
|
+
end
|
311
|
+
|
303
312
|
def generate
|
304
313
|
@recursion = 0
|
305
314
|
generate1(rules)
|
@@ -422,9 +431,17 @@ module CDDL
|
|
422
431
|
when 3
|
423
432
|
gen_word
|
424
433
|
when 6
|
425
|
-
|
434
|
+
tn = Integer === where[2] ? where[2] : generate1(where[2])
|
435
|
+
unless Integer === tn && tn >= 0
|
436
|
+
fail "Can't generate a tag number out of #{where[2]}"
|
437
|
+
end
|
438
|
+
CBOR::Tagged.new(tn, generate1(where[3]))
|
426
439
|
when 7
|
427
|
-
|
440
|
+
w2 = where[2]
|
441
|
+
if Array === w2
|
442
|
+
w2 = generate1(w2)
|
443
|
+
end
|
444
|
+
case w2
|
428
445
|
when nil
|
429
446
|
Math::PI
|
430
447
|
when 20
|
@@ -433,10 +450,22 @@ module CDDL
|
|
433
450
|
true
|
434
451
|
when 22
|
435
452
|
nil
|
436
|
-
when 23
|
437
|
-
|
438
|
-
when 25
|
439
|
-
|
453
|
+
when 0..19, 23, 32..255
|
454
|
+
CBOR::Simple.new(w2)
|
455
|
+
when 25
|
456
|
+
while !(hs = Half.encode_from_single_bytes([myfrand(5)].pack("g")))
|
457
|
+
end
|
458
|
+
Half.decode(hs)
|
459
|
+
when 26
|
460
|
+
while (a = [myfrand(8)].pack("g").unpack("g").first).to_cbor.size != 5
|
461
|
+
end
|
462
|
+
a
|
463
|
+
when 27
|
464
|
+
while (a = myfrand(11)).to_cbor.size != 9
|
465
|
+
end
|
466
|
+
a
|
467
|
+
else
|
468
|
+
fail "Can't generate prim #7.#{where[2].inspect}" # XXX retry array generate
|
440
469
|
end
|
441
470
|
else
|
442
471
|
fail "Can't generate prim #{where[1]}"
|
@@ -551,8 +580,7 @@ module CDDL
|
|
551
580
|
warn "HUH gen #{where.inspect} #{try.inspect}" unless try.nil?
|
552
581
|
end
|
553
582
|
end
|
554
|
-
|
555
|
-
content = generate1(target)
|
583
|
+
try_generate(target) do |content|
|
556
584
|
if validate1(content, where)
|
557
585
|
return content
|
558
586
|
end
|
@@ -605,22 +633,22 @@ module CDDL
|
|
605
633
|
content = Integer(generate1(control)).to_s
|
606
634
|
content
|
607
635
|
when :join
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
636
|
+
try_generate(control) do |content|
|
637
|
+
if Array === content &&
|
638
|
+
content.all? {|x| String === x} &&
|
639
|
+
Set[content.map {|x| x.encoding}].size == 1
|
640
|
+
content = content.join
|
641
|
+
if validate1(content, target)
|
642
|
+
return content
|
643
|
+
end
|
644
|
+
end
|
614
645
|
end
|
615
|
-
|
616
|
-
content
|
646
|
+
fail "Don't know yet how to generate #{where}"
|
617
647
|
when :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
|
618
648
|
:b45, :b32, :h32, :hex, :hexlc, :hexuc
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
end
|
623
|
-
content = case conop
|
649
|
+
try_generate(control) do |content|
|
650
|
+
if String === content
|
651
|
+
content = case conop
|
624
652
|
when :b64u, :"b64u-sloppy"
|
625
653
|
Base64.urlsafe_encode64(content, padding: false)
|
626
654
|
when :b64c, :"b64c-sloppy"
|
@@ -639,10 +667,32 @@ module CDDL
|
|
639
667
|
content.unpack("H*")[0]
|
640
668
|
else fail "Cannot happen"
|
641
669
|
end
|
642
|
-
|
670
|
+
if validate1(content, target)
|
671
|
+
return content
|
672
|
+
end
|
673
|
+
end
|
674
|
+
end
|
675
|
+
fail "Not smart enough to generate #{where}"
|
676
|
+
when :printf
|
677
|
+
try_generate(control) do |content|
|
678
|
+
if Array === content && content.size >= 1
|
679
|
+
fmt, *data = content
|
680
|
+
if String === fmt
|
681
|
+
begin
|
682
|
+
content = fmt % data
|
683
|
+
if validate1(content, target)
|
684
|
+
return content
|
685
|
+
end
|
686
|
+
rescue ArgumentError => e
|
687
|
+
# be verbose about mismatches here
|
688
|
+
@last_message << "\n** #{fmt.inspect} ArgumentError #{e}"
|
689
|
+
end
|
690
|
+
end
|
691
|
+
end
|
692
|
+
end
|
693
|
+
fail "Not smart enough to generate #{where}#{@last_message}"
|
643
694
|
when :within, :and
|
644
|
-
|
645
|
-
content = generate1(target)
|
695
|
+
try_generate(target) do |content|
|
646
696
|
if validate1(content, control)
|
647
697
|
return content
|
648
698
|
elsif conop == :within
|
@@ -670,22 +720,41 @@ module CDDL
|
|
670
720
|
end
|
671
721
|
end
|
672
722
|
|
723
|
+
def try_generate(target)
|
724
|
+
32.times do
|
725
|
+
content = generate1(target)
|
726
|
+
yield content # should return if success
|
727
|
+
end
|
728
|
+
end
|
729
|
+
|
673
730
|
VALUE_TYPE = {text: String, bytes: String, int: Integer, float: Float}
|
674
731
|
SIMPLE_VALUE = {
|
675
732
|
[:prim, 7, 20] => [true, false, :bool],
|
676
733
|
[:prim, 7, 21] => [true, true, :bool],
|
677
734
|
[:prim, 7, 22] => [true, nil, :nil],
|
678
|
-
[:prim, 7, 23] => [true, :undefined, :undefined],
|
679
735
|
}
|
736
|
+
SIMPLE_VALUE_SIMPLE = Set[23] + (0..19) + (32..255)
|
680
737
|
|
681
738
|
def extract_value(t) # []
|
682
739
|
if vt = VALUE_TYPE[t[0]]
|
683
740
|
[true, t[1], vt]
|
684
|
-
elsif
|
685
|
-
|
741
|
+
elsif t[0] == :prim && t[1] == 7
|
742
|
+
case t2 = t[2]
|
743
|
+
when Integer
|
744
|
+
when Array
|
745
|
+
a, b, c = extract_value(t2)
|
746
|
+
if a && c == Integer
|
747
|
+
t2 = b
|
748
|
+
end
|
749
|
+
end
|
750
|
+
if v = SIMPLE_VALUE[[:prim, 7, t2]]
|
751
|
+
v
|
752
|
+
elsif SIMPLE_VALUE_SIMPLE === t2
|
753
|
+
[true, CBOR::Simple.new(t2), :simple]
|
754
|
+
end
|
686
755
|
elsif t[0] == :anno
|
687
756
|
_, conop, target, control = t
|
688
|
-
|
757
|
+
warn ["EXV0", conop, target, control].inspect if ENV["CDDL_TRACE"]
|
689
758
|
if conop == :cat || conop == :plus || conop == :det
|
690
759
|
ok1, v1, vt1 = extract_value(target)
|
691
760
|
ok2, v2, vt2 = extract_value(control)
|
@@ -717,6 +786,19 @@ module CDDL
|
|
717
786
|
}]
|
718
787
|
end
|
719
788
|
|
789
|
+
|
790
|
+
def extract_arg0(t)
|
791
|
+
return [false] unless t[0] == :array
|
792
|
+
[true,
|
793
|
+
(el = t[1]
|
794
|
+
return [false] unless el[0..3] == [:member, 1, 1, nil]
|
795
|
+
ok, v, vt = extract_value(el[4])
|
796
|
+
return [false] unless ok
|
797
|
+
[v, vt]
|
798
|
+
),
|
799
|
+
*t[2..-1]]
|
800
|
+
end
|
801
|
+
|
720
802
|
def extract_feature(control, d)
|
721
803
|
ok, v, vt = extract_value(control)
|
722
804
|
if ok
|
@@ -905,6 +987,19 @@ module CDDL
|
|
905
987
|
}
|
906
988
|
end
|
907
989
|
|
990
|
+
def validate1a_ignore_encoding(d, where)
|
991
|
+
if String === d
|
992
|
+
validate1a(d.force_encoding(Encoding::BINARY), where) or (
|
993
|
+
text = d.force_encoding(Encoding::UTF_8).scrub {
|
994
|
+
fail "can't use bytes as text"
|
995
|
+
} rescue :NOT_A_TEXT_STRING
|
996
|
+
validate1a(text, where)
|
997
|
+
)
|
998
|
+
else
|
999
|
+
validate1a(d, where)
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
908
1003
|
def validate1a(d, where)
|
909
1004
|
if ann = validate1(d, where)
|
910
1005
|
here = [d, where]
|
@@ -917,6 +1012,8 @@ module CDDL
|
|
917
1012
|
end
|
918
1013
|
|
919
1014
|
OPERATORS = {lt: :<, le: :<=, gt: :>, ge: :>=, eq: :==, ne: :!=}
|
1015
|
+
OPERATORS_MATCH = {eq: true, ne: false}
|
1016
|
+
FLOAT_AI_FROM_SIZE = {3 => 25, 5 => 26, 9 => 27}
|
920
1017
|
|
921
1018
|
def validate1(d, where)
|
922
1019
|
if ENV["CDDL_TRACE"]
|
@@ -963,7 +1060,7 @@ module CDDL
|
|
963
1060
|
if conop == :cat || conop == :plus || conop == :det
|
964
1061
|
ok1, v1, vt1 = extract_value(target)
|
965
1062
|
ok2, v2, vt2 = extract_value(control)
|
966
|
-
|
1063
|
+
warn ["ANNO0", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
|
967
1064
|
if ok1 && ok2
|
968
1065
|
v2 = Integer(v2) if vt1 == Integer
|
969
1066
|
if conop == :det
|
@@ -972,6 +1069,30 @@ module CDDL
|
|
972
1069
|
end
|
973
1070
|
# warn ["ANNO", ok1, v1, vt1, ok2, v2, vt2, d].inspect
|
974
1071
|
[] if d == v1 + v2 # XXX Focus ArgumentError
|
1072
|
+
elsif conop == :cat && String === d
|
1073
|
+
warn ["CAT-L", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
|
1074
|
+
if ok1 && vt1 == String
|
1075
|
+
# d and lhs (v1) need to agree in encoding
|
1076
|
+
if d.encoding == v1.encoding
|
1077
|
+
if d[0...v1.length] == v1
|
1078
|
+
d2 = d[v1.length..-1]
|
1079
|
+
warn ["CAT-L1", d2, d2.encoding, control].inspect if ENV["CDDL_TRACE"]
|
1080
|
+
validate1a_ignore_encoding(d2, control)
|
1081
|
+
end
|
1082
|
+
end
|
1083
|
+
elsif ok2 && vt2 == String
|
1084
|
+
warn ["CAT-R", ok1, v1, vt1, ok2, v2, vt2, d].inspect if ENV["CDDL_TRACE"]
|
1085
|
+
if d[-v2.length..-1] == v2
|
1086
|
+
d1 = d[0...-v2.length]
|
1087
|
+
validate1a(d1, control)
|
1088
|
+
end
|
1089
|
+
end
|
1090
|
+
elsif conop == :plus && Integer === d
|
1091
|
+
if ok1 && vt1 == Integer
|
1092
|
+
validate1a(d - Integer(v1), control)
|
1093
|
+
elsif ok2 && vt2 == Integer
|
1094
|
+
validate1a(d - Integer(v2), target)
|
1095
|
+
end
|
975
1096
|
end
|
976
1097
|
elsif ann = validate1a(d, target)
|
977
1098
|
case conop
|
@@ -1022,6 +1143,11 @@ module CDDL
|
|
1022
1143
|
ok, v, _vt = extract_value(control)
|
1023
1144
|
if ok
|
1024
1145
|
ann if d.send(op, v) rescue nil # XXX Focus ArgumentError
|
1146
|
+
else
|
1147
|
+
needs_to_match = OPERATORS_MATCH[conop]
|
1148
|
+
unless needs_to_match.nil?
|
1149
|
+
ann if !!validate1(d, control) == needs_to_match
|
1150
|
+
end
|
1025
1151
|
end
|
1026
1152
|
when :regexp
|
1027
1153
|
ann if (
|
@@ -1081,14 +1207,75 @@ module CDDL
|
|
1081
1207
|
end
|
1082
1208
|
)
|
1083
1209
|
when :join
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1210
|
+
t = control
|
1211
|
+
v = if t[0] == :array
|
1212
|
+
t[1..-1].map { |el|
|
1213
|
+
if el[0..2] == [:member, 1, 1]
|
1214
|
+
ok, v, vt = extract_value(el[4])
|
1215
|
+
if ok
|
1216
|
+
[true, v, vt]
|
1217
|
+
else
|
1218
|
+
[false, el[4]]
|
1219
|
+
end
|
1220
|
+
end
|
1221
|
+
}
|
1222
|
+
end
|
1223
|
+
warn "@@@JOIN@@@ #{v.inspect}" if ENV["CDDL_TRACE"]
|
1224
|
+
ok = true
|
1225
|
+
if v
|
1226
|
+
ix = 0
|
1227
|
+
rest = d.dup
|
1228
|
+
while ix < v.length
|
1229
|
+
if left = v[ix]
|
1230
|
+
if left[0] # match constant value first
|
1231
|
+
fail "Not a string for #{left.inspect} in #{where}" unless String == left[2]
|
1232
|
+
want = left[1]
|
1233
|
+
have = rest[0...left[1].length]
|
1234
|
+
if want == have
|
1235
|
+
rest[0...left[1].length] = ''
|
1236
|
+
ix += 1
|
1237
|
+
next
|
1238
|
+
else
|
1239
|
+
fail ".join: want #{want.inspect}, have #{have.inspect}"
|
1240
|
+
end
|
1241
|
+
else
|
1242
|
+
ix += 1
|
1243
|
+
if ix == v.length # match remaining
|
1244
|
+
warn "@@@JOIN ok in #{ok.inspect} rest #{rest.inspect}" if ENV["CDDL_TRACE"]
|
1245
|
+
ok &&= validate1(rest, left[1])
|
1246
|
+
warn "@@@JOIN ok out #{ok.inspect}" if ENV["CDDL_TRACE"]
|
1247
|
+
# more diag
|
1248
|
+
rest = ''
|
1249
|
+
next
|
1250
|
+
else
|
1251
|
+
if mid = v[ix]
|
1252
|
+
if mid[0] # have constant value to split over
|
1253
|
+
fail "Not a string for #{mid} in #{where}" unless String == mid[2]
|
1254
|
+
rest1, rest2 = rest.split(mid[1], 2)
|
1255
|
+
if rest2
|
1256
|
+
warn "@@@JOIN ok in #{ok.inspect} rest1 #{rest1.inspect}" if ENV["CDDL_TRACE"]
|
1257
|
+
ok &&= validate1(rest1, left[1])
|
1258
|
+
warn "@@@JOIN ok out #{ok.inspect}" if ENV["CDDL_TRACE"]
|
1259
|
+
rest = rest2
|
1260
|
+
ix += 1
|
1261
|
+
next
|
1262
|
+
else
|
1263
|
+
fail "Can't find #{mid[1].inspect} in #{rest.inspect}"
|
1264
|
+
end
|
1265
|
+
else
|
1266
|
+
fail "Cannot validate consecutive non-constant members of .join in #{where}"
|
1267
|
+
end
|
1268
|
+
else
|
1269
|
+
fail "Cannot handle .join over #{t[ix+1]} in #{where}"
|
1270
|
+
end
|
1271
|
+
end
|
1272
|
+
end
|
1273
|
+
else
|
1274
|
+
fail "Cannot handle .join over #{t[ix+1]} in #{where}"
|
1275
|
+
end
|
1276
|
+
end
|
1277
|
+
fail "Can't match #{rest.inspect} for .join in #{where}" if rest != ''
|
1278
|
+
ann if ok
|
1092
1279
|
else
|
1093
1280
|
fail "Don't know yet how to validate against #{where}"
|
1094
1281
|
end
|
@@ -1097,7 +1284,7 @@ module CDDL
|
|
1097
1284
|
String === d && (
|
1098
1285
|
decoded = case conop
|
1099
1286
|
when :b64u
|
1100
|
-
|
1287
|
+
/[+\/=]/ !~ d &&
|
1101
1288
|
Base64.urlsafe_decode64(d)
|
1102
1289
|
when :"b64u-sloppy"
|
1103
1290
|
/[-_=]/ !~ d &&
|
@@ -1126,6 +1313,21 @@ module CDDL
|
|
1126
1313
|
end
|
1127
1314
|
) && validate1(decoded.b, control)
|
1128
1315
|
)
|
1316
|
+
when :printf
|
1317
|
+
ann if String === d && (
|
1318
|
+
ok, fmt, *v = extract_arg0(control)
|
1319
|
+
if ok && String == fmt[1]
|
1320
|
+
fmt = fmt[0]
|
1321
|
+
# warn "** ok #{ok.inspect} fmt #{fmt.inspect} v #{v.inspect}"
|
1322
|
+
decoded = d.scanf(fmt) # this is a bit too lenient, so let's do:
|
1323
|
+
encode_again = fmt % decoded
|
1324
|
+
if encode_again != d
|
1325
|
+
warn "** fmt #{fmt.inspect} d #{d.inspect} decoded #{decoded.inspect} encode_again #{encode_again.inspect}"
|
1326
|
+
else
|
1327
|
+
validate1(decoded, [:array, *v])
|
1328
|
+
end
|
1329
|
+
end
|
1330
|
+
)
|
1129
1331
|
when :within
|
1130
1332
|
if validate1(d, control)
|
1131
1333
|
ann
|
@@ -1161,20 +1363,35 @@ module CDDL
|
|
1161
1363
|
end
|
1162
1364
|
d = CBOR::Tagged.new(t, d == 0 ? "".b : d.digits(256).reverse!.pack("C*"))
|
1163
1365
|
end
|
1164
|
-
CBOR::Tagged === d &&
|
1366
|
+
CBOR::Tagged === d && (
|
1367
|
+
Integer === where[2] ? d.tag == where[2] : validate1a(d.tag, where[2])
|
1368
|
+
) && validate1a(d.data, where[3])
|
1165
1369
|
when 7
|
1166
1370
|
t, v = extract_value(where)
|
1167
1371
|
if t
|
1168
1372
|
v.eql? d
|
1169
1373
|
else
|
1170
|
-
case where[2]
|
1374
|
+
case w2 = where[2]
|
1171
1375
|
when nil
|
1172
|
-
|
1173
|
-
|
1376
|
+
Float === d || CBOR::Simple === d || [false, true, nil].include?(d)
|
1377
|
+
when Array
|
1378
|
+
headnum = case d
|
1379
|
+
when Float
|
1380
|
+
FLOAT_AI_FROM_SIZE[d.to_cbor.size]
|
1381
|
+
when false
|
1382
|
+
20
|
1383
|
+
when true
|
1384
|
+
21
|
1385
|
+
when nil
|
1386
|
+
22
|
1387
|
+
when CBOR::Simple
|
1388
|
+
d.value
|
1389
|
+
end
|
1390
|
+
validate1a(headnum, w2)
|
1174
1391
|
when 25, 26, 27
|
1175
|
-
Float === d
|
1392
|
+
Float === d && FLOAT_AI_FROM_SIZE[d.to_cbor.size] == w2
|
1176
1393
|
else
|
1177
|
-
fail
|
1394
|
+
fail [:val7, d, where].inspect
|
1178
1395
|
end
|
1179
1396
|
end
|
1180
1397
|
else
|
@@ -1224,6 +1441,10 @@ module CDDL
|
|
1224
1441
|
else
|
1225
1442
|
[:type1]
|
1226
1443
|
end
|
1444
|
+
elsif s = ENV["CDDL_INVENT"]
|
1445
|
+
s = "_" if s == ""
|
1446
|
+
r = [:type1, [:text, "#{s}-#{name}"]]
|
1447
|
+
return r
|
1227
1448
|
end
|
1228
1449
|
end
|
1229
1450
|
if r
|
@@ -1269,6 +1490,18 @@ module CDDL
|
|
1269
1490
|
end
|
1270
1491
|
end
|
1271
1492
|
|
1493
|
+
STRING_ESCAPES = {
|
1494
|
+
"\"" => "\"",
|
1495
|
+
"/" => "/",
|
1496
|
+
"\\" => "\\",
|
1497
|
+
"'" => "'",
|
1498
|
+
"b" => "\b",
|
1499
|
+
"f" => "\f",
|
1500
|
+
"n" => "\n",
|
1501
|
+
"r" => "\r",
|
1502
|
+
"t" => "\t",
|
1503
|
+
}
|
1504
|
+
|
1272
1505
|
def value(n)
|
1273
1506
|
# cheat:
|
1274
1507
|
# warn n
|
@@ -1278,7 +1511,20 @@ module CDDL
|
|
1278
1511
|
if parts[-1] != ""
|
1279
1512
|
warn "*** Problem decoding byte string #{s.inspect}"
|
1280
1513
|
end
|
1281
|
-
bsval = parts[0...-1].join("'").gsub(/\\(
|
1514
|
+
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])/) {
|
1515
|
+
if hex = $3 || $4
|
1516
|
+
hex.to_i(16).chr(Encoding::UTF_8)
|
1517
|
+
elsif lf = $5
|
1518
|
+
lf
|
1519
|
+
elsif escaped = $6
|
1520
|
+
STRING_ESCAPES[$6] or (
|
1521
|
+
fail "Invalid String Escape #{escaped.inspect} in #{s.inspect}"
|
1522
|
+
)
|
1523
|
+
else
|
1524
|
+
((($1.to_i(16) & 0x3ff) << 10) +
|
1525
|
+
($2.to_i(16) & 0x3ff) + 0x10000).chr(Encoding::UTF_8)
|
1526
|
+
end
|
1527
|
+
}
|
1282
1528
|
[:bytes,
|
1283
1529
|
case bsqual
|
1284
1530
|
when ""
|
@@ -1292,7 +1538,17 @@ module CDDL
|
|
1292
1538
|
end
|
1293
1539
|
]
|
1294
1540
|
else
|
1295
|
-
|
1541
|
+
if s[-1] == '"'
|
1542
|
+
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})/) {
|
1543
|
+
if $3
|
1544
|
+
"\\#$3" # skip this, use eval parser
|
1545
|
+
else
|
1546
|
+
((($1.to_i(16) & 0x3ff) << 10) +
|
1547
|
+
($2.to_i(16) & 0x3ff) + 0x10000).chr(Encoding::UTF_8)
|
1548
|
+
end
|
1549
|
+
}
|
1550
|
+
end
|
1551
|
+
val = eval(s)
|
1296
1552
|
# warn val
|
1297
1553
|
case val
|
1298
1554
|
when Integer; [:int, val]
|
@@ -1488,6 +1744,7 @@ module CDDL
|
|
1488
1744
|
:json, :decimal, :join,
|
1489
1745
|
:b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
|
1490
1746
|
:b45, :b32, :h32, :hex, :hexlc, :hexuc,
|
1747
|
+
:printf,
|
1491
1748
|
]
|
1492
1749
|
|
1493
1750
|
def type1(n, canbegroup = false)
|
@@ -1520,6 +1777,13 @@ module CDDL
|
|
1520
1777
|
when /\A#(\d+)/
|
1521
1778
|
maj = $1.to_i
|
1522
1779
|
s = [:prim, maj, *n.children(:uint).map(&:to_s).map(&:to_i)]
|
1780
|
+
if tn = n.headnumber
|
1781
|
+
if ui = tn.uint
|
1782
|
+
s << ui.to_s.to_i
|
1783
|
+
elsif tt = tn.type
|
1784
|
+
s << type(tt)
|
1785
|
+
end
|
1786
|
+
end
|
1523
1787
|
if tagged_type = n.type
|
1524
1788
|
s << type(tagged_type)
|
1525
1789
|
end
|
data/test-data/cat-re.cddl
CHANGED
data/test-data/enum.cddl
ADDED
@@ -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
|
data/test-data/jwt.cddl
ADDED
@@ -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
|
data/test-data/prim.cddl
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
my_label = text .printf (["0x%x: %a", 4711, 81.5])
|
@@ -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,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cddl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-12-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:
|
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:
|
40
|
+
version: 0.1.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: json_pure
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: regexp-examples
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 1.5.1
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 1.5.1
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: colorize
|
85
85
|
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
|
@@ -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,7 +272,7 @@ files:
|
|
228
272
|
- test-data/yangid.cddl
|
229
273
|
- test-data/yaron1.cddl
|
230
274
|
- test/test-cddl.rb
|
231
|
-
homepage:
|
275
|
+
homepage: https://www.rfc-editor.org/rfc/rfc8610#appendix-F
|
232
276
|
licenses:
|
233
277
|
- MIT
|
234
278
|
metadata: {}
|
@@ -240,14 +284,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
240
284
|
requirements:
|
241
285
|
- - ">="
|
242
286
|
- !ruby/object:Gem::Version
|
243
|
-
version: '2.
|
287
|
+
version: '2.3'
|
244
288
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
245
289
|
requirements:
|
246
290
|
- - ">="
|
247
291
|
- !ruby/object:Gem::Version
|
248
292
|
version: '0'
|
249
293
|
requirements: []
|
250
|
-
rubygems_version: 3.
|
294
|
+
rubygems_version: 3.5.14
|
251
295
|
signing_key:
|
252
296
|
specification_version: 4
|
253
297
|
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
|