json 2.7.2-java → 2.7.3.rc1-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,7 +43,7 @@ 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
 
@@ -75,7 +75,7 @@ module JSON
75
75
  [\x80-\xc1\xf5-\xff] # invalid
76
76
  )/nx) { |c|
77
77
  c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
78
- s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
78
+ s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0]
79
79
  s.force_encoding(::Encoding::ASCII_8BIT)
80
80
  s.gsub!(/.{4}/n, '\\\\u\&')
81
81
  s.force_encoding(::Encoding::UTF_8)
@@ -219,7 +219,9 @@ module JSON
219
219
  @script_safe
220
220
  end
221
221
 
222
- # Returns true, if forward slashes are escaped. Otherwise returns false.
222
+ # Returns true, if strict mode is enabled. Otherwise returns false.
223
+ # Strict mode only allow serializing JSON native types: Hash, Array,
224
+ # String, Integer, Float, true, false and nil.
223
225
  def strict?
224
226
  @strict
225
227
  end
@@ -237,6 +239,8 @@ module JSON
237
239
  opts.each do |key, value|
238
240
  instance_variable_set "@#{key}", value
239
241
  end
242
+
243
+ # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json
240
244
  @indent = opts[:indent] if opts.key?(:indent)
241
245
  @space = opts[:space] if opts.key?(:space)
242
246
  @space_before = opts[:space_before] if opts.key?(:space_before)
@@ -286,12 +290,71 @@ module JSON
286
290
  # created this method raises a
287
291
  # GeneratorError exception.
288
292
  def generate(obj)
289
- result = obj.to_json(self)
293
+ if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
294
+ !@ascii_only and !@script_safe and @max_nesting == 0 and !@strict
295
+ result = generate_json(obj, ''.dup)
296
+ else
297
+ result = obj.to_json(self)
298
+ end
290
299
  JSON.valid_utf8?(result) or raise GeneratorError,
291
300
  "source sequence #{result.inspect} is illegal/malformed utf-8"
292
301
  result
293
302
  end
294
303
 
304
+ # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
305
+ private def generate_json(obj, buf)
306
+ case obj
307
+ when Hash
308
+ buf << '{'
309
+ first = true
310
+ obj.each_pair do |k,v|
311
+ buf << ',' unless first
312
+ fast_serialize_string(k.to_s, buf)
313
+ buf << ':'
314
+ generate_json(v, buf)
315
+ first = false
316
+ end
317
+ buf << '}'
318
+ when Array
319
+ buf << '['
320
+ first = true
321
+ obj.each do |e|
322
+ buf << ',' unless first
323
+ generate_json(e, buf)
324
+ first = false
325
+ end
326
+ buf << ']'
327
+ when String
328
+ fast_serialize_string(obj, buf)
329
+ when Integer
330
+ buf << obj.to_s
331
+ else
332
+ # Note: Float is handled this way since Float#to_s is slow anyway
333
+ buf << obj.to_json(self)
334
+ end
335
+ end
336
+
337
+ # Assumes !@ascii_only, !@script_safe
338
+ if Regexp.method_defined?(:match?)
339
+ private def fast_serialize_string(string, buf) # :nodoc:
340
+ buf << '"'
341
+ string = string.encode(::Encoding::UTF_8) unless string.encoding == ::Encoding::UTF_8
342
+ raise GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding?
343
+
344
+ if /["\\\x0-\x1f]/n.match?(string)
345
+ buf << string.gsub(/["\\\x0-\x1f]/n, MAP)
346
+ else
347
+ buf << string
348
+ end
349
+ buf << '"'
350
+ end
351
+ else
352
+ # Ruby 2.3 compatibility
353
+ private def fast_serialize_string(string, buf) # :nodoc:
354
+ buf << string.to_json(self)
355
+ end
356
+ end
357
+
295
358
  # Return the value returned by method +name+.
296
359
  def [](name)
297
360
  if respond_to?(name)
@@ -316,8 +379,8 @@ module JSON
316
379
  # Converts this object to a string (calling #to_s), converts
317
380
  # it to a JSON string, and returns the result. This is a fallback, if no
318
381
  # special method #to_json was defined for some object.
319
- def to_json(generator_state)
320
- if generator_state.strict?
382
+ def to_json(state = nil, *)
383
+ if state && State.from_state(state).strict?
321
384
  raise GeneratorError, "#{self.class} not allowed in JSON"
322
385
  else
323
386
  to_s.to_json
@@ -347,6 +410,7 @@ module JSON
347
410
  def json_transform(state)
348
411
  delim = ",#{state.object_nl}"
349
412
  result = "{#{state.object_nl}"
413
+ result = result.dup if result.frozen? # RUBY_VERSION < 3.0
350
414
  depth = state.depth += 1
351
415
  first = true
352
416
  indent = !state.object_nl.empty?
@@ -354,7 +418,8 @@ module JSON
354
418
  result << delim unless first
355
419
  result << state.indent * depth if indent
356
420
  result = "#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}"
357
- if state.strict?
421
+ result = result.dup if result.frozen? # RUBY_VERSION < 3.0
422
+ if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
358
423
  raise GeneratorError, "#{value.class} not allowed in JSON"
359
424
  elsif value.respond_to?(:to_json)
360
425
  result << value.to_json(state)
@@ -387,17 +452,20 @@ module JSON
387
452
  private
388
453
 
389
454
  def json_transform(state)
390
- delim = ','
391
- delim << state.array_nl
392
- result = '['
393
- result << state.array_nl
455
+ result = '['.dup
456
+ if state.array_nl.empty?
457
+ delim = ","
458
+ else
459
+ result << state.array_nl
460
+ delim = ",#{state.array_nl}"
461
+ end
394
462
  depth = state.depth += 1
395
463
  first = true
396
464
  indent = !state.array_nl.empty?
397
465
  each { |value|
398
466
  result << delim unless first
399
467
  result << state.indent * depth if indent
400
- if state.strict?
468
+ if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
401
469
  raise GeneratorError, "#{value.class} not allowed in JSON"
402
470
  elsif value.respond_to?(:to_json)
403
471
  result << value.to_json(state)
@@ -448,14 +516,17 @@ module JSON
448
516
  def to_json(state = nil, *args)
449
517
  state = State.from_state(state)
450
518
  if encoding == ::Encoding::UTF_8
519
+ unless valid_encoding?
520
+ raise GeneratorError, "source sequence is illegal/malformed utf-8"
521
+ end
451
522
  string = self
452
523
  else
453
524
  string = encode(::Encoding::UTF_8)
454
525
  end
455
526
  if state.ascii_only?
456
- '"' << JSON.utf8_to_json_ascii(string, state.script_safe) << '"'
527
+ %("#{JSON.utf8_to_json_ascii(string, state.script_safe)}")
457
528
  else
458
- '"' << JSON.utf8_to_json(string, state.script_safe) << '"'
529
+ %("#{JSON.utf8_to_json(string, state.script_safe)}")
459
530
  end
460
531
  end
461
532
 
@@ -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.rc1'
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.rc1
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-23 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
@@ -62,9 +71,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
62
71
  version: '2.3'
63
72
  required_rubygems_version: !ruby/object:Gem::Requirement
64
73
  requirements:
65
- - - ">="
74
+ - - ">"
66
75
  - !ruby/object:Gem::Version
67
- version: '0'
76
+ version: 1.3.1
68
77
  requirements: []
69
78
  rubygems_version: 3.3.26
70
79
  signing_key:
Binary file
Binary file
File without changes