json 2.8.2 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -26,19 +26,6 @@ static const char deprecated_create_additions_warning[] =
26
26
  "and will be removed in 3.0, use JSON.unsafe_load or explicitly "
27
27
  "pass `create_additions: true`";
28
28
 
29
- #ifndef HAVE_RB_GC_MARK_LOCATIONS
30
- // For TruffleRuby
31
- void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
32
- {
33
- VALUE *value = start;
34
-
35
- while (value < end) {
36
- rb_gc_mark(*value);
37
- value++;
38
- }
39
- }
40
- #endif
41
-
42
29
  #ifndef HAVE_RB_HASH_BULK_INSERT
43
30
  // For TruffleRuby
44
31
  void rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
@@ -264,7 +251,10 @@ static inline void rvalue_stack_pop(rvalue_stack *stack, long count)
264
251
  static void rvalue_stack_mark(void *ptr)
265
252
  {
266
253
  rvalue_stack *stack = (rvalue_stack *)ptr;
267
- rb_gc_mark_locations(stack->ptr, stack->ptr + stack->head);
254
+ long index;
255
+ for (index = 0; index < stack->head; index++) {
256
+ rb_gc_mark(stack->ptr[index]);
257
+ }
268
258
  }
269
259
 
270
260
  static void rvalue_stack_free(void *ptr)
@@ -1349,8 +1339,10 @@ static void JSON_mark(void *ptr)
1349
1339
  rb_gc_mark(json->match_string);
1350
1340
  rb_gc_mark(json->stack_handle);
1351
1341
 
1352
- const VALUE *name_cache_entries = &json->name_cache.entries[0];
1353
- rb_gc_mark_locations(name_cache_entries, name_cache_entries + json->name_cache.length);
1342
+ long index;
1343
+ for (index = 0; index < json->name_cache.length; index++) {
1344
+ rb_gc_mark(json->name_cache.entries[index]);
1345
+ }
1354
1346
  }
1355
1347
 
1356
1348
  static void JSON_free(void *ptr)
data/lib/json/common.rb CHANGED
@@ -143,7 +143,23 @@ module JSON
143
143
  # :startdoc:
144
144
 
145
145
  # This exception is raised if a generator or unparser error occurs.
146
- class GeneratorError < JSONError; end
146
+ class GeneratorError < JSONError
147
+ attr_reader :invalid_object
148
+
149
+ def initialize(message, invalid_object = nil)
150
+ super(message)
151
+ @invalid_object = invalid_object
152
+ end
153
+
154
+ def detailed_message(...)
155
+ if @invalid_object.nil?
156
+ super
157
+ else
158
+ "#{super}\nInvalid object: #{@invalid_object.inspect}"
159
+ end
160
+ end
161
+ end
162
+
147
163
  # For backwards compatibility
148
164
  UnparserError = GeneratorError # :nodoc:
149
165
 
@@ -286,7 +302,7 @@ module JSON
286
302
  if State === opts
287
303
  opts.generate(obj)
288
304
  else
289
- State.generate(obj, opts)
305
+ State.generate(obj, opts, nil)
290
306
  end
291
307
  end
292
308
 
@@ -411,6 +427,10 @@ module JSON
411
427
  #
412
428
  # Returns the Ruby objects created by parsing the given +source+.
413
429
  #
430
+ # BEWARE: This method is meant to serialise data from trusted user input,
431
+ # like from your own database server or clients under your control, it could
432
+ # be dangerous to allow untrusted users to pass JSON sources into it.
433
+ #
414
434
  # - Argument +source+ must be, or be convertible to, a \String:
415
435
  # - If +source+ responds to instance method +to_str+,
416
436
  # <tt>source.to_str</tt> becomes the source.
@@ -425,9 +445,6 @@ module JSON
425
445
  # - Argument +proc+, if given, must be a \Proc that accepts one argument.
426
446
  # It will be called recursively with each result (depth-first order).
427
447
  # See details below.
428
- # BEWARE: This method is meant to serialise data from trusted user input,
429
- # like from your own database server or clients under your control, it could
430
- # be dangerous to allow untrusted users to pass JSON sources into it.
431
448
  # - Argument +opts+, if given, contains a \Hash of options for the parsing.
432
449
  # See {Parsing Options}[#module-JSON-label-Parsing+Options].
