diff --git a/ext/oj/object.c b/ext/oj/object.c index 1675c837..dac99839 100644 --- a/ext/oj/object.c +++ b/ext/oj/object.c @@ -324,26 +324,30 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol // If struct is not defined then we let this fail and raise an exception. sc = oj_name2struct(pi, *RARRAY_PTR(value), rb_eArgError); } - // Create a properly initialized struct instance without calling the initialize method. - parent->val = rb_obj_alloc(sc); - // If the JSON array has more entries than the struct class allows, we record an error. + if (sc == rb_cRange) { + parent->val = rb_class_new_instance(len - 1, RARRAY_PTR(value) + 1, rb_cRange); + } else { + // Create a properly initialized struct instance without calling the initialize method. + parent->val = rb_obj_alloc(sc); + // If the JSON array has more entries than the struct class allows, we record an error. #ifdef RSTRUCT_LEN #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val)); #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT - slen = (int)RSTRUCT_LEN(parent->val); + slen = (int)RSTRUCT_LEN(parent->val); #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT #else - slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0)); + slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0)); #endif - // MRI >= 1.9 - if (len - 1 > slen) { - oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data"); - } else { - int i; + // MRI >= 1.9 + if (len - 1 > slen) { + oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data"); + } else { + int i; - for (i = 0; i < len - 1; i++) { - rb_struct_aset(parent->val, INT2FIX(i), RARRAY_PTR(value)[i + 1]); + for (i = 0; i < len - 1; i++) { + rb_struct_aset(parent->val, INT2FIX(i), RARRAY_PTR(value)[i + 1]); + } } } return 1; diff --git a/ext/oj/oj.c b/ext/oj/oj.c index 2559a635..211e2472 100644 --- a/ext/oj/oj.c +++ b/ext/oj/oj.c @@ -932,7 +932,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) { if (Qnil == v) { return ST_CONTINUE; } - if (TYPE(v) == T_STRUCT && rb_obj_class(v) == rb_cRange) { + if (rb_obj_class(v) == rb_cRange) { VALUE min = rb_funcall(v, oj_begin_id, 0); VALUE max = rb_funcall(v, oj_end_id, 0); diff --git a/test/test_integer_range.rb b/test/test_integer_range.rb index 88df49d0..761fca93 100755 --- a/test/test_integer_range.rb +++ b/test/test_integer_range.rb @@ -23,24 +23,18 @@ def teardown end def test_range - skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby' - test = {s: 0, s2: -1, s3: 1, u: -2, u2: 2, u3: 9007199254740993} exp = '{"s":0,"s2":-1,"s3":1,"u":"-2","u2":"2","u3":"9007199254740993"}' assert_equal(exp, Oj.dump(test, integer_range: (-1..1))) end def test_bignum - skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby' - test = {u: -10000000000000000000, u2: 10000000000000000000} exp = '{"u":"-10000000000000000000","u2":"10000000000000000000"}' assert_equal(exp, Oj.dump(test, integer_range: (-1..1))) end def test_valid_modes - skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby' - test = {safe: 0, unsafe: 9007199254740993} exp = '{"safe":0,"unsafe":"9007199254740993"}'