json 2.7.2-java → 2.7.3.rc1-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,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