433
450
  # The default options can be changed via method JSON.unsafe_load_default_options=.
@@ -564,6 +581,16 @@ module JSON
564
581
  #
565
582
  # Returns the Ruby objects created by parsing the given +source+.
566
583
  #
584
+ # BEWARE: This method is meant to serialise data from trusted user input,
585
+ # like from your own database server or clients under your control, it could
586
+ # be dangerous to allow untrusted users to pass JSON sources into it.
587
+ # If you must use it, use JSON.unsafe_load instead to make it clear.
588
+ #
589
+ # Since JSON version 2.8.0, `load` emits a deprecation warning when a
590
+ # non native type is deserialized, without `create_additions` being explicitly
591
+ # enabled, and in JSON version 3.0, `load` will have `create_additions` disabled
592
+ # by default.
593
+ #
567
594
  # - Argument +source+ must be, or be convertible to, a \String:
568
595
  # - If +source+ responds to instance method +to_str+,
569
596
  # <tt>source.to_str</tt> becomes the source.
@@ -578,10 +605,6 @@ module JSON
578
605
  # - Argument +proc+, if given, must be a \Proc that accepts one argument.
579
606
  # It will be called recursively with each result (depth-first order).
580
607
  # See details below.
581
- # BEWARE: This method is meant to serialise data from trusted user input,
582
- # like from your own database server or clients under your control, it could
583
- # be dangerous to allow untrusted users to pass JSON sources into it.
584
- # If you must use it, use JSON.unsafe_load instead to make it clear.
585
608
  # - Argument +opts+, if given, contains a \Hash of options for the parsing.
586
609
  # See {Parsing Options}[#module-JSON-label-Parsing+Options].
587
610
  # The default options can be changed via method JSON.load_default_options=.
@@ -794,18 +817,15 @@ module JSON
794
817
  opts = opts.merge(:max_nesting => limit) if limit
795
818
  opts = merge_dump_options(opts, **kwargs) if kwargs
796
819
 
797
- result = begin
798
- generate(obj, opts)
820
+ begin
821
+ if State === opts
822
+ opts.generate(obj, anIO)
823
+ else
824
+ State.generate(obj, opts, anIO)
825
+ end
799
826
  rescue JSON::NestingError
800
827
  raise ArgumentError, "exceed depth limit"
801
828
  end
802
-
803
- if anIO.nil?
804
- result
805
- else
806
- anIO.write result
807
- anIO
808
- end
809
829
  end
810
830
 
811
831
  # Encodes string using String.encode.
@@ -47,6 +47,17 @@ module JSON
47
47
 
48
48
  alias_method :merge, :configure
49
49
 
50
+ # call-seq:
51
+ # generate(obj) -> String
52
+ # generate(obj, anIO) -> anIO
53
+ #
54
+ # Generates a valid JSON document from object +obj+ and returns the
55
+ # result. If no valid JSON document can be created this method raises a
56
+ # GeneratorError exception.
57
+ def generate(obj, io = nil)
58
+ _generate(obj, io)
59
+ end
60
+
50
61
  # call-seq: to_h
51
62
  #
52
63
  # Returns the configuration instance variables as a hash, that can be
@@ -62,8 +62,8 @@ module JSON
62
62
  string
63
63
  end
64
64
 
65
- def utf8_to_json_ascii(string, script_safe = false) # :nodoc:
66
- string = string.b
65
+ def utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
66
+ string = original_string.b
67
67
  map = script_safe ? SCRIPT_SAFE_MAP : MAP
68
68
  string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
69
69
  string.gsub!(/(
@@ -74,7 +74,7 @@ module JSON
74
74
  )+ |
75
75
  [\x80-\xc1\xf5-\xff] # invalid
76
76
  )/nx) { |c|
77
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
77
+ c.size == 1 and raise GeneratorError.new("invalid utf8 byte: '#{c}'", original_string)
78
78
  s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0]
79
79
  s.force_encoding(::Encoding::BINARY)
80
80
  s.gsub!(/.{4}/n, '\\\\u\&')
@@ -83,7 +83,7 @@ module JSON
83
83
  string.force_encoding(::Encoding::UTF_8)
84
84
  string
85
85
  rescue => e
86
- raise GeneratorError.wrap(e)
86
+ raise GeneratorError.new(e.message, original_string)
87
87
  end
88
88
 
89
89
  def valid_utf8?(string)
