json 2.7.2-java → 2.7.3-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.
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSON
4
+ module Ext
5
+ module Generator
6
+ class State
7
+ # call-seq: new(opts = {})
8
+ #
9
+ # Instantiates a new State object, configured by _opts_.
10
+ #
11
+ # _opts_ can have the following keys:
12
+ #
13
+ # * *indent*: a string used to indent levels (default: ''),
14
+ # * *space*: a string that is put after, a : or , delimiter (default: ''),
15
+ # * *space_before*: a string that is put before a : pair delimiter (default: ''),
16
+ # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
17
+ # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
18
+ # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
19
+ # generated, otherwise an exception is thrown, if these values are
20
+ # encountered. This options defaults to false.
21
+ # * *ascii_only*: true if only ASCII characters should be generated. This
22
+ # option defaults to false.
23
+ # * *buffer_initial_length*: sets the initial length of the generator's
24
+ # internal buffer.
25
+ def initialize(opts = nil)
26
+ if opts && !opts.empty?
27
+ configure(opts)
28
+ end
29
+ end
30
+
31
+ # call-seq: configure(opts)
32
+ #
33
+ # Configure this State instance with the Hash _opts_, and return
34
+ # itself.
35
+ def configure(opts)
36
+ unless opts.is_a?(Hash)
37
+ if opts.respond_to?(:to_hash)
38
+ opts = opts.to_hash
39
+ elsif opts.respond_to?(:to_h)
40
+ opts = opts.to_h
41
+ else
42
+ raise TypeError, "can't convert #{opts.class} into Hash"
43
+ end
44
+ end
45
+
46
+ opts.each do |key, value|
47
+ case key
48
+ when :indent
49
+ self.indent = value
50
+ when :space
51
+ self.space = value
52
+ when :space_before
53
+ self.space_before = value
54
+ when :array_nl
55
+ self.array_nl = value
56
+ when :object_nl
57
+ self.object_nl = value
58
+ when :max_nesting
59
+ self.max_nesting = value || 0
60
+ when :depth
61
+ self.depth = value
62
+ when :buffer_initial_length
63
+ self.buffer_initial_length = value
64
+ when :allow_nan
65
+ self.allow_nan = value
66
+ when :ascii_only
67
+ self.ascii_only = value
68
+ when :script_safe, :escape_slash
69
+ self.script_safe = value
70
+ when :strict
71
+ self.strict = value
72
+ end
73
+ end
74
+
75
+ self
76
+ end
77
+
78
+ alias_method :merge, :configure
79
+
80
+ # call-seq: to_h
81
+ #
82
+ # Returns the configuration instance variables as a hash, that can be
83
+ # passed to the configure method.
84
+ def to_h
85
+ result = {
86
+ indent: indent,
87
+ space: space,
88
+ space_before: space_before,
89
+ object_nl: object_nl,
90
+ array_nl: array_nl,
91
+ allow_nan: allow_nan?,
92
+ ascii_only: ascii_only?,
93
+ max_nesting: max_nesting,
94
+ script_safe: script_safe?,
95
+ strict: strict?,
96
+ depth: depth,
97
+ buffer_initial_length: buffer_initial_length,
98
+ }
99
+
100
+ instance_variables.each do |iv|
101
+ iv = iv.to_s[1..-1]
102
+ result[iv.to_sym] = self[iv]
103
+ end
104
+
105
+ result
106
+ end
107
+
108
+ alias_method :to_hash, :to_h
109
+
110
+ # call-seq: [](name)
111
+ #
112
+ # Returns the value returned by method +name+.
113
+ def [](name)
114
+ if respond_to?(name)
115
+ __send__(name)
116
+ else
117
+ instance_variable_get("@#{name}") if
118
+ instance_variables.include?("@#{name}".to_sym) # avoid warning
119
+ end
120
+ end
121
+
122
+ # call-seq: []=(name, value)
123
+ #
124
+ # Sets the attribute name to value.
125
+ def []=(name, value)
126
+ if respond_to?(name_writer = "#{name}=")
127
+ __send__ name_writer, value
128
+ else
129
+ instance_variable_set "@#{name}", value
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
data/lib/json/ext.rb CHANGED
@@ -1,14 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json/common'
2
4
 
