ndr_support 5.9.6 → 5.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/code_safety.yml +4 -4
- data/lib/ndr_support/version.rb +1 -1
- data/lib/ndr_support/yaml/serialization_migration.rb +39 -9
- data/test/yaml/serialization_test.rb +46 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 452da481cc47dceb02b62e7eb832db07ba61985fb2cdc8267a40b6194d0ef108
|
4
|
+
data.tar.gz: e06b9a9845389b639c2fbe55aab1f4008d6dad69843a24113bf55b2b88fd7d56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d06a0fb2e4adae1cbc71b7e89fd4fc45b527a419ad313d6440dd199ddb845df637b4dd505dce4220dae16bc6f059e96a2faddc455c1901a54bd8acba86b4b3e
|
7
|
+
data.tar.gz: d5abcaa621cf18823123cd1241a519c2c2a9dd856ac6659a9f4d4497adcd11ec4b57beeade25c7e799b9924de02736344b91ef079b2bef5a65785a41a6d20333
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
* No unreleased changes
|
3
3
|
|
4
|
+
## 5.10.0 / 2023-11-17
|
5
|
+
## Changed
|
6
|
+
* Generate UTF-8 encoded YAML by default. Disable with `utf8_storage = false`
|
7
|
+
* Use `YAML.safe_load` by default. Override with
|
8
|
+
`self.yaml_safe_classes = yaml_safe_classes + [Klass1, Klass2]` and revert to
|
9
|
+
unsafe loading with `yaml_safe_classes = :unsafe` and `gem 'psych', '< 4'`
|
10
|
+
|
11
|
+
## 5.9.7 / 2023-11-16
|
12
|
+
## Fixed
|
13
|
+
* YAMLSupport should preserve escaped backslashes in YAML text
|
14
|
+
|
4
15
|
## 5.9.6 / 2023-11-14
|
5
16
|
## Fixed
|
6
17
|
* YAMLSupport should preserve escape sequences in JSON text
|
data/code_safety.yml
CHANGED
@@ -23,7 +23,7 @@ file safety:
|
|
23
23
|
CHANGELOG.md:
|
24
24
|
comments:
|
25
25
|
reviewed_by: brian.shand
|
26
|
-
safe_revision:
|
26
|
+
safe_revision: 646eaebdf824490150e991225f9e15abb67dd4c1
|
27
27
|
CODE_OF_CONDUCT.md:
|
28
28
|
comments:
|
29
29
|
reviewed_by: timgentry
|
@@ -171,7 +171,7 @@ file safety:
|
|
171
171
|
lib/ndr_support/version.rb:
|
172
172
|
comments:
|
173
173
|
reviewed_by: brian.shand
|
174
|
-
safe_revision:
|
174
|
+
safe_revision: 765520ebaf3652bed7105995c815afe681dd5363
|
175
175
|
lib/ndr_support/working_days.rb:
|
176
176
|
comments:
|
177
177
|
reviewed_by: josh.pencheon
|
@@ -179,7 +179,7 @@ file safety:
|
|
179
179
|
lib/ndr_support/yaml/serialization_migration.rb:
|
180
180
|
comments:
|
181
181
|
reviewed_by: brian.shand
|
182
|
-
safe_revision:
|
182
|
+
safe_revision: 646eaebdf824490150e991225f9e15abb67dd4c1
|
183
183
|
ndr_support.gemspec:
|
184
184
|
comments:
|
185
185
|
reviewed_by: brian.shand
|
@@ -283,4 +283,4 @@ file safety:
|
|
283
283
|
test/yaml/serialization_test.rb:
|
284
284
|
comments:
|
285
285
|
reviewed_by: brian.shand
|
286
|
-
safe_revision:
|
286
|
+
safe_revision: 646eaebdf824490150e991225f9e15abb67dd4c1
|
data/lib/ndr_support/version.rb
CHANGED
@@ -12,8 +12,29 @@ module NdrSupport
|
|
12
12
|
# accepted by load_yaml
|
13
13
|
YAML_SAFE_CLASSES = [Date, DateTime, Time, Symbol].freeze
|
14
14
|
|
15
|
+
# Set list of YAML safe classes, or :unsafe to use unsafe load
|
16
|
+
def yaml_safe_classes=(yaml_safe_classes)
|
17
|
+
@yaml_safe_classes = yaml_safe_classes
|
18
|
+
end
|
19
|
+
|
20
|
+
def yaml_safe_classes
|
21
|
+
@yaml_safe_classes || YAML_SAFE_CLASSES
|
22
|
+
end
|
23
|
+
|
24
|
+
# Allow emitted YAML to contain UTF-8 characters
|
25
|
+
# Defaults to true. (Defaulted to false in ndr_support versions < 6)
|
26
|
+
def utf8_storage=(utf8_storage)
|
27
|
+
@utf8_storage = utf8_storage
|
28
|
+
end
|
29
|
+
|
30
|
+
def utf8_storage
|
31
|
+
return @utf8_storage if @utf8_storage == false
|
32
|
+
|
33
|
+
true # New ndr_support default for versions >= 6, previously false
|
34
|
+
end
|
35
|
+
|
15
36
|
# Wrapper around: YAML.load(string)
|
16
|
-
def load_yaml(string, coerce_invalid_chars = false)
|
37
|
+
def load_yaml(string, coerce_invalid_chars = false) # rubocop:disable Style/OptionalBooleanParameter
|
17
38
|
fix_encoding!(string, coerce_invalid_chars)
|
18
39
|
|
19
40
|
# Achieve same behaviour using `syck` and `psych`:
|
@@ -21,10 +42,14 @@ module NdrSupport
|
|
21
42
|
fix_encoding!(string, coerce_invalid_chars)
|
22
43
|
|
23
44
|
# TODO: Bump NdrSupport major version, and switch to safe_load by default
|
24
|
-
object = if
|
45
|
+
object = if yaml_safe_classes == :unsafe
|
46
|
+
unless Psych::VERSION.start_with?('3.')
|
47
|
+
raise(SecurityError, 'Unsafe YAML no longer supported')
|
48
|
+
end
|
49
|
+
|
25
50
|
Psych.load(string)
|
26
51
|
else
|
27
|
-
Psych.safe_load(string, permitted_classes:
|
52
|
+
Psych.safe_load(string, permitted_classes: yaml_safe_classes)
|
28
53
|
end
|
29
54
|
|
30
55
|
# Ensure that any string related to the object
|
@@ -37,8 +62,10 @@ module NdrSupport
|
|
37
62
|
|
38
63
|
# Wrapper around: YAML.dump(object)
|
39
64
|
def dump_yaml(object)
|
40
|
-
|
41
|
-
|
65
|
+
return Psych.dump(object) if utf8_storage
|
66
|
+
|
67
|
+
# Psych produces UTF-8 encoded output; historically we
|
68
|
+
# preferred YAML that can be safely stored in stores with
|
42
69
|
# other encodings. If #load_yaml is used, the binary
|
43
70
|
# encoding of the object will be reversed on load.
|
44
71
|
Psych.dump binary_encode_any_high_ascii(object)
|
@@ -56,14 +83,17 @@ module NdrSupport
|
|
56
83
|
# Within double quotes, YAML allows special characters.
|
57
84
|
# While `psych` emits UTF-8 YAML, `syck` double escapes
|
58
85
|
# higher characters. We need to unescape any we find:
|
86
|
+
# Both `psych` and `syck` escape lower control characters.
|
59
87
|
def handle_special_characters!(string, coerce_invalid_chars)
|
60
|
-
# TODO: Change to only handle syck control characters
|
61
88
|
return unless string.start_with?('---') # Only handle YAML that is not JSON
|
62
89
|
|
63
90
|
# Replace any encoded hex chars with their actual value:
|
64
|
-
string.gsub!(/((?:\\x[0-9A-F]{2})+)/) do
|
65
|
-
|
66
|
-
|
91
|
+
string.gsub!(/(?<!\\)((?:\\\\)*)((?:\\x[0-9A-F]{2})+)/) do
|
92
|
+
# We use negative lookbehind and the first capturing group to skip over
|
93
|
+
# properly escaped backslashes
|
94
|
+
prefix = ::Regexp.last_match(1) # Prefix is an even number of backslashes
|
95
|
+
byte_sequence = ::Regexp.last_match(2).scan(/[0-9A-F]{2}/)
|
96
|
+
prefix + byte_sequence.pack('H2' * byte_sequence.length).tap do |sequence|
|
67
97
|
fix_encoding!(sequence, coerce_invalid_chars)
|
68
98
|
end
|
69
99
|
end
|
@@ -29,8 +29,14 @@ class SerializationTest < Minitest::Test
|
|
29
29
|
assert_equal "control 0x01 char \n whoops!", load_yaml(chr_1_yaml)
|
30
30
|
end
|
31
31
|
|
32
|
+
test 'should handle non-binary yaml with escaped things that look like control chars' do
|
33
|
+
# irb> Psych.dump(['\\x01 \\xAF \\\\xAF', "\x01 \\\x01 \x01\\\x01"])
|
34
|
+
escaped_yaml = "---\n- \"\\\\x01 \\\\xAF \\\\\\\\xAF\"\n- \"\\x01 \\\\\\x01 \\x01\\\\\\x01\"\n"
|
35
|
+
assert_equal ['\\x01 \\xAF \\\\xAF', '0x01 \\0x01 0x01\\0x01'], load_yaml(escaped_yaml)
|
36
|
+
end
|
37
|
+
|
32
38
|
test 'should leave non-binary JSON with things that look like control chars unchanged' do
|
33
|
-
hash = { 'report' => ' \
|
39
|
+
hash = { 'report' => ' \x01 ' }
|
34
40
|
assert_equal hash, load_yaml(hash.to_json)
|
35
41
|
end
|
36
42
|
|
@@ -38,26 +44,60 @@ class SerializationTest < Minitest::Test
|
|
38
44
|
assert_yaml_coercion_behaviour
|
39
45
|
end
|
40
46
|
|
41
|
-
test 'dump_yaml should produce encoding-portable YAML' do
|
42
|
-
|
47
|
+
test 'dump_yaml with utf8_storage = false should produce encoding-portable YAML' do
|
48
|
+
self.utf8_storage = false
|
49
|
+
original_object = { basic: 'manana', complex: 'mañana' }
|
43
50
|
yaml_produced = dump_yaml(original_object)
|
44
51
|
reloaded_object = load_yaml(yaml_produced)
|
45
52
|
|
46
|
-
|
53
|
+
assert_match(/basic: manana/, yaml_produced, 'binary-encoded more than was necessary')
|
47
54
|
|
48
55
|
refute yaml_produced.bytes.detect { |byte| byte > 127 }, 'yaml has high-ascii'
|
49
56
|
assert reloaded_object.inspect.bytes.detect { |byte| byte > 127 }
|
50
57
|
assert_equal original_object, reloaded_object
|
51
58
|
end
|
52
59
|
|
53
|
-
test 'encoding-portable YAML should be loadable' do
|
54
|
-
|
60
|
+
test 'encoding-portable YAML with utf8_storage = false should be loadable' do
|
61
|
+
self.utf8_storage = false
|
62
|
+
original_object = { basic: 'manana', complex: 'mañana' }
|
63
|
+
yaml_produced = dump_yaml(original_object)
|
64
|
+
|
65
|
+
assert_equal("---\n:basic: manana\n:complex: !binary |-\n bWHDsWFuYQ==\n", yaml_produced)
|
66
|
+
|
67
|
+
reloaded_object = load_yaml(yaml_produced)
|
68
|
+
assert_equal original_object, reloaded_object
|
69
|
+
end
|
70
|
+
|
71
|
+
test 'non-encoding-portable YAML with utf8_storage = true should be loadable' do
|
72
|
+
self.utf8_storage = true
|
73
|
+
original_object = { basic: 'manana', complex: 'mañana' }
|
55
74
|
yaml_produced = dump_yaml(original_object)
|
75
|
+
assert_equal("---\n:basic: manana\n:complex: mañana\n", yaml_produced)
|
56
76
|
|
57
77
|
reloaded_object = load_yaml(yaml_produced)
|
58
78
|
assert_equal original_object, reloaded_object
|
59
79
|
end
|
60
80
|
|
81
|
+
test 'yaml_safe_classes should filter which classes can be loaded' do
|
82
|
+
original_object = { basic: 'manana', complex: 'mañana' }
|
83
|
+
yaml_produced = dump_yaml(original_object)
|
84
|
+
self.yaml_safe_classes = []
|
85
|
+
assert_raises Psych::DisallowedClass, 'Load should fail without Symbol in yaml_safe_classes' do
|
86
|
+
load_yaml(yaml_produced)
|
87
|
+
end
|
88
|
+
|
89
|
+
self.yaml_safe_classes = [Symbol]
|
90
|
+
reloaded_object = load_yaml(yaml_produced)
|
91
|
+
assert_equal original_object, reloaded_object, 'Safe reload with Symbol class specified'
|
92
|
+
|
93
|
+
if Psych::VERSION.start_with?('3.')
|
94
|
+
# Not supported with Ruby >= 3.1 unless you force psych version < 4
|
95
|
+
self.yaml_safe_classes = :unsafe
|
96
|
+
reloaded_object = load_yaml(yaml_produced)
|
97
|
+
assert_equal original_object, reloaded_object, 'Unsafe reload with Symbol class'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
61
101
|
test 'time-like objects should serialise correctly with psych' do
|
62
102
|
assert_timey_wimey_stuff
|
63
103
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ndr_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NCRS Development Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|