json 2.7.1-java → 2.7.3-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,5 +1,9 @@
1
- #frozen_string_literal: false
2
- require 'ostruct'
1
+ # frozen_string_literal: true
2
+ begin
3
+ require 'ostruct'
4
+ rescue LoadError
5
+ warn "JSON::GenericObject requires 'ostruct'. Please install it with `gem install ostruct`."
6
+ end
3
7
 
4
8
  module JSON
5
9
  class GenericObject < OpenStruct
@@ -67,5 +71,5 @@ module JSON
67
71
  def to_json(*a)
68
72
  as_json.to_json(*a)
69
73
  end
70
- end
74
+ end if defined?(::OpenStruct)
71
75
  end
@@ -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.1'
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.1
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: 2023-12-05 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