3
5
  module JSON
4
6
  # This module holds all the modules/classes that implement JSON's
5
7
  # functionality as C extensions.
6
8
  module Ext
7
- require 'json/ext/parser'
8
- require 'json/ext/generator'
9
- $DEBUG and warn "Using Ext extension for JSON."
10
- JSON.parser = Parser
11
- JSON.generator = Generator
9
+ if RUBY_ENGINE == 'truffleruby'
10
+ require 'json/ext/parser'
11
+ require 'json/pure'
12
+ $DEBUG and warn "Using Ext extension for JSON parser and Pure library for JSON generator."
13
+ JSON.parser = Parser
14
+ JSON.generator = JSON::Pure::Generator
15
+ else
16
+ require 'json/ext/parser'
17
+ require 'json/ext/generator'
18
+ unless RUBY_ENGINE == 'jruby'
19
+ require 'json/ext/generator/state'
20
+ end
21
+ $DEBUG and warn "Using Ext extension for JSON."
22
+ JSON.parser = Parser
23
+ JSON.generator = Generator
24
+ end
12
25
  end
13
26
 
14
27
  JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
@@ -1,4 +1,4 @@
1
- #frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  begin
3
3
  require 'ostruct'
4
4
  rescue LoadError
@@ -1,4 +1,4 @@
1
- #frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  module JSON
3
3
  MAP = {
4
4
  "\x0" => '\u0000',
@@ -35,7 +35,7 @@ module JSON
35
35
  "\x1f" => '\u001f',
36
36
  '"' => '\"',
37
37
  '\\' => '\\\\',
38
- } # :nodoc:
38
+ }.freeze # :nodoc:
39
39
 
40
40
  ESCAPE_PATTERN = /[\/"\\\x0-\x1f]/n # :nodoc:
41
41
 
@@ -43,15 +43,14 @@ module JSON
43
43
  '/' => '\\/',
44
44
  "\u2028".b => '\u2028',
45
45
  "\u2029".b => '\u2029',
46
- )
46
+ ).freeze
47
47
 
48
48
  SCRIPT_SAFE_ESCAPE_PATTERN = Regexp.union(ESCAPE_PATTERN, "\u2028".b, "\u2029".b)
49
49
 
50
50
  # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
51
51
  # UTF16 big endian characters as \u????, and return it.
52
52
  def utf8_to_json(string, script_safe = false) # :nodoc:
53
- string = string.dup
54
- string.force_encoding(::Encoding::ASCII_8BIT)
53
+ string = string.b
55
54
  if script_safe
56
55
  string.gsub!(SCRIPT_SAFE_ESCAPE_PATTERN) { SCRIPT_SAFE_MAP[$&] || $& }
57
56
  else
@@ -62,8 +61,7 @@ module JSON
62
61
  end
63
62
 
64
63
  def utf8_to_json_ascii(string, script_safe = false) # :nodoc:
65
- string = string.dup
66
- string.force_encoding(::Encoding::ASCII_8BIT)
64
+ string = string.b
67
65
  map = script_safe ? SCRIPT_SAFE_MAP : MAP
68
66
  string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
69
67
  string.gsub!(/(
@@ -75,7 +73,7 @@ module JSON
75
73
  [\x80-\xc1\xf5-\xff] # invalid
76
74
  )/nx) { |c|
77
75
  c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
78
- s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
76
+ s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0]
79
77
  s.force_encoding(::Encoding::ASCII_8BIT)
80
78
  s.gsub!(/.{4}/n, '\\\\u\&')
81
79
  s.force_encoding(::Encoding::UTF_8)
@@ -219,7 +217,9 @@ module JSON
219
217
  @script_safe
220
218
  end
221
219
 
222
- # Returns true, if forward slashes are escaped. Otherwise returns false.
220
+ # Returns true, if strict mode is enabled. Otherwise returns false.
221
+ # Strict mode only allow serializing JSON native types: Hash, Array,
222
+ # String, Integer, Float, true, false and nil.
223
223
  def strict?
224
224
  @strict
225
225
  end
