tinycode 0.1.1 → 0.2.0
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/.rubocop.yml +2 -0
- data/Gemfile.lock +8 -5
- data/README.md +3 -4
- data/Rakefile +7 -2
- data/bin/acid_test.rb +35 -0
- data/lib/tinycode/module.rb +33 -14
- data/lib/tinycode/version.rb +1 -1
- data/tinycode.gemspec +17 -16
- metadata +14 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e5a75ffceb25e155db277a905e940cbf22a3f43a666113aede98b5457176aca
|
4
|
+
data.tar.gz: f095520fdf8e46c939f7937957fb831951118d11ebef414a8d08bbee86b1a331
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5146523a4517a8effb28f426c6922cb0338ec6a66de0a545b75385551e9a2ed0158e5292f8af441f15c1888cff7deb99e6e9550e029f26e3e7e5a16519a80255
|
7
|
+
data.tar.gz: 0ad1a83f8c3f5d2a3ddbe5639d23e618a3dc4988825740d52ded2077188b5c373ce644b75b829be49fa0128fdad705fa690cc6b1107e4b0a0427361c3691bfa8
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tinycode (0.
|
4
|
+
tinycode (0.2.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -14,14 +14,14 @@ GEM
|
|
14
14
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
15
15
|
rb-inotify (~> 0.9, >= 0.9.10)
|
16
16
|
parallel (1.21.0)
|
17
|
-
parser (3.0.
|
17
|
+
parser (3.0.3.1)
|
18
18
|
ast (~> 2.4.1)
|
19
19
|
rainbow (3.0.0)
|
20
20
|
rake (13.0.6)
|
21
21
|
rb-fsevent (0.11.0)
|
22
22
|
rb-inotify (0.10.1)
|
23
23
|
ffi (~> 1.0)
|
24
|
-
regexp_parser (2.
|
24
|
+
regexp_parser (2.2.0)
|
25
25
|
rerun (0.13.1)
|
26
26
|
listen (~> 3.0)
|
27
27
|
rexml (3.2.5)
|
@@ -47,7 +47,7 @@ GEM
|
|
47
47
|
rubocop-ast (>= 1.12.0, < 2.0)
|
48
48
|
ruby-progressbar (~> 1.7)
|
49
49
|
unicode-display_width (>= 1.4.0, < 3.0)
|
50
|
-
rubocop-ast (1.
|
50
|
+
rubocop-ast (1.14.0)
|
51
51
|
parser (>= 3.0.1.1)
|
52
52
|
rubocop-rake (0.6.0)
|
53
53
|
rubocop (~> 1.0)
|
@@ -61,10 +61,13 @@ GEM
|
|
61
61
|
simplecov-html (0.12.3)
|
62
62
|
simplecov_json_formatter (0.1.3)
|
63
63
|
unicode-display_width (2.1.0)
|
64
|
-
|
64
|
+
webrick (1.7.0)
|
65
|
+
yard (0.9.27)
|
66
|
+
webrick (~> 1.7.0)
|
65
67
|
|
66
68
|
PLATFORMS
|
67
69
|
x86_64-darwin-19
|
70
|
+
x86_64-linux
|
68
71
|
|
69
72
|
DEPENDENCIES
|
70
73
|
rake (~> 13.0)
|
data/README.md
CHANGED
@@ -85,13 +85,13 @@ gem 'tinycode'
|
|
85
85
|
And then execute:
|
86
86
|
|
87
87
|
```sh
|
88
|
-
|
88
|
+
bundle install
|
89
89
|
```
|
90
90
|
|
91
91
|
Or install it yourself as:
|
92
92
|
|
93
93
|
```sh
|
94
|
-
|
94
|
+
gem install tinycode
|
95
95
|
```
|
96
96
|
|
97
97
|
## Usage
|
@@ -148,8 +148,7 @@ copyright dates.
|
|
148
148
|
|
149
149
|
This program is free software: you can redistribute it and/or modify
|
150
150
|
it under the terms of the GNU General Public License as published by
|
151
|
-
the Free Software Foundation,
|
152
|
-
(at your option) any later version.
|
151
|
+
the Free Software Foundation, version 3.
|
153
152
|
|
154
153
|
This program is distributed in the hope that it will be useful,
|
155
154
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
data/Rakefile
CHANGED
@@ -12,8 +12,13 @@ RuboCop::RakeTask.new(:lint) do |task|
|
|
12
12
|
end
|
13
13
|
YARD::Rake::YardocTask.new
|
14
14
|
|
15
|
-
task :
|
16
|
-
sh '
|
15
|
+
task :dev do
|
16
|
+
sh 'bundle install'
|
17
|
+
sh 'rerun -p "{**/*.{rb,gemspec},exe/**/*,Gemfile*,Rakefile}" -x rake yard spec'
|
18
|
+
end
|
19
|
+
|
20
|
+
task :autofixlint do
|
21
|
+
sh 'rerun -p "{**/*.{rb,gemspec},exe/**/*,Gemfile*,Rakefile}" -x rake lint:auto_correct'
|
17
22
|
end
|
18
23
|
|
19
24
|
task default: [:spec, :lint]
|
data/bin/acid_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
require_relative '../lib/tinycode'
|
5
|
+
|
6
|
+
ITERATIONS = 100_000
|
7
|
+
MAX_INPUT_LENGTH = 4096
|
8
|
+
|
9
|
+
MAX_INPUT_LENGTH.times do |input_length|
|
10
|
+
results = []
|
11
|
+
ITERATIONS.times do
|
12
|
+
input = SecureRandom.bytes(input_length)
|
13
|
+
begin
|
14
|
+
Tinycode.load(input)
|
15
|
+
results << 'Success'
|
16
|
+
rescue Tinycode::ParseError => e
|
17
|
+
results <<
|
18
|
+
if e.message =~ /\AUnexpected character: /
|
19
|
+
'Unexpected character: ...'
|
20
|
+
else
|
21
|
+
e.message
|
22
|
+
end
|
23
|
+
rescue Error
|
24
|
+
warn "Attempted to parse #{input.inspect} but got unexpected error:"
|
25
|
+
raise
|
26
|
+
end
|
27
|
+
end
|
28
|
+
puts "==== For inputs of length #{input_length}:"
|
29
|
+
results.tally.to_a.sort_by(&:last).each do |result, times|
|
30
|
+
puts "#{result} x#{times}"
|
31
|
+
end
|
32
|
+
puts
|
33
|
+
end
|
34
|
+
|
35
|
+
puts "Congratulations! Was unable to find a vector that results in an unexpected error for sizes <= #{MAX_INPUT_LENGTH}"
|
data/lib/tinycode/module.rb
CHANGED
@@ -28,17 +28,25 @@ module Tinycode
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def load(tinycode)
|
31
|
-
|
32
|
-
|
33
|
-
tinycode = tinycode.to_str.b
|
31
|
+
tinycode = implicitly_convert_str(tinycode).b
|
34
32
|
struct, length = load_with_length(tinycode)
|
35
|
-
raise
|
33
|
+
raise 'a load_ implementation claims it read past the end of stream!' if length > tinycode.length
|
34
|
+
raise ParseError, 'Stream is longer than expected' if length < tinycode.length
|
36
35
|
|
37
36
|
struct
|
38
37
|
end
|
39
38
|
|
40
39
|
private
|
41
40
|
|
41
|
+
def implicitly_convert_str(obj)
|
42
|
+
raise ArgumentError, "Cannot convert #{obj.class} to String" if !obj.respond_to?(:to_str)
|
43
|
+
|
44
|
+
str = obj.to_str
|
45
|
+
raise ArgumentError, "#{obj.class}#to_str did not return String, got #{str.class}" if !str.is_a?(String)
|
46
|
+
|
47
|
+
str
|
48
|
+
end
|
49
|
+
|
42
50
|
def load_with_length(tinycode)
|
43
51
|
case tinycode[0]
|
44
52
|
when /[\w \t\n]/ then load_id(tinycode)
|
@@ -53,7 +61,8 @@ module Tinycode
|
|
53
61
|
when '#' then load_fixed_integer(tinycode, U64, length: 8, unpack: 'Q>')
|
54
62
|
when "\0" then [nil, 1]
|
55
63
|
when '?' then load_boolean(tinycode)
|
56
|
-
|
64
|
+
when nil then raise ParseError, 'Unexpected end of stream'
|
65
|
+
else raise ParseError, "Unexpected character: #{tinycode[0].inspect}"
|
57
66
|
end
|
58
67
|
end
|
59
68
|
|
@@ -93,7 +102,7 @@ module Tinycode
|
|
93
102
|
|
94
103
|
def dump_string(str, code: "'")
|
95
104
|
str = str.encode('UTF-8').b unless str.encoding == Encoding::ASCII_8BIT
|
96
|
-
if str =~ /\A[\w \t\n]
|
105
|
+
if str =~ /\A[\w \t\n][^':]*\z/
|
97
106
|
[str, code].pack('a*a')
|
98
107
|
else
|
99
108
|
[code, str.length, str].pack('awa*')
|
@@ -102,18 +111,23 @@ module Tinycode
|
|
102
111
|
|
103
112
|
def load_id(tinycode)
|
104
113
|
length = tinycode.index(/[':]/)
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
114
|
+
raise ParseError, 'Unexpected end of stream' if !length
|
115
|
+
|
116
|
+
value = tinycode[0...length].force_encoding('UTF-8')
|
117
|
+
raise ParseError, 'invalid byte sequence in UTF-8 string' if !value.valid_encoding?
|
118
|
+
|
119
|
+
value = value.to_sym if tinycode[length] == ':'
|
111
120
|
[value, length + 1]
|
112
121
|
end
|
113
122
|
|
114
123
|
def load_string(tinycode)
|
115
124
|
str_length, offset = load_varint(tinycode[1..])
|
116
|
-
|
125
|
+
raise ParseError, 'Unexpected end of stream' if tinycode.length < 1 + offset + str_length
|
126
|
+
|
127
|
+
str = tinycode[(1 + offset)...(1 + offset + str_length)].force_encoding('UTF-8')
|
128
|
+
raise ParseError, 'invalid byte sequence in UTF-8 string' if !str.valid_encoding?
|
129
|
+
|
130
|
+
[str, 1 + offset + str_length]
|
117
131
|
end
|
118
132
|
|
119
133
|
def dump_symbol(sym)
|
@@ -136,6 +150,7 @@ module Tinycode
|
|
136
150
|
def load_integer(tinycode)
|
137
151
|
value, offset = load_varint(tinycode[1..])
|
138
152
|
value = -value if tinycode[0] == '-'
|
153
|
+
raise ParseError, '-0 is not a valid integer' if value == 0 && tinycode[0] == '-'
|
139
154
|
|
140
155
|
[value, 1 + offset]
|
141
156
|
end
|
@@ -145,11 +160,15 @@ module Tinycode
|
|
145
160
|
end
|
146
161
|
|
147
162
|
def load_fixed_integer(tinycode, clazz, length:, unpack:)
|
163
|
+
raise ParseError, 'Unexpected end of stream' if tinycode.length < length + 1
|
164
|
+
|
148
165
|
[clazz.new(tinycode[1...(1 + length)].unpack1(unpack)), 1 + length]
|
149
166
|
end
|
150
167
|
|
151
168
|
def load_varint(tinycode)
|
152
169
|
length = tinycode.each_byte.lazy.take_while {|b| b > 0x7F }.count + 1
|
170
|
+
raise ParseError, 'Unexpected end of stream' if length > tinycode.length
|
171
|
+
|
153
172
|
[tinycode[0...length].unpack1('w'), length]
|
154
173
|
end
|
155
174
|
|
@@ -157,7 +176,7 @@ module Tinycode
|
|
157
176
|
case tinycode[1]
|
158
177
|
when 'T' then [true, 2]
|
159
178
|
when 'F' then [false, 2]
|
160
|
-
else raise ParseError, 'Malformed boolean'
|
179
|
+
else raise ParseError, 'Malformed boolean value'
|
161
180
|
end
|
162
181
|
end
|
163
182
|
end
|
data/lib/tinycode/version.rb
CHANGED
data/tinycode.gemspec
CHANGED
@@ -3,20 +3,24 @@
|
|
3
3
|
require_relative 'lib/tinycode/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name
|
7
|
-
spec.version
|
8
|
-
spec.summary
|
9
|
-
spec.description =
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
spec.
|
14
|
-
spec.
|
15
|
-
spec.
|
16
|
-
# spec.metadata['changelog_uri'] =
|
6
|
+
spec.name = 'tinycode'
|
7
|
+
spec.version = Tinycode::VERSION
|
8
|
+
spec.summary = 'An encoder and decoder for tinycode'
|
9
|
+
spec.description = <<~DESCRIPTION
|
10
|
+
tinycode is a bencode like encoding that supports more data-types
|
11
|
+
and slightly smaller encoded sizes.
|
12
|
+
DESCRIPTION
|
13
|
+
spec.author = 'Alex Gittemeier'
|
14
|
+
spec.email = 'me@a.lexg.dev'
|
15
|
+
spec.license = 'GPL-3.0-only'
|
17
16
|
|
18
|
-
spec.
|
19
|
-
spec.metadata['
|
17
|
+
spec.metadata['homepage_uri'] = 'https://gitlab.com/windows93/tinycode'
|
18
|
+
spec.metadata['source_code_uri'] = 'https://gitlab.com/windows93/tinycode/-/tree/stable'
|
19
|
+
spec.metadata['documentation_uri'] = 'https://www.rubydoc.info/gems/tinycode/'
|
20
|
+
spec.metadata['bug_tracker_uri'] = 'https://gitlab.com/windows93/tinycode/-/issues'
|
21
|
+
spec.metadata['changelog_uri'] = 'https://gitlab.com/windows93/tinycode/-/commits/stable'
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
23
|
+
spec.homepage = spec.metadata['homepage_uri']
|
20
24
|
|
21
25
|
# Specify which files should be added to the gem when it is released.
|
22
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -25,9 +29,6 @@ Gem::Specification.new do |spec|
|
|
25
29
|
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
26
30
|
end
|
27
31
|
end
|
28
|
-
spec.bindir = 'exe'
|
29
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) {|f| File.basename(f) }
|
30
|
-
spec.require_paths = ['lib']
|
31
32
|
|
32
33
|
spec.required_ruby_version = '>= 2.6.0'
|
33
34
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tinycode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Gittemeier
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -122,10 +122,10 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0.9'
|
125
|
-
description:
|
126
|
-
|
127
|
-
|
128
|
-
|
125
|
+
description: |
|
126
|
+
tinycode is a bencode like encoding that supports more data-types
|
127
|
+
and slightly smaller encoded sizes.
|
128
|
+
email: me@a.lexg.dev
|
129
129
|
executables: []
|
130
130
|
extensions: []
|
131
131
|
extra_rdoc_files: []
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- LICENSE
|
139
139
|
- README.md
|
140
140
|
- Rakefile
|
141
|
+
- bin/acid_test.rb
|
141
142
|
- lib/tinycode.rb
|
142
143
|
- lib/tinycode/core_ext.rb
|
143
144
|
- lib/tinycode/fixed_integer.rb
|
@@ -147,11 +148,14 @@ files:
|
|
147
148
|
- tinycode.gemspec
|
148
149
|
homepage: https://gitlab.com/windows93/tinycode
|
149
150
|
licenses:
|
150
|
-
- GPL-3.0
|
151
|
+
- GPL-3.0-only
|
151
152
|
metadata:
|
152
|
-
source_code_uri: https://gitlab.com/windows93/tinycode
|
153
|
-
rubygems_mfa_required: 'true'
|
154
153
|
homepage_uri: https://gitlab.com/windows93/tinycode
|
154
|
+
source_code_uri: https://gitlab.com/windows93/tinycode/-/tree/stable
|
155
|
+
documentation_uri: https://www.rubydoc.info/gems/tinycode/
|
156
|
+
bug_tracker_uri: https://gitlab.com/windows93/tinycode/-/issues
|
157
|
+
changelog_uri: https://gitlab.com/windows93/tinycode/-/commits/stable
|
158
|
+
rubygems_mfa_required: 'true'
|
155
159
|
post_install_message:
|
156
160
|
rdoc_options: []
|
157
161
|
require_paths:
|