cddl 0.10.2 → 0.10.3
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/cddl.gemspec +1 -1
- data/lib/base45_lite.rb +71 -0
- data/lib/cddl.rb +60 -18
- data/test-data/b64c-sloppy.cddl +1 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e60b48882767d7e76926473b44c79369891e4203326d4e31f5693a3819f391d
|
4
|
+
data.tar.gz: 6ed2f45e7fa8468557e73c96a4dbfdd142d65fdebeeb362efeebec8007b7948f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2124a4fc046c3dc03d007ca949e4f9191497b359fe19fafe307ed2227c4b5654d909815575504e452add310dfc8487bfc13db94794d4b6c06a7af0bb2701e55f
|
7
|
+
data.tar.gz: 8a223332d81282eb9ad651dad887579ceb7b44a01d05ccff6458e271ea999a3c5fad5f81c87a6a2ccf927307b3bb9c4e06075361b0f8fc8b02005926a3d9a5b7
|
data/cddl.gemspec
CHANGED
data/lib/base45_lite.rb
ADDED
@@ -0,0 +1,71 @@
|
|
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
|
data/lib/cddl.rb
CHANGED
@@ -2,11 +2,13 @@ require 'abnc'
|
|
2
2
|
require 'pp'
|
3
3
|
require 'pathname'
|
4
4
|
require 'cbor-pure' unless defined?(CBOR::Tagged)
|
5
|
+
require 'cbor-deterministic'
|
5
6
|
require 'regexp-examples'
|
6
7
|
require 'abnftt'
|
7
8
|
require 'colorize'
|
8
9
|
require 'base64'
|
9
10
|
require 'base32'
|
11
|
+
require 'base45_lite'
|
10
12
|
|
11
13
|
module CDDL
|
12
14
|
|
@@ -267,6 +269,21 @@ module CDDL
|
|
267
269
|
l.map {|l| l.sub(/^ {0,#{indent}}/, "")}.join
|
268
270
|
end
|
269
271
|
|
272
|
+
def unpack_array_to_sequence(content, where)
|
273
|
+
# remove the first head
|
274
|
+
n = case content.getbyte(0) - (4 << 5)
|
275
|
+
when 0..23; 1
|
276
|
+
when 24; 2
|
277
|
+
when 25; 3
|
278
|
+
when 26; 5
|
279
|
+
when 27; 9 # unlikely :-)
|
280
|
+
else fail ".cborseq sequence for #{where} not an array"
|
281
|
+
end
|
282
|
+
content[0...n] = ''
|
283
|
+
content
|
284
|
+
end
|
285
|
+
|
286
|
+
|
270
287
|
# Memoize a bit here
|
271
288
|
|
272
289
|
REGEXP_FOR_STRING = Hash.new {|h, k|
|
@@ -561,22 +578,18 @@ module CDDL
|
|
561
578
|
end
|
562
579
|
enc = bytes ? Encoding::BINARY : Encoding::UTF_8
|
563
580
|
out.force_encoding(enc)
|
564
|
-
when :cbor, :cborseq
|
581
|
+
when :cbor, :cborseq, :cbordet, :cborseqdet
|
565
582
|
unless target == [:prim, 2]
|
566
583
|
fail "Don't know yet how to generate #{where}"
|
567
584
|
end
|
568
|
-
|
569
|
-
if conop == :
|
585
|
+
input = generate1(control)
|
586
|
+
if conop == :cbordet || conop == :cborseqdet
|
587
|
+
input = input.cbor_prepare_deterministic
|
588
|
+
end
|
589
|
+
content = CBOR::encode(input)
|
590
|
+
if conop == :cborseq || conop == :cborseqdet
|
570
591
|
# remove the first head
|
571
|
-
|
572
|
-
when 0..23; 1
|
573
|
-
when 24; 2
|
574
|
-
when 25; 3
|
575
|
-
when 26; 5
|
576
|
-
when 27; 9 # unlikely :-)
|
577
|
-
else fail "Generated .cborseq sequence for #{where} not an array"
|
578
|
-
end
|
579
|
-
content[0...n] = ''
|
592
|
+
content = unpack_array_to_sequence(content, where)
|
580
593
|
end
|
581
594
|
content
|
582
595
|
when :json
|
@@ -601,16 +614,19 @@ module CDDL
|
|
601
614
|
end
|
602
615
|
content = content.join
|
603
616
|
content
|
604
|
-
when :b64u, :
|
617
|
+
when :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
|
618
|
+
:b45, :b32, :h32, :hex, :hexlc, :hexuc
|
605
619
|
content = generate1(control)
|
606
620
|
unless String === content
|
607
621
|
fail "Don't know yet how to generate #{where}"
|
608
622
|
end
|
609
623
|
content = case conop
|
610
|
-
when :b64u
|
624
|
+
when :b64u, :"b64u-sloppy"
|
611
625
|
Base64.urlsafe_encode64(content, padding: false)
|
612
|
-
when :b64c
|
626
|
+
when :b64c, :"b64c-sloppy"
|
613
627
|
Base64.strict_encode64(content)
|
628
|
+
when :b45
|
629
|
+
Base45Lite.encode(content)
|
614
630
|
when :b32
|
615
631
|
Base32.table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
616
632
|
Base32.encode(content).gsub("=", "")
|
@@ -1040,6 +1056,22 @@ module CDDL
|
|
1040
1056
|
ann if validate1((CBOR::decode(d) rescue :BAD_CBOR), control)
|
1041
1057
|
when :cborseq
|
1042
1058
|
ann if validate1((CBOR::decode("\x9f".b << d << "\xff".b) rescue :BAD_CBOR), control)
|
1059
|
+
when :cbordet
|
1060
|
+
decoded = CBOR::decode(d) rescue :BAD_CBOR
|
1061
|
+
if d != decoded.to_deterministic_cbor
|
1062
|
+
@last_message = "CBOR #{d.inspect} not deterministically encoded"
|
1063
|
+
nil
|
1064
|
+
else
|
1065
|
+
ann if validate1(decoded, control)
|
1066
|
+
end
|
1067
|
+
when :cborseqdet
|
1068
|
+
decoded = CBOR::decode("\x9f".b << d << "\xff".b) rescue :BAD_CBOR
|
1069
|
+
if d != unpack_array_to_sequence(decoded.to_deterministic_cbor, d.inspect)
|
1070
|
+
@last_message = "CBOR Sequence #{d.inspect} not deterministically encoded"
|
1071
|
+
nil
|
1072
|
+
else
|
1073
|
+
ann if validate1(decoded, control)
|
1074
|
+
end
|
1043
1075
|
when :json
|
1044
1076
|
ann if validate1((JSON::load(d) rescue :BAD_JSON), control)
|
1045
1077
|
when :decimal
|
@@ -1060,19 +1092,26 @@ module CDDL
|
|
1060
1092
|
else
|
1061
1093
|
fail "Don't know yet how to validate against #{where}"
|
1062
1094
|
end
|
1063
|
-
when :b64u, :b64c, :b32, :h32, :hex, :hexlc, :hexuc
|
1095
|
+
when :b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy", :b45, :b32, :h32, :hex, :hexlc, :hexuc
|
1064
1096
|
ann if (
|
1065
1097
|
String === d && (
|
1066
1098
|
decoded = case conop
|
1067
1099
|
when :b64u
|
1068
1100
|
/=/ !~ d &&
|
1069
1101
|
Base64.urlsafe_decode64(d)
|
1102
|
+
when :"b64u-sloppy"
|
1103
|
+
/[-_=]/ !~ d &&
|
1104
|
+
Base64.decode64(d.tr("+/", "-_"))
|
1070
1105
|
when :b64c
|
1071
1106
|
Base64.strict_decode64(d)
|
1107
|
+
when :"b64c-sloppy"
|
1108
|
+
Base64.decode64(d)
|
1072
1109
|
when :b32
|
1073
1110
|
/=/ !~ d &&
|
1074
1111
|
(Base32.table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567") &&
|
1075
1112
|
Base32.decode(d)
|
1113
|
+
when :b45
|
1114
|
+
Base45Lite.decode(d)
|
1076
1115
|
when :h32
|
1077
1116
|
/=/ !~ d &&
|
1078
1117
|
(Base32.table = "0123456789ABCDEFGHIJKLMNOPQRSTUV") &&
|
@@ -1441,11 +1480,14 @@ module CDDL
|
|
1441
1480
|
|
1442
1481
|
BRACE = {"{" => :map, "[" => :array}
|
1443
1482
|
RANGE_EXCLUDE_END = {".." => false, "..." => true}
|
1444
|
-
SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp,
|
1483
|
+
SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp,
|
1484
|
+
:cbor, :cborseq, :cbordet, :cborseqdet,
|
1485
|
+
:within, :and,
|
1445
1486
|
:default, :lt, :le, :gt, :ge, :eq, :ne,
|
1446
1487
|
:feature, :abnf, :abnfb, :det, :cat, :plus,
|
1447
1488
|
:json, :decimal, :join,
|
1448
|
-
:b64u, :
|
1489
|
+
:b64u, :"b64u-sloppy", :b64c, :"b64c-sloppy",
|
1490
|
+
:b45, :b32, :h32, :hex, :hexlc, :hexuc,
|
1449
1491
|
]
|
1450
1492
|
|
1451
1493
|
def type1(n, canbegroup = false)
|
@@ -0,0 +1 @@
|
|
1
|
+
a = text .b64c-sloppy 'mnoabcdue=='
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cddl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cbor-diag
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- cddl.gemspec
|
120
120
|
- data/cddl.abnf
|
121
121
|
- data/prelude.cddl
|
122
|
+
- lib/base45_lite.rb
|
122
123
|
- lib/cbor-pp-play.rb
|
123
124
|
- lib/cbor-pp.rb
|
124
125
|
- lib/cddl.rb
|
@@ -133,6 +134,7 @@ files:
|
|
133
134
|
- test-data/abnf3.cddl
|
134
135
|
- test-data/ambig.cddl
|
135
136
|
- test-data/b.cddl
|
137
|
+
- test-data/b64c-sloppy.cddl
|
136
138
|
- test-data/b64c.cddl
|
137
139
|
- test-data/b64u.cddl
|
138
140
|
- test-data/badaddr.cddl
|
@@ -245,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
245
247
|
- !ruby/object:Gem::Version
|
246
248
|
version: '0'
|
247
249
|
requirements: []
|
248
|
-
rubygems_version: 3.4.
|
250
|
+
rubygems_version: 3.4.6
|
249
251
|
signing_key:
|
250
252
|
specification_version: 4
|
251
253
|
summary: CDDL generator and validator.
|