@@ -96,8 +96,14 @@ module JSON
96
96
  # This class is used to create State instances, that are use to hold data
97
97
  # while generating a JSON text from a Ruby data structure.
98
98
  class State
99
- def self.generate(obj, opts = nil)
100
- new(opts).generate(obj)
99
+ def self.generate(obj, opts = nil, io = nil)
100
+ string = new(opts).generate(obj)
101
+ if io
102
+ io.write(string)
103
+ io
104
+ else
105
+ string
106
+ end
101
107
  end
102
108
 
103
109
  # Creates a State object from _opts_, which ought to be Hash to create
@@ -300,8 +306,10 @@ module JSON
300
306
  else
301
307
  result = obj.to_json(self)
302
308
  end
303
- JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError,
304
- "source sequence #{result.inspect} is illegal/malformed utf-8"
309
+ JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new(
310
+ "source sequence #{result.inspect} is illegal/malformed utf-8",
311
+ obj
312
+ )
305
313
  result
306
314
  end
307
315
 
@@ -358,10 +366,10 @@ module JSON
358
366
  begin
359
367
  string = string.encode(::Encoding::UTF_8)
360
368
  rescue Encoding::UndefinedConversionError => error
361
- raise GeneratorError, error.message
369
+ raise GeneratorError.new(error.message, string)
362
370
  end
363
371
  end
364
- raise GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding?
372
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding?
365
373
 
366
374
  if /["\\\x0-\x1f]/n.match?(string)
367
375
  buf << string.gsub(/["\\\x0-\x1f]/n, MAP)
@@ -397,7 +405,7 @@ module JSON
397
405
  # special method #to_json was defined for some object.
398
406
  def to_json(state = nil, *)
399
407
  if state && State.from_state(state).strict?
400
- raise GeneratorError, "#{self.class} not allowed in JSON"
408
+ raise GeneratorError.new("#{self.class} not allowed in JSON", self)
401
409
  else
402
410
  to_s.to_json
403
411
  end
@@ -448,7 +456,7 @@ module JSON
448
456
 
449
457
  result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
450
458
  if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
451
- raise GeneratorError, "#{value.class} not allowed in JSON"
459
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
452
460
  elsif value.respond_to?(:to_json)
453
461
  result << value.to_json(state)
454
462
  else
@@ -501,7 +509,7 @@ module JSON
501
509
  result << delim unless first
502
510
  result << state.indent * depth if indent
503
511
  if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
504
- raise GeneratorError, "#{value.class} not allowed in JSON"
512
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
505
513
  elsif value.respond_to?(:to_json)
506
514
  result << value.to_json(state)
507
515
  else
@@ -530,13 +538,13 @@ module JSON
530
538
  if state.allow_nan?
531
539
  to_s
532
540
  else
533
- raise GeneratorError, "#{self} not allowed in JSON"
541
+ raise GeneratorError.new("#{self} not allowed in JSON", self)
534
542
  end
535
543
  when nan?
536
544
  if state.allow_nan?
537
545
  to_s
538
546
  else
539
- raise GeneratorError, "#{self} not allowed in JSON"
547
+ raise GeneratorError.new("#{self} not allowed in JSON", self)
540
548
  end
541
549
  else
542
550
  to_s
@@ -552,7 +560,7 @@ module JSON
552
560
  state = State.from_state(state)
553
561
  if encoding == ::Encoding::UTF_8
554
562
  unless valid_encoding?
555
- raise GeneratorError, "source sequence is illegal/malformed utf-8"
563
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
556
564
  end
557
565
  string = self
558
566
  else
@@ -564,7 +572,7 @@ module JSON
564
572
  %("#{JSON::TruffleRuby::Generator.utf8_to_json(string, state.script_safe)}")
565
573
  end
566
574
  rescue Encoding::UndefinedConversionError => error
567
- raise ::JSON::GeneratorError, error.message
575
+ raise ::JSON::GeneratorError.new(error.message, self)
568
576
  end
569
577
 
570
578
  # Module that holds the extending methods if, the String module is
data/lib/json/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSON
4
- VERSION = '2.8.2'
4
+ VERSION = '2.9.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.2
4
+ version: 2.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-14 00:00:00.000000000 Z
11
+ date: 2024-12-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This is a JSON implementation as a Ruby extension in C.
14
14
  email: flori@ping.de