cddl 0.10.3 → 0.12.9
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 +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
|