multi_json 1.20.0-java → 1.20.1-java

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 655af0021178ca97de8ee1cba9d1030d1927000488f97ada84aa9880eb975bfe
4
- data.tar.gz: f912b91f94dd636544461efa0326ef6d221932ffb3231e899713e93053151a01
3
+ metadata.gz: 634ced36b2a9427f21420de9dd7cdaf89db7c639552666151a4d43ceebb3223e
4
+ data.tar.gz: 147682bd527b367f21765a5de9f17c5f980b06aded3aee749b65e16647d0a635
5
5
  SHA512:
6
- metadata.gz: 34d70e95e9a5511897e7981cbf72bc76de574ad0367c6ab0560eca4380be17658918a05455fb1574dd5ac7e667f05c39fa73bd3959be231dba008f860024afd9
7
- data.tar.gz: c0ec70d897dbd2da1c5757ffd503cafcc4321a28fb4acd0ad8195b720159f3a31a7b4ed7325fd87bea46ceb315ca563d3018dbb8a30c4cd625049f5305ca469b
6
+ metadata.gz: '07269879d9521ae2cc8b41cfa8e8b91514bccdb86fc35f32d6318cac160885e1d769452914988de015ef15a2a0fca768fc5d8e4b413389d29c75d4194ef76abe'
7
+ data.tar.gz: 9030ba9532f7b96b49bc381f1bb43b25c4e5efe8a51f05ab8d64f12b979cd422bcebf2bb78456184c2c1a1091839d5bb84018a011358087fb6b6b6969144c7b0
data/CHANGELOG.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
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 contains invalid bytes that
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
- begin
37
- string = string.encode(Encoding::UTF_8)
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
- attr_accessor :max_cache_size
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
  #
@@ -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 = 0 unless defined? MultiJson::Version::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.0
4
+ version: 1.20.1
5
5
  platform: java
6
6
  authors:
7
7
  - Michael Bleigh
@@ -61,10 +61,10 @@ licenses:
61
61
  - MIT
62
62
  metadata:
63
63
  bug_tracker_uri: https://github.com/sferik/multi_json/issues
64
- changelog_uri: https://github.com/sferik/multi_json/blob/v1.20.0/CHANGELOG.md
65
- documentation_uri: https://www.rubydoc.info/gems/multi_json/1.20.0
64
+ changelog_uri: https://github.com/sferik/multi_json/blob/v1.20.1/CHANGELOG.md
65
+ documentation_uri: https://www.rubydoc.info/gems/multi_json/1.20.1
66
66
  rubygems_mfa_required: 'true'
67
- source_code_uri: https://github.com/sferik/multi_json/tree/v1.20.0
67
+ source_code_uri: https://github.com/sferik/multi_json/tree/v1.20.1
68
68
  wiki_uri: https://github.com/sferik/multi_json/wiki
69
69
  rdoc_options: []
70
70
  require_paths: