multi_json 1.20.0 → 1.20.1
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/CHANGELOG.md +4 -1
- data/README.md +3 -0
- data/lib/multi_json/adapter_selector.rb +21 -1
- data/lib/multi_json/adapters/json_gem.rb +11 -7
- data/lib/multi_json/options_cache.rb +15 -1
- data/lib/multi_json/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fbba8097011550d30c5962bdd828a95b431ab54cc9a6d831844e78c78f2ddc74
|
|
4
|
+
data.tar.gz: 767ba488de4f71c7503d69126130b88d904f656ec12cd2b0c039a1d66c39e594
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a0e46b45475da5fa524fdfc00c02b10bf9a3c677d3702bf81fa1bfaef278dc219a7720f082cc1a8edbc5fe07e2aa83e92a87ec2a7057a42edabd90a211fde34e
|
|
7
|
+
data.tar.gz: 650953b9efc5ba89c84cb751c206972e8d95923c5b466558a97c340666a31b71645943e83b0186076cbf9a843da3dd306c3fdb654911873797bedf89e763e7d7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 1.20.1
|
|
4
|
+
* Fix `JsonGem#load` raising `ParseError` on ASCII-8BIT strings that contain valid UTF-8 bytes ([#64](https://github.com/sferik/multi_json/issues/64)). Ruby HTTP clients tag response bodies as ASCII-8BIT by default; the 1.20.0 change from `force_encoding` to `encode` broke the dominant real-world case by trying to transcode each byte individually. Switch back to `force_encoding` followed by a `valid_encoding?` guard so genuinely invalid byte sequences still surface as `ParseError`.
|
|
5
|
+
* Validate custom adapters during `MultiJson.use` and `MultiJson.load`/`dump` with an `:adapter` option, raising `MultiJson::AdapterError` immediately if the adapter does not respond to `.load`, `.dump`, or define a `ParseError` constant.
|
|
6
|
+
* Validate `OptionsCache.max_cache_size=` to reject `nil`, zero, negative, and non-integer values with a clear `ArgumentError`.
|
|
4
7
|
|
|
5
8
|
## 1.20.0
|
|
6
9
|
* Drop the `UnannotatedEmptyCollection` Steep diagnostic override by inline-annotating `Options::EMPTY_OPTIONS` with `#: options` and routing `MultiJson.current_adapter`'s `||=` fallback through that constant. Also enable rubocop's `Layout/LeadingCommentSpace` `AllowSteepAnnotation` / `AllowRBSInlineAnnotation` so future inline `#:` casts don't need a per-line disable.
|
data/README.md
CHANGED
|
@@ -55,6 +55,9 @@ can raise the ceiling at runtime:
|
|
|
55
55
|
MultiJson::OptionsCache.max_cache_size = 5000
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
`max_cache_size` must be a positive integer; `0`, negative values, and
|
|
59
|
+
non-integers raise `ArgumentError`.
|
|
60
|
+
|
|
58
61
|
Lowering the limit only takes effect for *new* inserts; existing cache
|
|
59
62
|
entries are left in place until normal eviction trims them below the
|
|
60
63
|
new ceiling. Call `MultiJson::OptionsCache.reset` if you want to evict
|
|
@@ -142,13 +142,14 @@ module MultiJson
|
|
|
142
142
|
# @param adapter_spec [Symbol, String, Module, nil, false] adapter specification
|
|
143
143
|
# @return [Class] the adapter class
|
|
144
144
|
def load_adapter(adapter_spec)
|
|
145
|
-
case adapter_spec
|
|
145
|
+
adapter = case adapter_spec
|
|
146
146
|
when ::String then load_adapter_by_name(adapter_spec)
|
|
147
147
|
when ::Symbol then load_adapter_by_name(adapter_spec.to_s)
|
|
148
148
|
when nil, false then load_adapter(default_adapter)
|
|
149
149
|
when ::Module then adapter_spec
|
|
150
150
|
else raise ::LoadError, "expected adapter to be a Symbol, String, or Module, got #{adapter_spec.inspect}"
|
|
151
151
|
end
|
|
152
|
+
validate_adapter!(adapter)
|
|
152
153
|
rescue ::LoadError => e
|
|
153
154
|
raise AdapterError.build(e)
|
|
154
155
|
end
|
|
@@ -170,5 +171,24 @@ module MultiJson
|
|
|
170
171
|
class_name = normalized.split("_").map(&:capitalize).join
|
|
171
172
|
::MultiJson::Adapters.const_get(class_name)
|
|
172
173
|
end
|
|
174
|
+
|
|
175
|
+
# Validate that an adapter satisfies the documented contract
|
|
176
|
+
#
|
|
177
|
+
# Custom adapters are accepted as modules/classes, so fail fast
|
|
178
|
+
# during adapter resolution rather than later on the first load or
|
|
179
|
+
# dump call.
|
|
180
|
+
#
|
|
181
|
+
# @api private
|
|
182
|
+
# @param adapter [Module] adapter class or module
|
|
183
|
+
# @return [Module] the validated adapter
|
|
184
|
+
# @raise [AdapterError] when the adapter is missing a required class method
|
|
185
|
+
# or ParseError constant
|
|
186
|
+
def validate_adapter!(adapter)
|
|
187
|
+
raise AdapterError, "Adapter #{adapter} must respond to .load" unless adapter.respond_to?(:load)
|
|
188
|
+
raise AdapterError, "Adapter #{adapter} must respond to .dump" unless adapter.respond_to?(:dump)
|
|
189
|
+
|
|
190
|
+
MultiJson.parse_error_class_for(adapter)
|
|
191
|
+
adapter
|
|
192
|
+
end
|
|
173
193
|
end
|
|
174
194
|
end
|
|
@@ -22,22 +22,26 @@ module MultiJson
|
|
|
22
22
|
|
|
23
23
|
# Parse a JSON string into a Ruby object
|
|
24
24
|
#
|
|
25
|
+
# Non-UTF-8 strings are re-labeled via ``force_encoding`` (not
|
|
26
|
+
# transcoded) and then validated. This handles the dominant
|
|
27
|
+
# real-world case: Ruby HTTP libraries return response bodies
|
|
28
|
+
# tagged as ``ASCII-8BIT`` even when the bytes are valid UTF-8.
|
|
29
|
+
# ``encode(Encoding::UTF_8)`` would raise on any multi-byte
|
|
30
|
+
# sequence in that scenario because it tries to transcode each
|
|
31
|
+
# byte individually from ASCII-8BIT to UTF-8.
|
|
32
|
+
#
|
|
25
33
|
# @api private
|
|
26
34
|
# @param string [String] JSON string to parse
|
|
27
35
|
# @param options [Hash] parsing options
|
|
28
36
|
# @return [Object] parsed Ruby object
|
|
29
|
-
# @raise [::JSON::ParserError] when input
|
|
30
|
-
# cannot be transcoded to UTF-8
|
|
37
|
+
# @raise [::JSON::ParserError] when the input is not valid UTF-8
|
|
31
38
|
#
|
|
32
39
|
# @example Parse JSON string
|
|
33
40
|
# adapter.load('{"key":"value"}') #=> {"key" => "value"}
|
|
34
41
|
def load(string, options = {})
|
|
35
42
|
if string.encoding != Encoding::UTF_8
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError => e
|
|
39
|
-
raise ::JSON::ParserError, e.message
|
|
40
|
-
end
|
|
43
|
+
string = string.dup.force_encoding(Encoding::UTF_8)
|
|
44
|
+
raise ::JSON::ParserError, "Invalid UTF-8 byte sequence in JSON input" unless string.valid_encoding?
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
::JSON.parse(string, translate_load_options(options))
|
|
@@ -41,7 +41,21 @@ module MultiJson
|
|
|
41
41
|
# @example
|
|
42
42
|
# MultiJson::OptionsCache.max_cache_size = 5000
|
|
43
43
|
# MultiJson::OptionsCache.max_cache_size #=> 5000
|
|
44
|
-
|
|
44
|
+
attr_reader :max_cache_size
|
|
45
|
+
|
|
46
|
+
# Set the maximum number of entries per cache store
|
|
47
|
+
#
|
|
48
|
+
# @api public
|
|
49
|
+
# @param value [Integer] positive entry cap
|
|
50
|
+
# @return [Integer] the validated value
|
|
51
|
+
# @raise [ArgumentError] when value is not a positive Integer
|
|
52
|
+
# @example
|
|
53
|
+
# MultiJson::OptionsCache.max_cache_size = 5000
|
|
54
|
+
def max_cache_size=(value)
|
|
55
|
+
raise ArgumentError, "max_cache_size must be a positive Integer, got #{value.inspect}" unless Integer === value && value.positive? # rubocop:disable Style/CaseEquality
|
|
56
|
+
|
|
57
|
+
@max_cache_size = value
|
|
58
|
+
end
|
|
45
59
|
|
|
46
60
|
# Reset both caches
|
|
47
61
|
#
|
data/lib/multi_json/version.rb
CHANGED
|
@@ -10,7 +10,7 @@ module MultiJson
|
|
|
10
10
|
# Minor version number
|
|
11
11
|
MINOR = 20 unless defined? MultiJson::Version::MINOR
|
|
12
12
|
# Patch version number
|
|
13
|
-
PATCH =
|
|
13
|
+
PATCH = 1 unless defined? MultiJson::Version::PATCH
|
|
14
14
|
# Pre-release version suffix
|
|
15
15
|
PRE = nil unless defined? MultiJson::Version::PRE
|
|
16
16
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: multi_json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.20.
|
|
4
|
+
version: 1.20.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Bleigh
|
|
@@ -45,10 +45,10 @@ licenses:
|
|
|
45
45
|
- MIT
|
|
46
46
|
metadata:
|
|
47
47
|
bug_tracker_uri: https://github.com/sferik/multi_json/issues
|
|
48
|
-
changelog_uri: https://github.com/sferik/multi_json/blob/v1.20.
|
|
49
|
-
documentation_uri: https://www.rubydoc.info/gems/multi_json/1.20.
|
|
48
|
+
changelog_uri: https://github.com/sferik/multi_json/blob/v1.20.1/CHANGELOG.md
|
|
49
|
+
documentation_uri: https://www.rubydoc.info/gems/multi_json/1.20.1
|
|
50
50
|
rubygems_mfa_required: 'true'
|
|
51
|
-
source_code_uri: https://github.com/sferik/multi_json/tree/v1.20.
|
|
51
|
+
source_code_uri: https://github.com/sferik/multi_json/tree/v1.20.1
|
|
52
52
|
wiki_uri: https://github.com/sferik/multi_json/wiki
|
|
53
53
|
rdoc_options: []
|
|
54
54
|
require_paths:
|