@@ -237,6 +237,8 @@ module JSON
237
237
  opts.each do |key, value|
238
238
  instance_variable_set "@#{key}", value
239
239
  end
240
+
241
+ # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json
240
242
  @indent = opts[:indent] if opts.key?(:indent)
241
243
  @space = opts[:space] if opts.key?(:space)
242
244
  @space_before = opts[:space_before] if opts.key?(:space_before)
@@ -286,12 +288,71 @@ module JSON
286
288
  # created this method raises a
287
289
  # GeneratorError exception.
288
290
  def generate(obj)
289
- result = obj.to_json(self)
291
+ if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
292
+ !@ascii_only and !@script_safe and @max_nesting == 0 and !@strict
293
+ result = generate_json(obj, ''.dup)
294
+ else
295
+ result = obj.to_json(self)
296
+ end
290
297
  JSON.valid_utf8?(result) or raise GeneratorError,
291
298
  "source sequence #{result.inspect} is illegal/malformed utf-8"
292
299
  result
293
300
  end
294
301
 
302
+ # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
303
+ private def generate_json(obj, buf)
304
+ case obj
305
+ when Hash
306
+ buf << '{'
307
+ first = true
308
+ obj.each_pair do |k,v|
309
+ buf << ',' unless first
310
+ fast_serialize_string(k.to_s, buf)
311
+ buf << ':'
312
+ generate_json(v, buf)
313
+ first = false
314
+ end
315
+ buf << '}'
316
+ when Array
317
+ buf << '['
318
+ first = true
319
+ obj.each do |e|
320
+ buf << ',' unless first
321
+ generate_json(e, buf)
322
+ first = false
323
+ end
324
+ buf << ']'
325
+ when String
326
+ fast_serialize_string(obj, buf)
327
+ when Integer
328
+ buf << obj.to_s
329
+ else
330
+ # Note: Float is handled this way since Float#to_s is slow anyway
331
+ buf << obj.to_json(self)
332
+ end
333
+ end
334
+
335
+ # Assumes !@ascii_only, !@script_safe
336
+ if Regexp.method_defined?(:match?)
337
+ private def fast_serialize_string(string, buf) # :nodoc:
338
+ buf << '"'
339
+ string = string.encode(::Encoding::UTF_8) unless string.encoding == ::Encoding::UTF_8
340
+ raise GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding?
341
+
342
+ if /["\\\x0-\x1f]/n.match?(string)
343
+ buf << string.gsub(/["\\\x0-\x1f]/n, MAP)
344
+ else
345
+ buf << string
346
+ end
347
+ buf << '"'
348
+ end
349
+ else
350
+ # Ruby 2.3 compatibility
351
+ private def fast_serialize_string(string, buf) # :nodoc:
352
+ buf << string.to_json(self)
353
+ end
354
+ end
355
+
295
356
  # Return the value returned by method +name+.
296
357
  def [](name)
297
358
  if respond_to?(name)
@@ -316,8 +377,8 @@ module JSON
316
377
  # Converts this object to a string (calling #to_s), converts
317
378
  # it to a JSON string, and returns the result. This is a fallback, if no
318
379
  # special method #to_json was defined for some object.
319
- def to_json(generator_state)
320
- if generator_state.strict?
380
+ def to_json(state = nil, *)
381
+ if state && State.from_state(state).strict?
321
382
  raise GeneratorError, "#{self.class} not allowed in JSON"
322
383
  else
323
384
  to_s.to_json
@@ -346,15 +407,15 @@ module JSON
346
407
 
347
408
  def json_transform(state)
348
409
  delim = ",#{state.object_nl}"
349
- result = "{#{state.object_nl}"
410
+ result = +"{#{state.object_nl}"
350
411
  depth = state.depth += 1
351
412
  first = true
352
413
  indent = !state.object_nl.empty?
353
414
  each { |key, value|
354
415
  result << delim unless first
355
416
  result << state.indent * depth if indent
356
- result = "#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}"
357
- if state.strict?
417
+ result = +"#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}"
418
+ if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
358
419
  raise GeneratorError, "#{value.class} not allowed in JSON"
359
420
  elsif value.respond_to?(:to_json)
360
421
  result << value.to_json(state)
@@ -387,17 +448,20 @@ module JSON
387
448
  private
388
449
 
389
450
  def json_transform(state)
390
- delim = ','
391
- delim << state.array_nl
392
- result = '['
393
- result << state.array_nl
451
+ result = '['.dup
452
+ if state.array_nl.empty?
453
+ delim = ","
454
+ else
455
+ result << state.array_nl
456
+ delim = ",#{state.array_nl}"
457
+ end
394
458
  depth = state.depth += 1
395
459
  first = true
396
460
  indent = !state.array_nl.empty?
397
461
  each { |value|
398
462
  result << delim unless first
399
463
  result << state.indent * depth if indent
400
- if state.strict?
464
+ if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
401
465
  raise GeneratorError, "#{value.class} not allowed in JSON"
402
466
  elsif value.respond_to?(:to_json)
403
467
  result << value.to_json(state)
@@ -448,14 +512,17 @@ module JSON
448
512
  def to_json(state = nil, *args)
449
513
  state = State.from_state(state)
450
514
  if encoding == ::Encoding::UTF_8
515
+ unless valid_encoding?
516
+ raise GeneratorError, "source sequence is illegal/malformed utf-8"
517
+ end
451
518
  string = self
452
519
  else
453
520
  string = encode(::Encoding::UTF_8)
454
521
  end
455
522
  if state.ascii_only?
456
- '"' << JSON.utf8_to_json_ascii(string, state.script_safe) << '"'
523
+ %("#{JSON.utf8_to_json_ascii(string, state.script_safe)}")
457
524
  else
458
- '"' << JSON.utf8_to_json(string, state.script_safe) << '"'
525
+ %("#{JSON.utf8_to_json(string, state.script_safe)}")
459
526
  end
460
527
  end
461
528
 
@@ -1,4 +1,4 @@
1
- #frozen_string_literal: false
1
+ #frozen_string_literal: true
2
2
  require 'strscan'
3
3
 
4
4
  module JSON
@@ -39,11 +39,8 @@ module JSON
39
39
  //[^\n\r]*[\n\r]| # line comments
40
40
  /\* # c-style comments
41
41
  (?:
42
- [^*/]| # normal chars
43
- /[^*]| # slashes that do not start a nested comment
44
- \*[^/]| # asterisks that do not end this comment
45
- /(?=\*/) # single slash before this comment's end
46
- )*
42
+ [\s\S]*? # any char, repeated lazily
43
+ )
47
44
  \*/ # the End of this comment
48
45
  |[ \t\r\n]+ # whitespaces: space, horizontal tab, lf, cr
49
46
  )+
@@ -70,12 +67,16 @@ module JSON
70
67
  # * *create_additions*: If set to true, the Parser creates
71
68
  # additions when a matching class and create_id are found. This
72
69
  # option defaults to false.
73
- # * *object_class*: Defaults to Hash
74
- # * *array_class*: Defaults to Array
70
+ # * *object_class*: Defaults to Hash. If another type is provided, it will be used
71
+ # instead of Hash to represent JSON objects. The type must respond to
72
+ # +new+ without arguments, and return an object that respond to +[]=+.
73
+ # * *array_class*: Defaults to Array If another type is provided, it will be used
74
+ # instead of Hash to represent JSON arrays. The type must respond to
75
+ # +new+ without arguments, and return an object that respond to +<<+.
75
76
  # * *decimal_class*: Specifies which class to use instead of the default
76
77
  # (Float) when parsing decimal numbers. This class must accept a single
77
78
  # string argument in its constructor.
78
- def initialize(source, opts = {})
79
+ def initialize(source, opts = nil)
79
80
  opts ||= {}
80
81
  source = convert_encoding source
81
82
  super source
@@ -160,11 +161,6 @@ module JSON
160
161
  ?u => nil,
161
162
  })
162
163
 
163
- EMPTY_8BIT_STRING = ''
164
- if ::String.method_defined?(:encode)
165
- EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
166
- end
167
-
168
164
  STR_UMINUS = ''.respond_to?(:-@)
169
165
  def parse_string
170
166
  if scan(STRING)
@@ -173,18 +169,16 @@ module JSON
173
169
  if u = UNESCAPE_MAP[$&[1]]
174
170
  u
175
171
  else # \uXXXX
176
- bytes = EMPTY_8BIT_STRING.dup
172
+ bytes = ''.b
177
173
  i = 0
178
174
  while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
179
175
  bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
180
176
  i += 1
181
177
  end
182
- JSON.iconv('utf-8', 'utf-16be', bytes).force_encoding(::Encoding::ASCII_8BIT)
178
+ bytes.encode(Encoding::UTF_8, Encoding::UTF_16BE).force_encoding(::Encoding::BINARY)
183
179
  end
184
180
  end
185
- if string.respond_to?(:force_encoding)
186
- string.force_encoding(::Encoding::UTF_8)
187
- end
181
+ string.force_encoding(::Encoding::UTF_8)
188
182
 
189
183
  if @freeze
190
184
  if STR_UMINUS
data/lib/json/pure.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'json/common'
2
3
 
3
4
  module JSON
data/lib/json/version.rb CHANGED
@@ -1,9 +1,5 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
+
2
3
  module JSON
3
- # JSON version
4
- VERSION = '2.7.2'
5
- VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
6
- VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
7
- VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
8
- VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
4
+ VERSION = '2.7.3'
9
5
  end
data/lib/json.rb CHANGED
@@ -1,4 +1,4 @@
1
- #frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  require 'json/common'
3
3
 
4
4
  ##
metadata CHANGED
@@ -1,22 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.2
4
+ version: 2.7.3
5
5
  platform: java
6
6
  authors:
7
7
  - Daniel Luz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-04 00:00:00.000000000 Z
11
+ date: 2024-10-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A JSON implementation as a JRuby extension.
14
14
  email: dev+ruby@mernen.com
15
15
  executables: []
16
16
  extensions: []
17
- extra_rdoc_files: []
17
+ extra_rdoc_files:
18
+ - README.md
18
19
  files:
19
- - LICENSE
20
+ - BSDL
21
+ - CHANGES.md
22
+ - COPYING
23
+ - LEGAL
24
+ - README.md
25
+ - json.gemspec
20
26
  - lib/json.rb
21
27
  - lib/json/add/bigdecimal.rb
22
28
  - lib/json/add/complex.rb
@@ -34,25 +40,28 @@ files:
34
40
  - lib/json/add/time.rb
35
41
  - lib/json/common.rb
36
42
  - lib/json/ext.rb
37
- - lib/json/ext/generator.jar
38
- - lib/json/ext/parser.jar
43
+ - lib/json/ext/generator/state.rb
39
44
  - lib/json/generic_object.rb
40
45
  - lib/json/pure.rb
41
46
  - lib/json/pure/generator.rb
42
47
  - lib/json/pure/parser.rb
43
48
  - lib/json/version.rb
44
- homepage: https://flori.github.io/json
49
+ homepage: https://ruby.github.io/json
45
50
  licenses:
46
51
  - Ruby
47
52
  metadata:
48
- bug_tracker_uri: https://github.com/flori/json/issues
49
- changelog_uri: https://github.com/flori/json/blob/master/CHANGES.md
50
- documentation_uri: https://flori.github.io/json/doc/index.html
51
- homepage_uri: https://flori.github.io/json
52
- source_code_uri: https://github.com/flori/json
53
- wiki_uri: https://github.com/flori/json/wiki
53
+ bug_tracker_uri: https://github.com/ruby/json/issues
54
+ changelog_uri: https://github.com/ruby/json/blob/master/CHANGES.md
55
+ documentation_uri: https://ruby.github.io/json/doc/index.html
56
+ homepage_uri: https://ruby.github.io/json
57
+ source_code_uri: https://github.com/ruby/json
58
+ wiki_uri: https://github.com/ruby/json/wiki
54
59
  post_install_message:
55
- rdoc_options: []
60
+ rdoc_options:
61
+ - "--title"
62
+ - JSON implementation for Ruby
63
+ - "--main"
64
+ - README.md
56
65
  require_paths:
57
66
  - lib
58
67
  required_ruby_version: !ruby/object:Gem::Requirement
Binary file
Binary file
File without changes