Skip to content

Commit 4eb51df

Browse files
authored
Merge JSON 2.7.2 for Ruby 3.3 (ruby#11541)
Merge JSON 2.7.2
1 parent ef084cc commit 4eb51df

File tree

8 files changed

+90
-47
lines changed

8 files changed

+90
-47
lines changed

ext/json/generator/generator.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
867867
if (klass == rb_cString) {
868868
key_to_s = key;
869869
} else if (klass == rb_cSymbol) {
870-
key_to_s = rb_id2str(SYM2ID(key));
870+
key_to_s = rb_sym2str(key);
871871
} else {
872872
key_to_s = rb_funcall(key, i_to_s, 0);
873873
}
@@ -892,7 +892,6 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
892892
struct hash_foreach_arg arg;
893893

894894
if (max_nesting != 0 && depth > max_nesting) {
895-
fbuffer_free(buffer);
896895
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
897896
}
898897
fbuffer_append_char(buffer, '{');
@@ -927,7 +926,6 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
927926
long depth = ++state->depth;
928927
int i, j;
929928
if (max_nesting != 0 && depth > max_nesting) {
930-
fbuffer_free(buffer);
931929
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
932930
}
933931
fbuffer_append_char(buffer, '[');
@@ -1020,10 +1018,8 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
10201018
VALUE tmp = rb_funcall(obj, i_to_s, 0);
10211019
if (!allow_nan) {
10221020
if (isinf(value)) {
1023-
fbuffer_free(buffer);
10241021
rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(tmp));
10251022
} else if (isnan(value)) {
1026-
fbuffer_free(buffer);
10271023
rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(tmp));
10281024
}
10291025
}
@@ -1096,11 +1092,45 @@ static FBuffer *cState_prepare_buffer(VALUE self)
10961092
return buffer;
10971093
}
10981094

1095+
struct generate_json_data {
1096+
FBuffer *buffer;
1097+
VALUE vstate;
1098+
JSON_Generator_State *state;
1099+
VALUE obj;
1100+
};
1101+
1102+
static VALUE generate_json_try(VALUE d)
1103+
{
1104+
struct generate_json_data *data = (struct generate_json_data *)d;
1105+
1106+
generate_json(data->buffer, data->vstate, data->state, data->obj);
1107+
1108+
return Qnil;
1109+
}
1110+
1111+
static VALUE generate_json_rescue(VALUE d, VALUE exc)
1112+
{
1113+
struct generate_json_data *data = (struct generate_json_data *)d;
1114+
fbuffer_free(data->buffer);
1115+
1116+
rb_exc_raise(exc);
1117+
1118+
return Qundef;
1119+
}
1120+
10991121
static VALUE cState_partial_generate(VALUE self, VALUE obj)
11001122
{
11011123
FBuffer *buffer = cState_prepare_buffer(self);
11021124
GET_STATE(self);
1103-
generate_json(buffer, self, state, obj);
1125+
1126+
struct generate_json_data data = {
1127+
.buffer = buffer,
1128+
.vstate = self,
1129+
.state = state,
1130+
.obj = obj
1131+
};
1132+
rb_rescue(generate_json_try, (VALUE)&data, generate_json_rescue, (VALUE)&data);
1133+
11041134
return fbuffer_to_s(buffer);
11051135
}
11061136

ext/json/lib/json/add/ostruct.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
33
require 'json'
44
end
5-
require 'ostruct'
5+
begin
6+
require 'ostruct'
7+
rescue LoadError
8+
end
69

710
class OpenStruct
811

@@ -48,4 +51,4 @@ def as_json(*)
4851
def to_json(*args)
4952
as_json.to_json(*args)
5053
end
51-
end
54+
end if defined?(::OpenStruct)

ext/json/lib/json/common.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#frozen_string_literal: false
22
require 'json/version'
3-
require 'json/generic_object'
43

54
module JSON
5+
autoload :GenericObject, 'json/generic_object'
6+
67
NOT_SET = Object.new.freeze
78
private_constant :NOT_SET
89

ext/json/lib/json/generic_object.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#frozen_string_literal: false
2-
require 'ostruct'
2+
begin
3+
require 'ostruct'
4+
rescue LoadError
5+
warn "JSON::GenericObject requires 'ostruct'. Please install it with `gem install ostruct`."
6+
end
37

48
module JSON
59
class GenericObject < OpenStruct
@@ -67,5 +71,5 @@ def as_json(*)
6771
def to_json(*a)
6872
as_json.to_json(*a)
6973
end
70-
end
74+
end if defined?(::OpenStruct)
7175
end

ext/json/lib/json/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: false
22
module JSON
33
# JSON version
4-
VERSION = '2.7.1'
4+
VERSION = '2.7.2'
55
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
66
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
77
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:

test/json/json_addition_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ def test_ostruct
190190
# XXX this won't work; o.foo = { :bar => true }
191191
o.foo = { 'bar' => true }
192192
assert_equal o, parse(JSON(o), :create_additions => true)
193-
end
193+
end if defined?(::OpenStruct)
194194

195195
def test_set
196196
s = Set.new([:a, :b, :c, :a])

test/json/json_generic_object_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,4 @@ def switch_json_creatable
7979
ensure
8080
JSON::GenericObject.json_creatable = false
8181
end
82-
end
82+
end if defined?(JSON::GenericObject)

test/json/json_parser_test.rb

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
require_relative 'test_helper'
44
require 'stringio'
55
require 'tempfile'
6-
require 'ostruct'
6+
begin
7+
require 'ostruct'
8+
rescue LoadError
9+
end
710
begin
811
require 'bigdecimal'
912
rescue LoadError
@@ -412,46 +415,48 @@ def self.json_create(o)
412415
end
413416
end
414417

415-
class SubOpenStruct < OpenStruct
416-
def [](k)
417-
__send__(k)
418-
end
419-
420-
def []=(k, v)
421-
@item_set = true
422-
__send__("#{k}=", v)
423-
end
424-
425-
def item_set?
426-
@item_set
427-
end
428-
end
429-
430418
def test_parse_object_custom_hash_derived_class
431419
res = parse('{"foo":"bar"}', :object_class => SubHash)
432420
assert_equal({"foo" => "bar"}, res)
433421
assert_equal(SubHash, res.class)
434422
assert res.item_set?
435423
end
436424

437-
def test_parse_object_custom_non_hash_derived_class
438-
res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
439-
assert_equal "bar", res.foo
440-
assert_equal(SubOpenStruct, res.class)
441-
assert res.item_set?
442-
end
425+
if defined?(::OpenStruct)
426+
class SubOpenStruct < OpenStruct
427+
def [](k)
428+
__send__(k)
429+
end
443430

444-
def test_parse_generic_object
445-
res = parse(
446-
'{"foo":"bar", "baz":{}}',
447-
:object_class => JSON::GenericObject
448-
)
449-
assert_equal(JSON::GenericObject, res.class)
450-
assert_equal "bar", res.foo
451-
assert_equal "bar", res["foo"]
452-
assert_equal "bar", res[:foo]
453-
assert_equal "bar", res.to_hash[:foo]
454-
assert_equal(JSON::GenericObject, res.baz.class)
431+
def []=(k, v)
432+
@item_set = true
433+
__send__("#{k}=", v)
434+
end
435+
436+
def item_set?
437+
@item_set
438+
end
439+
end
440+
441+
def test_parse_object_custom_non_hash_derived_class
442+
res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
443+
assert_equal "bar", res.foo
444+
assert_equal(SubOpenStruct, res.class)
445+
assert res.item_set?
446+
end
447+
448+
def test_parse_generic_object
449+
res = parse(
450+
'{"foo":"bar", "baz":{}}',
451+
:object_class => JSON::GenericObject
452+
)
453+
assert_equal(JSON::GenericObject, res.class)
454+
assert_equal "bar", res.foo
455+
assert_equal "bar", res["foo"]
456+
assert_equal "bar", res[:foo]
457+
assert_equal "bar", res.to_hash[:foo]
458+
assert_equal(JSON::GenericObject, res.baz.class)
459+
end
455460
end
456461

457462
def test_generate_core_subclasses_with_new_to_json

0 commit comments

Comments
 (0)